static void expand(FILE *file, unsigned tab_size, unsigned opt) { char *line; char *ptr; int convert; int pos; /* Increment tab_size by 1 locally.*/ tab_size++; while ((line = xmalloc_fgets(file)) != NULL) { convert = 1; pos = 0; ptr = line; while (*line) { pos++; if (*line == '\t' && convert) { for (; pos < tab_size; pos++) { xputchar(' '); } } else { if ((opt & OPT_INITIAL) && !isblank(*line)) { convert = 0; } xputchar(*line); } if (pos == tab_size) { pos = 0; } line++; } free(ptr); } }
char *ask_password(const char *question) { if (is_slave_mode()) printf(REPORT_PREFIX_ASK_PASSWORD "%s\n", question); else printf("%s ", question); fflush(stdout); if (!is_slave_mode() && is_noninteractive_mode()) { putchar('\n'); fflush(stdout); return xstrdup(""); } bool changed = set_echo(false); char *result = xmalloc_fgets(stdin); strtrimch(result, '\n'); if (changed) set_echo(true); return result; }
static void expand(FILE *file, unsigned tab_size, unsigned opt) { char *line; while ((line = xmalloc_fgets(file)) != NULL) { unsigned char c; char *ptr; char *ptr_strbeg; ptr = ptr_strbeg = line; while ((c = *ptr) != '\0') { if ((opt & OPT_INITIAL) && !isblank(c)) { /* not space or tab */ break; } if (c == '\t') { unsigned len; *ptr = '\0'; # if ENABLE_UNICODE_SUPPORT len = unicode_strwidth(ptr_strbeg); # else len = ptr - ptr_strbeg; # endif len = tab_size - (len % tab_size); /*while (ptr[1] == '\t') { ptr++; len += tab_size; } - can handle many tabs at once */ printf("%s%*s", ptr_strbeg, len, ""); ptr_strbeg = ptr + 1; } ptr++; } fputs(ptr_strbeg, stdout); free(line); } }
static void expand(FILE *file, int tab_size, unsigned opt) { char *line; tab_size = -tab_size; while ((line = xmalloc_fgets(file)) != NULL) { int pos; unsigned char c; char *ptr = line; goto start; while ((c = *ptr) != '\0') { if ((opt & OPT_INITIAL) && !isblank(c)) { fputs(ptr, stdout); break; } ptr++; if (c == '\t') { c = ' '; while (++pos < 0) bb_putchar(c); } bb_putchar(c); if (++pos >= 0) { start: pos = tab_size; } } free(line); } }
static void unexpand(FILE *file, unsigned tab_size, unsigned opt) { char *line; while ((line = xmalloc_fgets(file)) != NULL) { char *ptr = line; unsigned column = 0; while (*ptr) { unsigned n; unsigned len = 0; while (*ptr == ' ') { ptr++; len++; } column += len; if (*ptr == '\t') { column += tab_size - (column % tab_size); ptr++; continue; } n = column / tab_size; if (n) { len = column = column % tab_size; while (n--) putchar('\t'); } if ((opt & OPT_INITIAL) && ptr != line) { printf("%*s%s", len, "", ptr); break; } n = strcspn(ptr, "\t "); printf("%*s%.*s", len, "", n, ptr); # if ENABLE_UNICODE_SUPPORT { char c; uni_stat_t uni_stat; c = ptr[n]; ptr[n] = '\0'; printable_string(&uni_stat, ptr); len = uni_stat.unicode_width; ptr[n] = c; } # else len = n; # endif ptr += n; column = (column + len) % tab_size; } free(line); } }
static void unexpand(FILE *file, unsigned int tab_size, unsigned opt) { char *line; char *ptr; int convert; int pos; int i = 0; int column = 0; while ((line = xmalloc_fgets(file)) != NULL) { convert = 1; pos = 0; ptr = line; while (*line) { while ((*line == ' ' || *line == '\t') && convert) { pos += (*line == ' ') ? 1 : tab_size; line++; column++; if ((opt & OPT_ALL) && column == tab_size) { column = 0; goto put_tab; } } if (pos) { i = pos / tab_size; if (i) { for (; i > 0; i--) { put_tab: xputchar('\t'); } } else { for (i = pos % tab_size; i > 0; i--) { xputchar(' '); } } pos = 0; } else { if (opt & OPT_INITIAL) { convert = 0; } if (opt & OPT_ALL) { column++; } xputchar(*line); line++; } } free(ptr); } }
static void del_line_matching(const char *login, const char *filename) { char *line; FILE *passwd; int len = strlen(login); int found = 0; llist_t *plist = NULL; passwd = fopen_or_warn(filename, "r"); if (!passwd) return; while ((line = xmalloc_fgets(passwd))) { if (!strncmp(line, login, len) && line[len] == ':' ) { found++; free(line); } else { llist_add_to_end(&plist, line); } } if (!ENABLE_FEATURE_CLEAN_UP) { if (!found) { bb_error_msg("can't find '%s' in '%s'", login, filename); return; } passwd = fopen_or_warn(filename, "w"); if (passwd) while ((line = llist_pop(&plist))) fputs(line, passwd); } else { if (!found) { bb_error_msg("can't find '%s' in '%s'", login, filename); goto clean_up; } fclose(passwd); passwd = fopen_or_warn(filename, "w"); if (passwd) { clean_up: while ((line = llist_pop(&plist))) { if (found) fputs(line, passwd); free(line); } fclose(passwd); } } }
static unsigned copy_lines(FILE *src_stream, FILE *dst_stream, unsigned lines_count) { while (src_stream && lines_count) { char *line; line = xmalloc_fgets(src_stream); if (line == NULL) { break; } if (fputs(line, dst_stream) == EOF) { bb_perror_msg_and_die("error writing to new file"); } free(line); lines_count--; } return lines_count; }
int lsmod_main(int argc, char **argv) { FILE *file = xfopen("/proc/modules", "r"); printf("Module Size Used by"); check_tainted(); #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT) { char *line; while ((line = xmalloc_fgets(file)) != NULL) { char *tok; tok = strtok(line, " \t"); printf("%-19s", tok); tok = strtok(NULL, " \t\n"); printf(" %8s", tok); tok = strtok(NULL, " \t\n"); /* Null if no module unloading support. */ if (tok) { printf(" %s", tok); tok = strtok(NULL, "\n"); if (!tok) tok = (char*)""; /* New-style has commas, or -. If so, truncate (other fields might follow). */ else if (strchr(tok, ',')) { tok = strtok(tok, "\t "); /* Strip trailing comma. */ if (tok[strlen(tok)-1] == ',') tok[strlen(tok)-1] = '\0'; } else if (tok[0] == '-' && (tok[1] == '\0' || isspace(tok[1])) ) { tok = (char*)""; } printf(" %s", tok); } puts(""); free(line); } fclose(file); } #else xprint_and_close_file(file); #endif /* CONFIG_FEATURE_2_6_MODULES */ return EXIT_SUCCESS; }
static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count) { unsigned int i = 0; while (src_stream && (i < lines_count)) { char *line; line = xmalloc_fgets(src_stream); if (line == NULL) { break; } if (fputs(line, dest_stream) == EOF) { bb_perror_msg_and_die("error writing to new file"); } free(line); i++; } return i; }
char *ask(const char *question) { if (is_slave_mode()) printf(REPORT_PREFIX_ASK "%s\n", question); else printf("%s ", question); fflush(stdout); if (!is_slave_mode() && is_noninteractive_mode()) { putchar('\n'); fflush(stdout); return xstrdup(""); } char *result = xmalloc_fgets(stdin); strtrimch(result, '\n'); return result; }
static void unexpand(FILE *file, unsigned tab_size, unsigned opt) { char *line; while ((line = xmalloc_fgets(file)) != NULL) { char *ptr = line; unsigned column = 0; while (*ptr) { unsigned n; while (*ptr == ' ') { column++; ptr++; } if (*ptr == '\t') { column += tab_size - (column % tab_size); ptr++; continue; } n = column / tab_size; column = column % tab_size; while (n--) putchar('\t'); if ((opt & OPT_INITIAL) && ptr != line) { printf("%*s%s", column, "", ptr); break; } n = strcspn(ptr, "\t "); printf("%*s%.*s", column, "", n, ptr); ptr += n; column = (column + n) % tab_size; } free(line); } }
static void do_info(const char *file, const char *name, void (*proc)(int, const char *)) { int lnr = 0; FILE *procinfo; procinfo = fopen(file, "r"); if (procinfo == NULL) { if (errno != ENOENT) { bb_perror_msg("%s", file); } else { bb_error_msg("no support for '%s' on this system", name); } return; } do { char *buffer = xmalloc_fgets(procinfo); if (buffer) { (proc)(lnr++, buffer); free(buffer); } } while (!feof(procinfo)); fclose(procinfo); }
int nameif_main(int argc, char **argv) { ethtable_t *clist = NULL; FILE *ifh; const char *fname = "/etc/mactab"; char *line; char *line_ptr; int linenum; int ctl_sk; ethtable_t *ch; if (1 & getopt32(argv, "sc:", &fname)) { openlog(applet_name, 0, LOG_LOCAL0); logmode = LOGMODE_SYSLOG; } argc -= optind; argv += optind; if (argc & 1) bb_show_usage(); if (argc) { while (*argv) { char *ifname = xstrdup(*argv++); prepend_new_eth_table(&clist, ifname, *argv++); } } else { ifh = xfopen(fname, "r"); while ((line = xmalloc_fgets(ifh)) != NULL) { char *next; line_ptr = skip_whitespace(line); if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) { free(line); continue; } next = skip_non_whitespace(line_ptr); if (*next) *next++ = '\0'; prepend_new_eth_table(&clist, line_ptr, next); free(line); } fclose(ifh); } ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); ifh = xfopen("/proc/net/dev", "r"); linenum = 0; while (clist) { struct ifreq ifr; #if ENABLE_FEATURE_NAMEIF_EXTENDED struct ethtool_drvinfo drvinfo; #endif line = xmalloc_fgets(ifh); if (line == NULL) break; /* Seems like we're done */ if (linenum++ < 2 ) goto next_line; /* Skip the first two lines */ /* Find the current interface name and copy it to ifr.ifr_name */ line_ptr = skip_whitespace(line); *skip_non_whitespace(line_ptr) = '\0'; memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, line_ptr, sizeof(ifr.ifr_name)); #if ENABLE_FEATURE_NAMEIF_EXTENDED /* Check for driver etc. */ memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); drvinfo.cmd = ETHTOOL_GDRVINFO; ifr.ifr_data = (caddr_t) &drvinfo; /* Get driver and businfo first, so we have it in drvinfo */ ioctl(ctl_sk, SIOCETHTOOL, &ifr); #endif ioctl(ctl_sk, SIOCGIFHWADDR, &ifr); /* Search the list for a matching device */ for (ch = clist; ch; ch = ch->next) { #if ENABLE_FEATURE_NAMEIF_EXTENDED if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0) continue; if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0) continue; #endif if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0) continue; /* if we came here, all selectors have matched */ goto found; } /* Nothing found for current interface */ goto next_line; found: if (strcmp(ifr.ifr_name, ch->ifname) != 0) { strcpy(ifr.ifr_newname, ch->ifname); ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr, "cannot change ifname %s to %s", ifr.ifr_name, ch->ifname); } /* Remove list entry of renamed interface */ if (ch->prev != NULL) ch->prev->next = ch->next; else clist = ch->next; if (ch->next != NULL) ch->next->prev = ch->prev; if (ENABLE_FEATURE_CLEAN_UP) { free(ch->ifname); free(ch->mac); free(ch); } next_line: free(line); } if (ENABLE_FEATURE_CLEAN_UP) { fclose(ifh); }; return 0; }
int patch_main(int argc UNUSED_PARAM, char **argv) { struct stat saved_stat; char *patch_line; FILE *patch_file; int patch_level; int ret = 0; char plus = '+'; xfunc_error_retval = 2; { const char *p = "-1"; const char *i = "-"; /* compat */ if (getopt32(argv, "p:i:R", &p, &i) & 4) plus = '-'; patch_level = xatoi(p); /* can be negative! */ patch_file = xfopen_stdin(i); } patch_line = xmalloc_fgetline(patch_file); while (patch_line) { FILE *src_stream; FILE *dst_stream; //char *old_filename; char *new_filename; char *backup_filename; unsigned src_cur_line = 1; unsigned dst_cur_line = 0; unsigned dst_beg_line; unsigned bad_hunk_count = 0; unsigned hunk_count = 0; smallint copy_trailing_lines_flag = 0; /* Skip everything upto the "---" marker * No need to parse the lines "Only in <dir>", and "diff <args>" */ do { /* Extract the filename used before the patch was generated */ new_filename = extract_filename(patch_line, patch_level, "--- "); // was old_filename above patch_line = xmalloc_fgetline(patch_file); if (!patch_line) goto quit; } while (!new_filename); free(new_filename); // "source" filename is irrelevant new_filename = extract_filename(patch_line, patch_level, "+++ "); if (!new_filename) { bb_error_msg_and_die("invalid patch"); } /* Get access rights from the file to be patched */ if (stat(new_filename, &saved_stat) != 0) { char *slash = strrchr(new_filename, '/'); if (slash) { /* Create leading directories */ *slash = '\0'; bb_make_directory(new_filename, -1, FILEUTILS_RECUR); *slash = '/'; } backup_filename = NULL; src_stream = NULL; saved_stat.st_mode = 0644; } else { backup_filename = xasprintf("%s.orig", new_filename); xrename(new_filename, backup_filename); src_stream = xfopen_for_read(backup_filename); } dst_stream = xfopen_for_write(new_filename); fchmod(fileno(dst_stream), saved_stat.st_mode); printf("patching file %s\n", new_filename); /* Handle all hunks for this file */ patch_line = xmalloc_fgets(patch_file); while (patch_line) { unsigned count; unsigned src_beg_line; unsigned hunk_offset_start; unsigned src_last_line = 1; unsigned dst_last_line = 1; if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) ) { /* No more hunks for this file */ break; } if (plus != '+') { /* reverse patch */ unsigned tmp = src_last_line; src_last_line = dst_last_line; dst_last_line = tmp; tmp = src_beg_line; src_beg_line = dst_beg_line; dst_beg_line = tmp; } hunk_count++; if (src_beg_line && dst_beg_line) { /* Copy unmodified lines upto start of hunk */ /* src_beg_line will be 0 if it's a new file */ count = src_beg_line - src_cur_line; if (copy_lines(src_stream, dst_stream, count)) { bb_error_msg_and_die("bad src file"); } src_cur_line += count; dst_cur_line += count; copy_trailing_lines_flag = 1; } src_last_line += hunk_offset_start = src_cur_line; dst_last_line += dst_cur_line; while (1) { free(patch_line); patch_line = xmalloc_fgets(patch_file); if (patch_line == NULL) break; /* EOF */ if ((*patch_line != '-') && (*patch_line != '+') && (*patch_line != ' ') ) { break; /* End of hunk */ } if (*patch_line != plus) { /* '-' or ' ' */ char *src_line = NULL; if (src_cur_line == src_last_line) break; if (src_stream) { src_line = xmalloc_fgets(src_stream); if (src_line) { int diff = strcmp(src_line, patch_line + 1); src_cur_line++; free(src_line); if (diff) src_line = NULL; } } if (!src_line) { bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); bad_hunk_count++; break; } if (*patch_line != ' ') { /* '-' */ continue; } } if (dst_cur_line == dst_last_line) break; fputs(patch_line + 1, dst_stream); dst_cur_line++; } /* end of while loop handling one hunk */ } /* end of while loop handling one file */ /* Cleanup last patched file */ if (copy_trailing_lines_flag) { copy_lines(src_stream, dst_stream, (unsigned)(-1)); } if (src_stream) { fclose(src_stream); } fclose(dst_stream); if (bad_hunk_count) { ret = 1; bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count); } else { /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); } if ((dst_cur_line == 0) || (dst_beg_line == 0)) { /* The new patched file is empty, remove it */ xunlink(new_filename); // /* old_filename and new_filename may be the same file */ // unlink(old_filename); } } free(backup_filename); //free(old_filename); free(new_filename); } /* end of "while there are patch lines" */ quit: /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems (exited earlier) */ return ret; }
int patch_main(int argc UNUSED_PARAM, char **argv) { struct stat saved_stat; char *patch_line; FILE *patch_file; int patch_level; int ret = 0; char plus = '+'; unsigned opt; enum { OPT_R = (1 << 2), OPT_N = (1 << 3), /*OPT_f = (1 << 4), ignored */ /*OPT_E = (1 << 5), ignored, this is the default */ /*OPT_g = (1 << 6), ignored */ OPT_dry_run = (1 << 7) * ENABLE_LONG_OPTS, }; xfunc_error_retval = 2; { const char *p = "-1"; const char *i = "-"; /* compat */ #if ENABLE_LONG_OPTS static const char patch_longopts[] ALIGN1 = "strip\0" Required_argument "p" "input\0" Required_argument "i" "reverse\0" No_argument "R" "forward\0" No_argument "N" /* "Assume user knows what [s]he is doing, do not ask any questions": */ "force\0" No_argument "f" /*ignored*/ # if ENABLE_DESKTOP "remove-empty-files\0" No_argument "E" /*ignored*/ /* "Controls actions when a file is under RCS or SCCS control, * and does not exist or is read-only and matches the default version, * or when a file is under ClearCase control and does not exist..." * IOW: rather obscure option. * But Gentoo's portage does use -g0 */ "get\0" Required_argument "g" /*ignored*/ # endif "dry-run\0" No_argument "\xfd" # if ENABLE_DESKTOP "backup-if-mismatch\0" No_argument "\xfe" /*ignored*/ "no-backup-if-mismatch\0" No_argument "\xff" /*ignored*/ # endif ; applet_long_options = patch_longopts; #endif /* -f,-E,-g are ignored */ opt = getopt32(argv, "p:i:RN""fEg:", &p, &i, NULL); if (opt & OPT_R) plus = '-'; patch_level = xatoi(p); /* can be negative! */ patch_file = xfopen_stdin(i); } patch_line = xmalloc_fgetline(patch_file); while (patch_line) { FILE *src_stream; FILE *dst_stream; //char *old_filename; char *new_filename; char *backup_filename = NULL; unsigned src_cur_line = 1; unsigned dst_cur_line = 0; unsigned dst_beg_line; unsigned bad_hunk_count = 0; unsigned hunk_count = 0; smallint copy_trailing_lines_flag = 0; /* Skip everything upto the "---" marker * No need to parse the lines "Only in <dir>", and "diff <args>" */ do { /* Extract the filename ugsed before the patch was generated */ new_filename = extract_filename(patch_line, patch_level, "--- "); // was old_filename above patch_line = xmalloc_fgetline(patch_file); if (!patch_line) goto quit; } while (!new_filename); free(new_filename); // "source" filename is irrelevant new_filename = extract_filename(patch_line, patch_level, "+++ "); if (!new_filename) { bb_error_msg_and_die("invalid patch"); } /* Get access rights from the file to be patched */ if (stat(new_filename, &saved_stat) != 0) { char *slash = strrchr(new_filename, '/'); if (slash) { /* Create leading directories */ *slash = '\0'; bb_make_directory(new_filename, -1, FILEUTILS_RECUR); *slash = '/'; } src_stream = NULL; saved_stat.st_mode = 0644; } else if (!(opt & OPT_dry_run)) { backup_filename = xasprintf("%s.orig", new_filename); xrename(new_filename, backup_filename); src_stream = xfopen_for_read(backup_filename); } else src_stream = xfopen_for_read(new_filename); if (opt & OPT_dry_run) { dst_stream = xfopen_for_write("/dev/null"); } else { dst_stream = xfopen_for_write(new_filename); fchmod(fileno(dst_stream), saved_stat.st_mode); } printf("patching file %s\n", new_filename); /* Handle all hunks for this file */ patch_line = xmalloc_fgets(patch_file); while (patch_line) { unsigned count; unsigned src_beg_line; unsigned hunk_offset_start; unsigned src_last_line = 1; unsigned dst_last_line = 1; if ((sscanf(patch_line, "@@ -%u,%u +%u,%u", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) && (sscanf(patch_line, "@@ -%u +%u,%u", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) ) { /* No more hunks for this file */ break; } if (plus != '+') { /* reverse patch */ unsigned tmp = src_last_line; src_last_line = dst_last_line; dst_last_line = tmp; tmp = src_beg_line; src_beg_line = dst_beg_line; dst_beg_line = tmp; } hunk_count++; if (src_beg_line && dst_beg_line) { /* Copy unmodified lines upto start of hunk */ /* src_beg_line will be 0 if it's a new file */ count = src_beg_line - src_cur_line; if (copy_lines(src_stream, dst_stream, count)) { bb_error_msg_and_die("bad src file"); } src_cur_line += count; dst_cur_line += count; copy_trailing_lines_flag = 1; } src_last_line += hunk_offset_start = src_cur_line; dst_last_line += dst_cur_line; while (1) { free(patch_line); patch_line = xmalloc_fgets(patch_file); if (patch_line == NULL) break; /* EOF */ if (!*patch_line) { /* whitespace-damaged patch with "" lines */ free(patch_line); patch_line = xstrdup(" "); } if ((*patch_line != '-') && (*patch_line != '+') && (*patch_line != ' ') ) { break; /* End of hunk */ } if (*patch_line != plus) { /* '-' or ' ' */ char *src_line = NULL; if (src_cur_line == src_last_line) break; if (src_stream) { src_line = xmalloc_fgets(src_stream); if (src_line) { int diff = strcmp(src_line, patch_line + 1); src_cur_line++; free(src_line); if (diff) src_line = NULL; } } /* Do not patch an already patched hunk with -N */ if (src_line == 0 && (opt & OPT_N)) { continue; } if (!src_line) { bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); bad_hunk_count++; break; } if (*patch_line != ' ') { /* '-' */ continue; } } if (dst_cur_line == dst_last_line) break; fputs(patch_line + 1, dst_stream); dst_cur_line++; } /* end of while loop handling one hunk */ } /* end of while loop handling one file */ /* Cleanup last patched file */ if (copy_trailing_lines_flag) { copy_lines(src_stream, dst_stream, (unsigned)(-1)); } if (src_stream) { fclose(src_stream); } fclose(dst_stream); if (bad_hunk_count) { ret = 1; bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count); } else { /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); } if (!(opt & OPT_dry_run) && ((dst_cur_line == 0) || (dst_beg_line == 0)) ) { /* The new patched file is empty, remove it */ xunlink(new_filename); // /* old_filename and new_filename may be the same file */ // unlink(old_filename); } } free(backup_filename); //free(old_filename); free(new_filename); } /* end of "while there are patch lines" */ quit: /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems (exited earlier) */ return ret; }
int nameif_main(int argc, char **argv) { mactable_t *clist = NULL; FILE *ifh; const char *fname = "/etc/mactab"; char *line; int ctl_sk; int if_index = 1; mactable_t *ch; if (1 & getopt32(argc, argv, "sc:", &fname)) { openlog(applet_name, 0, LOG_LOCAL0); logmode = LOGMODE_SYSLOG; } if ((argc - optind) & 1) bb_show_usage(); if (optind < argc) { char **a = argv + optind; while (*a) { if (strlen(*a) > IF_NAMESIZE) bb_error_msg_and_die("interface name '%s' " "too long", *a); ch = xzalloc(sizeof(mactable_t)); ch->ifname = xstrdup(*a++); ch->mac = cc_macaddr(*a++); if (clist) clist->prev = ch; ch->next = clist; clist = ch; } } else { ifh = xfopen(fname, "r"); while ((line = xmalloc_fgets(ifh)) != NULL) { char *line_ptr; size_t name_length; line_ptr = line + strspn(line, " \t"); if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) { free(line); continue; } name_length = strcspn(line_ptr, " \t"); ch = xzalloc(sizeof(mactable_t)); ch->ifname = xstrndup(line_ptr, name_length); if (name_length > IF_NAMESIZE) bb_error_msg_and_die("interface name '%s' " "too long", ch->ifname); line_ptr += name_length; line_ptr += strspn(line_ptr, " \t"); name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:"); line_ptr[name_length] = '\0'; ch->mac = cc_macaddr(line_ptr); if (clist) clist->prev = ch; ch->next = clist; clist = ch; free(line); } fclose(ifh); } ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0); while (clist) { struct ifreq ifr; memset(&ifr, 0, sizeof(struct ifreq)); if_index++; ifr.ifr_ifindex = if_index; /* Get ifname by index or die */ if (ioctl(ctl_sk, SIOCGIFNAME, &ifr)) break; /* Has this device hwaddr? */ if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr)) continue; /* Search for mac like in ifr.ifr_hwaddr.sa_data */ for (ch = clist; ch; ch = ch->next) if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN)) break; /* Nothing found for current ifr.ifr_hwaddr.sa_data */ if (ch == NULL) continue; strcpy(ifr.ifr_newname, ch->ifname); if (ioctl(ctl_sk, SIOCSIFNAME, &ifr) < 0) bb_perror_msg_and_die("cannot change ifname %s to %s", ifr.ifr_name, ch->ifname); /* Remove list entry of renamed interface */ if (ch->prev != NULL) { (ch->prev)->next = ch->next; } else { clist = ch->next; } if (ch->next != NULL) (ch->next)->prev = ch->prev; if (ENABLE_FEATURE_CLEAN_UP) { free(ch->ifname); free(ch->mac); free(ch); } } return 0; }
int patch_main(int argc, char **argv) { int patch_level = -1; char *patch_line; int ret; FILE *patch_file = NULL; { char *p, *i; ret = getopt32(argv, "p:i:", &p, &i); if (ret & 1) patch_level = xatol_range(p, -1, USHRT_MAX); if (ret & 2) { patch_file = xfopen(i, "r"); } else { patch_file = stdin; } ret = 0; } patch_line = xmalloc_getline(patch_file); while (patch_line) { FILE *src_stream; FILE *dst_stream; char *original_filename; char *new_filename; char *backup_filename; unsigned int src_cur_line = 1; unsigned int dest_cur_line = 0; unsigned int dest_beg_line; unsigned int bad_hunk_count = 0; unsigned int hunk_count = 0; char copy_trailing_lines_flag = 0; /* Skip everything upto the "---" marker * No need to parse the lines "Only in <dir>", and "diff <args>" */ while (patch_line && strncmp(patch_line, "--- ", 4) != 0) { free(patch_line); patch_line = xmalloc_getline(patch_file); } /* FIXME: patch_line NULL check?? */ /* Extract the filename used before the patch was generated */ original_filename = extract_filename(patch_line, patch_level); free(patch_line); patch_line = xmalloc_getline(patch_file); /* FIXME: NULL check?? */ if (strncmp(patch_line, "+++ ", 4) != 0) { ret = 2; bb_error_msg("invalid patch"); continue; } new_filename = extract_filename(patch_line, patch_level); free(patch_line); if (file_doesnt_exist(new_filename)) { char *line_ptr; /* Create leading directories */ line_ptr = strrchr(new_filename, '/'); if (line_ptr) { *line_ptr = '\0'; bb_make_directory(new_filename, -1, FILEUTILS_RECUR); *line_ptr = '/'; } dst_stream = xfopen(new_filename, "w+"); backup_filename = NULL; } else { backup_filename = xmalloc(strlen(new_filename) + 6); strcpy(backup_filename, new_filename); strcat(backup_filename, ".orig"); if (rename(new_filename, backup_filename) == -1) { bb_perror_msg_and_die("cannot create file %s", backup_filename); } dst_stream = xfopen(new_filename, "w"); } if ((backup_filename == NULL) || file_doesnt_exist(original_filename)) { src_stream = NULL; } else { if (strcmp(original_filename, new_filename) == 0) { src_stream = xfopen(backup_filename, "r"); } else { src_stream = xfopen(original_filename, "r"); } } printf("patching file %s\n", new_filename); /* Handle each hunk */ patch_line = xmalloc_fgets(patch_file); while (patch_line) { unsigned int count; unsigned int src_beg_line; unsigned int unused; unsigned int hunk_offset_start = 0; int hunk_error = 0; /* This bit should be improved */ if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) && (sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) && (sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) { /* No more hunks for this file */ break; } free(patch_line); hunk_count++; if (src_beg_line && dest_beg_line) { /* Copy unmodified lines upto start of hunk */ /* src_beg_line will be 0 if its a new file */ count = src_beg_line - src_cur_line; if (copy_lines(src_stream, dst_stream, count) != count) { bb_error_msg_and_die("bad src file"); } src_cur_line += count; dest_cur_line += count; copy_trailing_lines_flag = 1; } hunk_offset_start = src_cur_line; while ((patch_line = xmalloc_fgets(patch_file)) != NULL) { if ((*patch_line == '-') || (*patch_line == ' ')) { char *src_line = NULL; if (src_stream) { src_line = xmalloc_fgets(src_stream); if (!src_line) { hunk_error++; break; } else { src_cur_line++; } if (strcmp(src_line, patch_line + 1) != 0) { bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start); hunk_error++; free(patch_line); /* Probably need to find next hunk, etc... */ /* but for now we just bail out */ patch_line = NULL; break; } free(src_line); } if (*patch_line == ' ') { fputs(patch_line + 1, dst_stream); dest_cur_line++; } } else if (*patch_line == '+') { fputs(patch_line + 1, dst_stream); dest_cur_line++; } else { break; } free(patch_line); } if (hunk_error) { bad_hunk_count++; } } /* Cleanup last patched file */ if (copy_trailing_lines_flag) { copy_lines(src_stream, dst_stream, -1); } if (src_stream) { fclose(src_stream); } if (dst_stream) { fclose(dst_stream); } if (bad_hunk_count) { if (!ret) { ret = 1; } bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count); } else { /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); } if ((dest_cur_line == 0) || (dest_beg_line == 0)) { /* The new patched file is empty, remove it */ xunlink(new_filename); if (strcmp(new_filename, original_filename) != 0) xunlink(original_filename); } } } /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems */ return ret; }