📄 ifrename.c
字号:
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", linenum); else fprintf(stderr, "Error: Line %d ignored due to prior errors\n", linenum); free(ifnode); } else { /* Link it in the list */ ifnode->next = mapping_list; mapping_list = ifnode; } } /* Cleanup */ free(linebuf); /* Finished reading, close the file */ if(stream != stdin) fclose(stream); return(0);}/*------------------------------------------------------------------*//* * Extract all the interesting selectors for the interface in consideration */static struct if_mapping *mapping_extract(int skfd, const char * ifname){ struct if_mapping * target; int i; /* Create mapping, zero it */ target = calloc(1, sizeof(if_mapping)); if(!target) { fprintf(stderr, "Error: Can't allocate interface mapping.\n"); return(NULL); } /* Set the interface name */ strcpy(target->ifname, ifname); /* Loop on all active selectors */ for(i = 0; i < SELECT_NUM; i++) { /* Check if this selector is active */ if(selector_active[i] != 0) { /* Extract selector */ selector_list[i].get_fn(skfd, ifname, target, selector_active[i]); /* Ignore errors. Some mapping may not need all selectors */ } } return(target);} /*------------------------------------------------------------------*//* * Find the first mapping in the list matching the one we want. */static struct if_mapping *mapping_find(struct if_mapping * target){ struct if_mapping * ifnode; int i; /* Look over all our mappings */ for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next) { int matches = 1; /* Look over all our selectors, all must match */ for(i = 0; i < SELECT_NUM; i++) { /* Check if this selector is active */ if(ifnode->active[i] != 0) { /* If this selector doesn't match, game over for this mapping */ if((target->active[i] == 0) || (selector_list[i].cmp_fn(ifnode, target) != 0)) { matches = 0; break; } } } /* Check is this mapping was "the one" */ if(matches) return(ifnode); } /* Not found */ return(NULL);} /************************** MODULE SUPPORT **************************//* * Load all necessary module so that interfaces do exist. * This is necessary for system that are fully modular when * doing the boot time processing, because we need to run before * 'ifup -a'. *//*------------------------------------------------------------------*//* * Probe interfaces based on our list of mappings. * This is the default, but usually not the best way to do it. */static voidprobe_mappings(int skfd){ struct if_mapping * ifnode; struct ifreq ifr; /* Look over all our mappings */ for(ifnode = mapping_list; ifnode != NULL; ifnode = ifnode->next) { /* Can't load wildcards interface name :-( */ if(strchr(ifnode->ifname, '%') != NULL) continue; if(verbose) fprintf(stderr, "Probing : Trying to load interface [%s]\n", ifnode->ifname); /* Trick the kernel into loading the interface. * This allow us to not depend on the exact path and * name of the '/sbin/modprobe' command. * Obviously, we expect this command to 'fail', as * the interface will load with the old/wrong name. */ strncpy(ifr.ifr_name, ifnode->ifname, IFNAMSIZ); ioctl(skfd, SIOCGIFHWADDR, &ifr); }}/*------------------------------------------------------------------*//* * Probe interfaces based on Debian's config files. * This allow to enly load modules for interfaces the user want active, * all built-in interfaces that should remain unconfigured won't * be probed (and can have mappings). */static voidprobe_debian(int skfd){ FILE * stream; char * linebuf = NULL; size_t linelen = 0; struct ifreq ifr; /* Open Debian config file */ stream = fopen(DEBIAN_CONFIG_FILE, "r"); if(stream == NULL) { fprintf(stderr, "Error: can't open file [%s]\n", DEBIAN_CONFIG_FILE); return; } /* 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; char * e; size_t n; /* Check for auto keyword, ignore when commented out */ if(!strncasecmp(linebuf, "auto ", 5)) { /* Skip "auto" keyword */ p = linebuf + 5; /* Terminate at first comment */ e = strchr(p, '#'); if(e != NULL) *e = '\0'; /* Loop on all interfaces given */ while(*p != '\0') { /* Interface name length */ n = strcspn(p, " \t\n"); /* Look for end of interface name */ e = p + n; /* Make 'e' point past the '\0' we are going to add */ if(*e != '\0') e++; /* Terminate interface name */ p[n] = '\0'; if(verbose) fprintf(stderr, "Probing : Trying to load interface [%s]\n", p); /* Load interface */ strncpy(ifr.ifr_name, p, IFNAMSIZ); ioctl(skfd, SIOCGIFHWADDR, &ifr); /* Go to next interface name */ p = e; p += strspn(p, " \t\n"); } } } /* Done */ fclose(stream); return;}/**************************** MAIN LOGIC ****************************//*------------------------------------------------------------------*//* * Rename an interface to a specified new name. */static intprocess_rename(int skfd, char * ifname, char * newname){ char retname[IFNAMSIZ+1]; int len; char * star; len = strlen(newname); star = strchr(newname, '*'); /* Check newname length, need one extra char for wildcard */ if((len + (star != NULL)) > IFNAMSIZ) { fprintf(stderr, "Error: Interface name `%s' too long.\n", newname); return(-1); } /* Change the name of the interface */ if(if_set_name(skfd, ifname, newname, retname) < 0) { fprintf(stderr, "Error: cannot change name of %s to %s: %s\n", ifname, newname, strerror(errno)); return(-1); } /* Always print out the *new* interface name so that * the calling script can pick it up and know where its interface * has gone. */ printf("%s\n", retname); /* Done */ return(0);}/*------------------------------------------------------------------*//* * Process a specified interface. */static intprocess_ifname(int skfd, char * ifname, char * args[], int count){ struct if_mapping * target; const struct if_mapping * mapping; char retname[IFNAMSIZ+1]; /* Avoid "Unused parameter" warning */ args = args; count = count; /* Get description of this interface */ target = mapping_extract(skfd, ifname); if(target == NULL) return(-1); /* If udev is calling us, get the real devpath. */ if(udev_output) { const char *env; /* It's passed to us as an environment variable */ env = getenv("DEVPATH"); if(env) { int env_len = strlen(env); target->sysfs_devplen = env_len; /* Make enough space for new interface name */ target->sysfs_devpath = malloc(env_len + IFNAMSIZ + 1); if(target->sysfs_devpath != NULL) memcpy(target->sysfs_devpath, env, env_len + 1); } /* We will get a second chance is the user has some sysfs selectors */ } /* Find matching mapping */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -