📄 ifrename.c
字号:
fprintf(stderr, "Error: Can't allocate SYSFS value\n"); return(-1); } ifnode->sysfs[findex] = sdup; /* Activate */ ifnode->active[SELECT_SYSFS] = 1; active[SELECT_SYSFS] = 1; if(verbose) fprintf(stderr, "Parsing : Added SYSFS filename `%s' value `%s' from line %d.\n", sysfs_global.filename[findex], ifnode->sysfs[findex], linenum); return(0);}/*------------------------------------------------------------------*//* * Compare all the sysfs values of two mappings */static intmapping_cmpsysfs(struct if_mapping * ifnode, struct if_mapping * target){ int findex; /* filename index */ int match = 1; /* Loop on all sysfs selector */ for(findex = 0; findex < sysfs_global.filenum; findex++) { /* If the mapping defines this sysfs selector.. */ if(ifnode->sysfs[findex] != NULL) /* And if the sysfs values don't match */ if((target->sysfs[findex] == NULL) || (fnmatch(ifnode->sysfs[findex], target->sysfs[findex], FNM_CASEFOLD))) /* Then the sysfs selector doesn't match */ match = 0; } return(!match);}/*------------------------------------------------------------------*//* * Extract all the sysfs values of an interface */static intmapping_getsysfs(int skfd, const char * ifname, struct if_mapping * target, int flag){ FILE * stream; char * linebuf = NULL; size_t linelen = 0; char * sdup; int findex; /* filename index */ /* Avoid "Unused parameter" warning */ skfd = skfd; flag = flag; /* Check if we know the root of the sysfs filesystem */ if(sysfs_global.root == NULL) { /* Open the mount file for reading */ stream = fopen("/proc/mounts", "r"); if(!stream) { fprintf(stderr, "Error: Can't open /proc/mounts file: %s\n", strerror(errno)); return(-1); } /* Read each line of file * getline is a GNU extension :-( The buffer is recycled and increased * as needed by getline. */ while(getline(&linebuf, &linelen, stream) > 0) { char * p; size_t n; /* Get the line starting with sysfs */ p = linebuf; while(isspace(*p)) ++p; if(!strncasecmp(p, "sysfs ", 6)) { /* Find the mount point */ p += 6; while(isspace(*p)) ++p; n = strcspn(p, " \t\n"); sdup = strndup(p, n); if((n == 0) || (sdup == NULL)) { fprintf(stderr, "Error: Can't parse /proc/mounts file: %s\n", strerror(errno)); return(-1); } /* Store it */ sysfs_global.root = sdup; sysfs_global.rlen = n; break; } /* Finished -> next line */ } /* Cleanup */ fclose(stream); /* Check if we found it */ if(sysfs_global.root == NULL) { fprintf(stderr, "Error: Can't find sysfs in /proc/mounts file\n"); free(linebuf); return(-1); } } /* Loop on all sysfs selector */ for(findex = 0; findex < sysfs_global.filenum; findex++) { char * fname; int flen; char * p; ssize_t n; /* Construct complete filename for the sysfs selector */ flen = (sysfs_global.rlen + 11 + strlen(ifname) + 1 + strlen(sysfs_global.filename[findex]) + 1); fname = malloc(flen); if(fname == NULL) { fprintf(stderr, "Error: Can't allocate SYSFS filename\n"); free(linebuf); return(-1); } sprintf(fname, "%s/class/net/%s/%s", sysfs_global.root, ifname, sysfs_global.filename[findex]); /* Open the sysfs file for reading */ stream = fopen(fname, "r"); if(!stream) { /* Some sysfs attribute may no exist for some interface */ if(verbose) fprintf(stderr, "Error: Can't open file `%s': %s\n", fname, strerror(errno)); /* Next sysfs selector */ continue; } /* Read file. Only one line in file. */ n = getline(&linebuf, &linelen, stream); fclose(stream); if(n <= 0) { /* Some sysfs attribute are void for some interface */ if(verbose) fprintf(stderr, "Error: Can't read file `%s'\n", fname); /* Next sysfs selector */ continue; } /* Get content, remove trailing '/n', save it */ p = linebuf; if(p[n - 1] == '\n') n--; sdup = strndup(p, n); if(sdup == NULL) { fprintf(stderr, "Error: Can't allocate SYSFS value\n"); free(linebuf); return(-1); } target->sysfs[findex] = sdup; /* Activate */ target->active[SELECT_SYSFS] = 1; if(verbose) fprintf(stderr, "Querying %s : Got SYSFS filename `%s' value `%s'.\n", ifname, sysfs_global.filename[findex], target->sysfs[findex]); /* Finished : Next sysfs selector */ } /* Cleanup */ free(linebuf); return(target->active[SELECT_SYSFS] ? 0 : -1);}/*********************** MAPPING MANAGEMENTS ***********************//* * Manage interface mappings. * Each mapping tell us how to identify a specific interface name. * It is composed of a bunch of selector values. *//*------------------------------------------------------------------*//* * Create a new interface mapping and verify its name */static struct if_mapping *mapping_create(char * pos, int len, int linenum){ struct if_mapping * ifnode; char * star; /* Check overflow. */ if(len > IFNAMSIZ) { fprintf(stderr, "Error: Interface name `%.*s' too long at line %d\n", (int) len, pos, linenum); return(NULL); } /* Create mapping, zero it */ ifnode = calloc(1, sizeof(if_mapping)); if(!ifnode) { fprintf(stderr, "Error: Can't allocate interface mapping.\n"); return(NULL); } /* Set the name, terminates it */ memcpy(ifnode->ifname, pos, len); ifnode->ifname[len] = '\0'; /* Check the interface name and issue various pedantic warnings. * We assume people using takeover want to force interfaces to those * names and know what they are doing, so don't bother them... */ if((!force_takeover) && ((!strcmp(ifnode->ifname, "eth0")) || (!strcmp(ifnode->ifname, "wlan0")))) fprintf(stderr, "Warning: Interface name is `%s' at line %d, can't be mapped reliably.\n", ifnode->ifname, linenum); if(strchr(ifnode->ifname, ':')) fprintf(stderr, "Warning: Alias device `%s' at line %d probably can't be mapped.\n", ifnode->ifname, linenum); /* Check for wildcard interface name, such as 'eth*' or 'wlan*'... * This require specific kernel support (2.6.2-rc1 and later). * We externally use '*', but the kernel doesn't know about that, * so convert it to something it knows about... */ star = strchr(ifnode->ifname, '*'); if(star != NULL) { /* We need an extra char */ if(len >= IFNAMSIZ) { fprintf(stderr, "Error: Interface wildcard `%s' too long at line %d\n", ifnode->ifname, linenum); free(ifnode); return(NULL); } /* Replace '*' with '%d' */ memmove(star + 2, star + 1, len + 1 - (star - ifnode->ifname)); star[0] = '%'; star[1] = 'd'; } if(verbose) fprintf(stderr, "Parsing : Added Mapping `%s' from line %d.\n", ifnode->ifname, linenum); /* Done */ return(ifnode);}/*------------------------------------------------------------------*//* * Find the most appropriate selector matching a given selector name */static inline const struct mapping_selector *selector_find(const char * string, size_t slen, int linenum){ const struct mapping_selector * found = NULL; int ambig = 0; int i; /* Go through all selectors */ for(i = 0; selector_list[i].name != NULL; ++i) { /* No match -> next one */ if(strncasecmp(selector_list[i].name, string, slen) != 0) continue; /* Exact match -> perfect */ if(slen == strlen(selector_list[i].name)) return &selector_list[i]; /* Partial match */ if(found == NULL) /* First time */ found = &selector_list[i]; else /* Another time */ if (selector_list[i].add_fn != found->add_fn) ambig = 1; } if(found == NULL) { fprintf(stderr, "Error: Unknown selector `%.*s' at line %d.\n", (int) slen, string, linenum); return NULL; } if(ambig) { fprintf(stderr, "Selector `%.*s'at line %d is ambiguous.\n", (int) slen, string, linenum); return NULL; } return found;}/*------------------------------------------------------------------*//* * Read the configuration file and extract all valid mappings and their * selectors. */static intmapping_readfile(const char * filename){ FILE * stream; char * linebuf = NULL; size_t linelen = 0; int linenum = 0; struct add_extra extrainfo; /* Reset the list of filters */ bzero(selector_active, sizeof(selector_active)); /* Check filename */ if(!strcmp(filename, "-")) { /* Read from stdin */ stream = stdin; } else { /* Open the file for reading */ stream = fopen(filename, "r"); if(!stream) { fprintf(stderr, "Error: Can't open configuration file `%s': %s\n", filename, strerror(errno)); return(-1); } } /* Read each line of file * getline is a GNU extension :-( The buffer is recycled and increased * as needed by getline. */ while(getline(&linebuf, &linelen, stream) > 0) { struct if_mapping * ifnode; char * p; char * e; size_t n; int ret = -13; /* Complain if no selectors */ /* Keep track of line number */ linenum++; /* Every comments terminates parsing */ if((p = strchr(linebuf,'#')) != NULL) *p = '\0'; /* Get interface name */ p = linebuf; while(isspace(*p)) ++p; if(*p == '\0') continue; /* Line ended */ n = strcspn(p, " \t\n"); /* Create mapping */ ifnode = mapping_create(p, n, linenum); if(!ifnode) continue; /* Ignore this line */ p += n; p += strspn(p, " \t\n"); /* Loop on all selectors */ while(*p != '\0') { const struct mapping_selector * selector = NULL; struct add_extra * extra = NULL; /* Selector name length - stop at modifier start */ n = strcspn(p, " \t\n{"); /* Find it */ selector = selector_find(p, n, linenum); if(!selector) { ret = -1; break; } p += n; /* Check for modifier */ if(*p == '{') { p++; /* Find end of modifier */ e = strchr(p, '}'); if(e == NULL) { fprintf(stderr, "Error: unterminated selector modifier value on line %d\n", linenum); ret = -1; break; /* Line ended */ } /* Fill in struct and hook it */ extrainfo.modif_pos = p; extrainfo.modif_len = e - p; extra = &extrainfo; /* Terminate modifier value */ e[0] = '\0'; /* Skip it */ p = e + 1; } /* Get to selector value */ p += strspn(p, " \t\n"); if(*p == '\0') { fprintf(stderr, "Error: no value for selector `%s' on line %d\n", selector->name, linenum); ret = -1; break; /* Line ended */ } /* Check for quoted arguments */ if(*p == '"') { p++; e = strchr(p, '"'); if(e == NULL) { fprintf(stderr, "Error: unterminated quoted value on line %d\n", linenum); ret = -1; break; /* Line ended */ } n = e - p; e++; } else { /* Just end at next blank */ n = strcspn(p, " \t\n"); e = p + n; } /* Make 'e' point past the '\0' we are going to add */ if(*e != '\0') e++; /* Terminate selector value */ p[n] = '\0'; /* Add it to the mapping */ ret = selector->add_fn(ifnode, selector_active, p, n, extra, linenum); if(ret < 0) break; /* Go to next selector */ p = e; p += strspn(p, " \t\n"); } /* We add a mapping only if it has at least one selector and if all * selectors were parsed properly. */ if(ret < 0) { /* If we have not yet printed an error, now is a good time ;-) */ if(ret == -13) fprintf(stderr, "Error: Line %d ignored, no valid selectors\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -