/* append a new user to the passwd file */ static int addgroup(char *group, gid_t gid, const char *user) { FILE *file; struct group gr; /* make sure gid and group haven't already been allocated */ gr.gr_gid = gid; gr.gr_name = group; if (group_study(&gr)) return 1; /* add entry to group */ file = bb_xfopen(bb_path_group_file, "a"); /* group:passwd:gid:userlist */ fprintf(file, "%s:%s:%d:%s\n", group, "x", gr.gr_gid, user); fclose(file); #if ENABLE_FEATURE_SHADOWPASSWDS file = bb_xfopen(bb_path_gshadow_file, "a"); fprintf(file, "%s:!::\n", group); fclose(file); #endif /* return 1; */ return 0; }
static void data_readlines(void) { int i; char current_line[256]; FILE *fp; fp = (inp_stdin) ? stdin : bb_xfopen(filename, "r"); flines = NULL; for (i = 0; (feof(fp)==0) && (i <= MAXLINES); i++) { strcpy(current_line, ""); fgets(current_line, 256, fp); if (fp != stdin) bb_xferror(fp, filename); flines = xrealloc(flines, (i+1) * sizeof(char *)); flines[i] = bb_xstrdup(current_line); } num_flines = i - 2; /* Reset variables for a new file */ line_pos = 0; past_eof = 0; fclose(fp); if (inp == NULL) inp = (inp_stdin) ? bb_xfopen(CURRENT_TTY, "r") : stdin; if (flags & FLAG_N) add_linenumbers(); }
static void do_sethostname(char *s, int isfile) { FILE *f; char buf[255]; if (!s) return; if (!isfile) { if (sethostname(s, strlen(s)) < 0) { if (errno == EPERM) bb_error_msg_and_die("you must be root to change the hostname"); else bb_perror_msg_and_die("sethostname"); } } else { f = bb_xfopen(s, "r"); while (fgets(buf, 255, f) != NULL) { if (buf[0] =='#') { continue; } chomp(buf); do_sethostname(buf, 0); } #ifdef CONFIG_FEATURE_CLEAN_UP fclose(f); #endif } }
/* make sure gr_name isn't taken, make sure gid is kosher * return 1 on failure */ static int group_study(const char *filename, struct group *g) { FILE *etc_group; gid_t desired; struct group *grp; const int max = 65000; etc_group = bb_xfopen(filename, "r"); /* make sure gr_name isn't taken, make sure gid is kosher */ desired = g->gr_gid; while ((grp = fgetgrent(etc_group))) { if ((strcmp(grp->gr_name, g->gr_name)) == 0) { bb_error_msg_and_die("%s: group already in use\n", g->gr_name); } if ((desired) && grp->gr_gid == desired) { bb_error_msg_and_die("%d: gid has already been allocated\n", desired); } if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) { g->gr_gid = grp->gr_gid; } } fclose(etc_group); /* gid */ if (desired) { g->gr_gid = desired; } else { g->gr_gid++; } /* return 1; */ return 0; }
/* * Process the commands arguments */ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) { /* handle (s)ubstitution command */ if (sed_cmd->cmd == 's') cmdstr += parse_subst_cmd(sed_cmd, cmdstr); /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ else if (strchr("aic", sed_cmd->cmd)) { if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') bb_error_msg_and_die ("only a beginning address can be specified for edit commands"); while(isspace(*cmdstr)) cmdstr++; sed_cmd->string = bb_xstrdup(cmdstr); parse_escapes(sed_cmd->string,sed_cmd->string,strlen(cmdstr),0,0); cmdstr += strlen(cmdstr); /* handle file cmds: (r)ead */ } else if(strchr("rw", sed_cmd->cmd)) { if (sed_cmd->end_line || sed_cmd->end_match) bb_error_msg_and_die("Command only uses one address"); cmdstr += parse_file_cmd(sed_cmd, cmdstr, &sed_cmd->string); if(sed_cmd->cmd=='w') sed_cmd->file=bb_xfopen(sed_cmd->string,"w"); /* handle branch commands */ } else if (strchr(":bt", sed_cmd->cmd)) { int length; while(isspace(*cmdstr)) cmdstr++; length = strcspn(cmdstr, semicolon_whitespace); if (length) { sed_cmd->string = strndup(cmdstr, length); cmdstr += length; } } /* translation command */ else if (sed_cmd->cmd == 'y') { char *match, *replace; int i=cmdstr[0]; cmdstr+=parse_regex_delim(cmdstr, &match, &replace)+1; /* \n already parsed, but \delimiter needs unescaping. */ parse_escapes(match,match,strlen(match),i,i); parse_escapes(replace,replace,strlen(replace),i,i); sed_cmd->string = xcalloc(1, (strlen(match) + 1) * 2); for (i = 0; match[i] && replace[i]; i++) { sed_cmd->string[i * 2] = match[i]; sed_cmd->string[(i * 2) + 1] = replace[i]; } free(match); free(replace); } /* if it wasnt a single-letter command that takes no arguments * then it must be an invalid command. */ else if (strchr("dDgGhHlnNpPqx={}", sed_cmd->cmd) == 0) { bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd); } /* give back whatever's left over */ return (cmdstr); }
/* setspent - initialize access to shadow text and DBM files */ void setspent(void) { if (shadow) { rewind(shadow); } else { shadow = bb_xfopen(bb_path_shadow_file, "r"); } }
static FILE *xgetoptfile_uniq_s(char **argv, int read0write2) { const char *n; if ((n = *argv) != NULL) { if ((*n != '-') || n[1]) { return bb_xfopen(n, "r\0w" + read0write2); } } return (read0write2) ? stdout : stdin; }
/* append a new user to the passwd file */ static int addgroup(const char *filename, char *group, gid_t gid, const char *user) { FILE *etc_group; #ifdef CONFIG_FEATURE_SHADOWPASSWDS FILE *etc_gshadow; #endif struct group gr; /* group:passwd:gid:userlist */ static const char entryfmt[] = "%s:%s:%d:%s\n"; /* make sure gid and group haven't already been allocated */ gr.gr_gid = gid; gr.gr_name = group; if (group_study(filename, &gr)) return 1; /* add entry to group */ etc_group = bb_xfopen(filename, "a"); fprintf(etc_group, entryfmt, group, default_passwd, gr.gr_gid, user); fclose(etc_group); #ifdef CONFIG_FEATURE_SHADOWPASSWDS /* add entry to gshadow if necessary */ if (access(bb_path_gshadow_file, F_OK|W_OK) == 0) { etc_gshadow = bb_xfopen(bb_path_gshadow_file, "a"); fprintf(etc_gshadow, "%s:!::\n", group); fclose(etc_gshadow); } #endif /* return 1; */ return 0; }
int lsmod_main(int argc, char **argv) { printf("Module Size Used by"); check_tainted(); #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT) { FILE *file; char line[4096]; file = bb_xfopen("/proc/modules", "r"); while (fgets(line, sizeof(line), file)) { 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 = ""; /* 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 = ""; printf(" %s", tok); } printf("\n"); } fclose(file); } return 0; /* Success */ #else if (bb_xprint_file_by_name("/proc/modules") < 0) { return 0; } #endif /* CONFIG_FEATURE_2_6_MODULES */ return 1; }
static void load_regexes_from_file(llist_t *fopt) { char *line; FILE *f; while(fopt) { llist_t *cur = fopt; char *ffile = cur->data; fopt = cur->link; free(cur); f = bb_xfopen(ffile, "r"); while ((line = bb_get_chomped_line_from_file(f)) != NULL) { pattern_head = llist_add_to(pattern_head, line); } } }
static void bb_dump_addfile(char *name) { register char *p; FILE *fp; char *buf; fp = bb_xfopen(name, "r"); while ((buf = bb_get_chomped_line_from_file(fp)) != NULL) { p = skip_whitespace(buf); if (*p && (*p != '#')) { bb_dump_add(p); } free(buf); } fclose(fp); }
long my_getgrnam(const char *name) { struct group *mygroup; FILE *stream; stream = bb_xfopen(GROUP_PATH, "r"); while(1) { errno = 0; mygroup = fgetgrent(stream); if (mygroup == NULL) bb_error_msg_and_die("unknown group name: %s", name); if (errno) bb_perror_msg_and_die("fgetgrent"); if (!strcmp(name, mygroup->gr_name)) break; } fclose(stream); return mygroup->gr_gid; }
long my_getpwnam(const char *name) { struct passwd *myuser; FILE *stream; stream = bb_xfopen(PASSWD_PATH, "r"); while(1) { errno = 0; myuser = fgetpwent(stream); if (myuser == NULL) bb_error_msg_and_die("unknown user name: %s", name); if (errno) bb_perror_msg_and_die("fgetpwent"); if (!strcmp(name, myuser->pw_name)) break; } fclose(stream); return myuser->pw_uid; }
static void save_input_to_file(void) { char current_line[256]; int i; FILE *fp; clear_line(); printf("Log file: "); fgets(current_line, 256, inp); current_line[strlen(current_line) - 1] = '\0'; if (strlen(current_line) > 1) { fp = bb_xfopen(current_line, "w"); for (i = 0; i < num_flines; i++) fprintf(fp, "%s", flines[i]); fclose(fp); buffer_print(); } else printf("%sNo log file%s", HIGHLIGHT, NORMAL); }
static llist_t *append_file_list_to_list(llist_t *list) { FILE *src_stream; llist_t *cur = list; llist_t *tmp; char *line; llist_t *newlist = NULL; while(cur) { src_stream = bb_xfopen(cur->data, "r"); tmp = cur; cur = cur->link; free(tmp); while((line = bb_get_chomped_line_from_file(src_stream)) != NULL) { newlist = llist_add_to(newlist, line); } fclose(src_stream); } return newlist; }
/* This could become a common function for md5 as well, by using md5_stream */ static int hash_files(int argc, char **argv, const uint8_t hash_algo) { int return_value = EXIT_SUCCESS; uint8_t *hash_value; #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK unsigned int flags; flags = bb_getopt_ulflags(argc, argv, "scw"); #endif #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK if (!(flags & FLAG_CHECK)) { if (flags & FLAG_SILENT) { bb_error_msg_and_die ("the -s option is meaningful only when verifying checksums"); } else if (flags & FLAG_WARN) { bb_error_msg_and_die ("the -w option is meaningful only when verifying checksums"); } } #endif if (argc == optind) { argv[argc++] = "-"; } #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK if (flags & FLAG_CHECK) { FILE *pre_computed_stream; int count_total = 0; int count_failed = 0; char *file_ptr = argv[optind]; char *line; if (optind + 1 != argc) { bb_error_msg_and_die ("only one argument may be specified when using -c"); } if (strcmp(file_ptr, "-") == 0) { pre_computed_stream = stdin; } else { pre_computed_stream = bb_xfopen(file_ptr, "r"); } while ((line = bb_get_chomped_line_from_file(pre_computed_stream)) != NULL) { char *filename_ptr; count_total++; filename_ptr = strstr(line, " "); if (filename_ptr == NULL) { if (flags & FLAG_WARN) { bb_error_msg("Invalid format"); } count_failed++; return_value = EXIT_FAILURE; free(line); continue; } *filename_ptr = '\0'; filename_ptr += 2; hash_value = hash_file(filename_ptr, hash_algo); if (hash_value && (strcmp((char*)hash_value, line) == 0)) { if (!(flags & FLAG_SILENT)) printf("%s: OK\n", filename_ptr); } else { if (!(flags & FLAG_SILENT)) printf("%s: FAILED\n", filename_ptr); count_failed++; return_value = EXIT_FAILURE; } /* possible free(NULL) */ free(hash_value); free(line); } if (count_failed && !(flags & FLAG_SILENT)) { bb_error_msg("WARNING: %d of %d computed checksums did NOT match", count_failed, count_total); } if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { bb_perror_msg_and_die("Couldnt close file %s", file_ptr); } } else #endif { while (optind < argc) { char *file_ptr = argv[optind++]; hash_value = hash_file(file_ptr, hash_algo); if (hash_value == NULL) { return_value = EXIT_FAILURE; } else { printf("%s %s\n", hash_value, file_ptr); free(hash_value); } } } return (return_value); }
extern int sed_main(int argc, char **argv) { int opt, status = EXIT_SUCCESS; #ifdef CONFIG_FEATURE_CLEAN_UP /* destroy command strings on exit */ if (atexit(free_and_close_stuff) == -1) bb_perror_msg_and_die("atexit"); #endif #define LIE_TO_AUTOCONF #ifdef LIE_TO_AUTOCONF if(argc==2 && !strcmp(argv[1],"--version")) { printf("This is not GNU sed version 4.0\n"); exit(0); } #endif /* do normal option parsing */ while ((opt = getopt(argc, argv, "ne:f:")) > 0) { switch (opt) { case 'n': be_quiet++; break; case 'e': add_cmd_block(optarg); break; case 'f': { FILE *cmdfile; char *line; cmdfile = bb_xfopen(optarg, "r"); while ((line = bb_get_chomped_line_from_file(cmdfile)) != NULL) { add_cmd(line); free(line); } bb_xprint_and_close_file(cmdfile); break; } default: bb_show_usage(); } } /* if we didn't get a pattern from a -e and no command file was specified, * argv[optind] should be the pattern. no pattern, no worky */ if (sed_cmd_head.next == NULL) { if (argv[optind] == NULL) bb_show_usage(); else add_cmd_block(argv[optind++]); } /* Flush any unfinished commands. */ add_cmd(""); /* argv[(optind)..(argc-1)] should be names of file to process. If no * files were specified or '-' was specified, take input from stdin. * Otherwise, we process all the files specified. */ if (argv[optind] == NULL) { process_file(stdin); } else { int i; FILE *file; for (i = optind; i < argc; i++) { if(!strcmp(argv[i], "-")) { process_file(stdin); } else { file = bb_wfopen(argv[i], "r"); if (file) { process_file(file); fclose(file); } else { status = EXIT_FAILURE; } } } } return status; }
// if fn is NULL then input is stdin and output is stdout static int convert(char *fn, int ConvType) { int c, fd; struct timeval tv; char tempFn[BUFSIZ]; static bb_uint64_t value=0; FILE *in = stdin, *out = stdout; if (fn != NULL) { in = bb_xfopen(fn, "rw"); safe_strncpy(tempFn, fn, sizeof(tempFn)); c = strlen(tempFn); tempFn[c] = '.'; while(1) { /* tempFn is BUFSIZ so the last addressable spot it BUFSIZ-1. * The loop increments by 2. So this must check for BUFSIZ-3. */ if (c >=BUFSIZ-3) bb_error_msg_and_die("unique name not found"); /* Get some semi random stuff to try and make a * random filename based (and in the same dir as) * the input file... */ gettimeofday (&tv, NULL); value += ((bb_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); tempFn[++c] = letters[value % 62]; tempFn[c+1] = '\0'; value /= 62; if ((fd = open(tempFn, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0 ) { continue; } out = fdopen(fd, "w+"); if (!out) { close(fd); remove(tempFn); continue; } break; } } while ((c = fgetc(in)) != EOF) { if (c == '\r') { if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) { // file is alredy in DOS format so it is not necessery to touch it remove(tempFn); if (fclose(in) < 0 || fclose(out) < 0) { bb_perror_nomsg(); return -2; } return 0; } if (!ConvType) ConvType = CT_DOS2UNIX; break; } if (c == '\n') { if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) { // file is alredy in UNIX format so it is not necessery to touch it remove(tempFn); if ((fclose(in) < 0) || (fclose(out) < 0)) { bb_perror_nomsg(); return -2; } return 0; } if (!ConvType) { ConvType = CT_UNIX2DOS; } if (ConvType == CT_UNIX2DOS) { fputc('\r', out); } fputc('\n', out); break; } fputc(c, out); } if (c != EOF) while ((c = fgetc(in)) != EOF) { if (c == '\r') continue; if (c == '\n') { if (ConvType == CT_UNIX2DOS) fputc('\r', out); fputc('\n', out); continue; } fputc(c, out); } if (fn != NULL) { if (fclose(in) < 0 || fclose(out) < 0) { bb_perror_nomsg(); remove(tempFn); return -2; } /* Assume they are both on the same filesystem (which * should be true since we put them into the same directory * so we _should_ be ok, but you never know... */ if (rename(tempFn, fn) < 0) { bb_perror_msg("unable to rename '%s' as '%s'", tempFn, fn); return -1; } } return 0; }
static int readmode(struct fb_var_screeninfo *base, const char *fn, const char *mode) { #ifdef CONFIG_FEATURE_FBSET_READMODE FILE *f; char buf[256]; char *p = buf; f = bb_xfopen(fn, "r"); while (!feof(f)) { fgets(buf, sizeof(buf), f); if ((p = strstr(buf, "mode ")) || (p = strstr(buf, "mode\t"))) { p += 5; if ((p = strstr(buf, mode))) { p += strlen(mode); if (!isspace(*p) && (*p != 0) && (*p != '"') && (*p != '\r') && (*p != '\n')) continue; /* almost, but not quite */ while (!feof(f)) { fgets(buf, sizeof(buf), f); if ((p = strstr(buf, "geometry "))) { p += 9; sscanf(p, "%d %d %d %d %d", &(base->xres), &(base->yres), &(base->xres_virtual), &(base->yres_virtual), &(base->bits_per_pixel)); } else if ((p = strstr(buf, "timings "))) { p += 8; sscanf(p, "%d %d %d %d %d %d %d", &(base->pixclock), &(base->left_margin), &(base->right_margin), &(base->upper_margin), &(base->lower_margin), &(base->hsync_len), &(base->vsync_len)); } else if ((p = strstr(buf, "laced "))) { p += 6; if (strstr(buf, "false")) { base->vmode &= ~FB_VMODE_INTERLACED; } else { base->vmode |= FB_VMODE_INTERLACED; } } else if ((p = strstr(buf, "double "))) { p += 7; if (strstr(buf, "false")) { base->vmode &= ~FB_VMODE_DOUBLE; } else { base->vmode |= FB_VMODE_DOUBLE; } } else if ((p = strstr(buf, "vsync "))) { p += 6; if (strstr(buf, "low")) { base->sync &= ~FB_SYNC_VERT_HIGH_ACT; } else { base->sync |= FB_SYNC_VERT_HIGH_ACT; } } else if ((p = strstr(buf, "hsync "))) { p += 6; if (strstr(buf, "low")) { base->sync &= ~FB_SYNC_HOR_HIGH_ACT; } else { base->sync |= FB_SYNC_HOR_HIGH_ACT; } } else if ((p = strstr(buf, "csync "))) { p += 6; if (strstr(buf, "low")) { base->sync &= ~FB_SYNC_COMP_HIGH_ACT; } else { base->sync |= FB_SYNC_COMP_HIGH_ACT; } } else if ((p = strstr(buf, "extsync "))) { p += 8; if (strstr(buf, "false")) { base->sync &= ~FB_SYNC_EXT; } else { base->sync |= FB_SYNC_EXT; } } if (strstr(buf, "endmode")) return 1; } } } } #else bb_error_msg( "mode reading not compiled in"); #endif return 0; }
static void INET6_displayroutes(int noresolve) { char addr6[128], naddr6[128]; /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses. * We read the non-delimited strings into the tail of the buffer * using fscanf and then modify the buffer by shifting forward * while inserting ':'s and the nul terminator for the first string. * Hence the strings are at addr6x and addr6x+40. This generates * _much_ less code than the previous (upstream) approach. */ char addr6x[80]; char iface[16], flags[16]; int iflags, metric, refcnt, use, prefix_len, slen; struct sockaddr_in6 snaddr6; FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r"); bb_printf("Kernel IPv6 routing table\n%-44s%-40s" "Flags Metric Ref Use Iface\n", "Destination", "Next Hop"); while (1) { int r; r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n", addr6x+14, &prefix_len, &slen, addr6x+40+7, &metric, &use, &refcnt, &iflags, iface); if (r != 9) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; } ERROR: bb_error_msg_and_die("fscanf"); } /* Do the addr6x shift-and-insert changes to ':'-delimit addresses. * For now, always do this to validate the proc route format, even * if the interface is down. */ { int i = 0; char *p = addr6x+14; do { if (!*p) { if (i==40) { /* nul terminator for 1st address? */ addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */ ++p; /* Skip and continue. */ continue; } goto ERROR; } addr6x[i++] = *p++; if (!((i+1)%5)) { addr6x[i++] = ':'; } } while (i < 40+28+7); } if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */ continue; } set_flags(flags, (iflags & IPV6_MASK)); r = 0; do { inet_pton(AF_INET6, addr6x + r, (struct sockaddr *) &snaddr6.sin6_addr); snaddr6.sin6_family = AF_INET6; INET6_rresolve(naddr6, sizeof(naddr6), (struct sockaddr_in6 *) &snaddr6, #if 0 (noresolve | 0x8000) /* Default instead of *. */ #else 0x0fff /* Apparently, upstream never resolves. */ #endif ); if (!r) { /* 1st pass */ snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); r += 40; } else { /* 2nd pass */ /* Print the info. */ bb_printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", addr6, naddr6, flags, metric, refcnt, use, iface); break; } } while (1); } }
int main(int argc, char **argv) { int opt; FILE *table = stdin; char *rootdir = NULL; char *line = NULL; int linenum = 0; int ret = EXIT_SUCCESS; bb_applet_name = basename(argv[0]); while ((opt = getopt(argc, argv, "d:")) != -1) { switch(opt) { case 'd': table = bb_xfopen((line=optarg), "r"); break; default: bb_show_usage(); } } if (optind >= argc || (rootdir=argv[optind])==NULL) { bb_error_msg_and_die("root directory not speficied"); } if (chdir(rootdir) != 0) { bb_perror_msg_and_die("Couldnt chdir to %s", rootdir); } umask(0); printf("rootdir=%s\n", rootdir); if (line) { printf("table='%s'\n", line); } else { printf("table=<stdin>\n"); } while ((line = bb_get_chomped_line_from_file(table))) { char type; unsigned int mode = 0755; unsigned int major = 0; unsigned int minor = 0; unsigned int count = 0; unsigned int increment = 0; unsigned int start = 0; char name[4096]; char user[41]; char group[41]; char *full_name; uid_t uid; gid_t gid; linenum++; if ((2 > sscanf(line, "%4095s %c %o %40s %40s %u %u %u %u %u", name, &type, &mode, user, group, &major, &minor, &start, &increment, &count)) || ((major | minor | start | count | increment) > 0xfffff)) { if (*line=='\0' || *line=='#' || isspace(*line)) continue; bb_error_msg("line %d invalid: '%s'\n", linenum, line); ret = EXIT_FAILURE; continue; } if (name[0] == '#') { continue; } if (*group) { gid = get_ug_id(group, my_getgrnam); } else { gid = getgid(); } if (*user) { uid = get_ug_id(user, my_getpwnam); } else { uid = getuid(); } full_name = concat_path_file(rootdir, name); if (type == 'd') { bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } } else if (type == 'f') { struct stat st; if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) { bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } } else if (type == 'r') { recursive_uid = uid; recursive_gid = gid; recursive_mode = mode; if (nftw(full_name, bb_recursive, 20, FTW_MOUNT | FTW_PHYS) < 0) { bb_perror_msg("line %d: recursive failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } } else { dev_t rdev; if (type == 'p') { mode |= S_IFIFO; } else if (type == 'c') { mode |= S_IFCHR; } else if (type == 'b') { mode |= S_IFBLK; } else { bb_error_msg("line %d: Unsupported file type %c", linenum, type); ret = EXIT_FAILURE; goto loop; } if (count > 0) { int i; char *full_name_inc; full_name_inc = xmalloc(strlen(full_name) + 8); for (i = 0; i < count; i++) { sprintf(full_name_inc, "%s%d", full_name, start + i); rdev = makedev(major, minor + i * increment); if (mknod(full_name_inc, mode, rdev) == -1) { bb_perror_msg("line %d: Couldnt create node %s", linenum, full_name_inc); ret = EXIT_FAILURE; } else if (chown(full_name_inc, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc); ret = EXIT_FAILURE; } if ((mode != -1) && (chmod(full_name_inc, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name_inc); ret = EXIT_FAILURE; } } free(full_name_inc); } else { rdev = makedev(major, minor); if (mknod(full_name, mode, rdev) == -1) { bb_perror_msg("line %d: Couldnt create node %s", linenum, full_name); ret = EXIT_FAILURE; } else if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; } } } loop: free(line); free(full_name); } fclose(table); return ret; }
int readprofile_main(int argc, char **argv) { FILE *map; int proFd; const char *mapFile, *proFile, *mult=0; unsigned long len=0, indx=1; unsigned long long add0=0; unsigned int step; unsigned int *buf, total, fn_len; unsigned long long fn_add, next_add; /* current and next address */ char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */ char mode[8]; int c; int optAll=0, optInfo=0, optReset=0, optVerbose=0, optNative=0; int optBins=0, optSub=0; char mapline[S_LEN]; int maplineno=1; int header_printed; #define next (current^1) proFile = defaultpro; mapFile = defaultmap; while ((c = getopt(argc, argv, "M:m:np:itvarVbs")) != -1) { switch(c) { case 'm': mapFile = optarg; break; case 'n': optNative++; break; case 'p': proFile = optarg; break; case 'a': optAll++; break; case 'b': optBins++; break; case 's': optSub++; break; case 'i': optInfo++; break; case 'M': mult = optarg; break; case 'r': optReset++; break; case 'v': optVerbose++; break; default: bb_show_usage(); } } if (optReset || mult) { int multiplier, fd, to_write; /* * When writing the multiplier, if the length of the write is * not sizeof(int), the multiplier is not changed */ if (mult) { multiplier = strtoul(mult, 0, 10); to_write = sizeof(int); } else { multiplier = 0; to_write = 1; /* sth different from sizeof(int) */ } fd = bb_xopen(defaultpro,O_WRONLY); if (write(fd, &multiplier, to_write) != to_write) bb_perror_msg_and_die("error writing %s", defaultpro); close(fd); return EXIT_SUCCESS; } /* * Use an fd for the profiling buffer, to skip stdio overhead */ proFd = bb_xopen(proFile,O_RDONLY); if (((int)(len=lseek(proFd,0,SEEK_END)) < 0) || (lseek(proFd,0,SEEK_SET) < 0)) bb_perror_msg_and_die(proFile); buf = xmalloc(len); if (read(proFd,buf,len) != len) bb_perror_msg_and_die(proFile); close(proFd); if (!optNative) { int entries = len/sizeof(*buf); int big = 0,small = 0,i; unsigned *p; for (p = buf+1; p < buf+entries; p++) { if (*p & ~0U << (sizeof(*buf)*4)) big++; if (*p & ((1 << (sizeof(*buf)*4))-1)) small++; } if (big > small) { bb_error_msg("Assuming reversed byte order. " "Use -n to force native byte order."); for (p = buf; p < buf+entries; p++) for (i = 0; i < sizeof(*buf)/2; i++) { unsigned char *b = (unsigned char *) p; unsigned char tmp; tmp = b[i]; b[i] = b[sizeof(*buf)-i-1]; b[sizeof(*buf)-i-1] = tmp; } } } step = buf[0]; if (optInfo) { printf("Sampling_step: %i\n", step); return EXIT_SUCCESS; } total = 0; map = bb_xfopen(mapFile, "r"); while (fgets(mapline,S_LEN,map)) { if (sscanf(mapline,"%llx %s %s",&fn_add,mode,fn_name) != 3) bb_error_msg_and_die("%s(%i): wrong map line", mapFile, maplineno); if (!strcmp(fn_name,"_stext")) /* only elf works like this */ { add0 = fn_add; break; } maplineno++; } if (!add0) bb_error_msg_and_die("can't find \"_stext\" in %s", mapFile); /* * Main loop. */ while (fgets(mapline,S_LEN,map)) { unsigned int this = 0; if (sscanf(mapline,"%llx %s %s",&next_add,mode,next_name) != 3) bb_error_msg_and_die("%s(%i): wrong map line", mapFile, maplineno); header_printed = 0; /* ignore any LEADING (before a '[tT]' symbol is found) Absolute symbols */ if ((*mode == 'A' || *mode == '?') && total == 0) continue; if (*mode != 'T' && *mode != 't' && *mode != 'W' && *mode != 'w') break; /* only text is profiled */ if (indx >= len / sizeof(*buf)) bb_error_msg_and_die("profile address out of range. " "Wrong map file?"); while (indx < (next_add-add0)/step) { if (optBins && (buf[indx] || optAll)) { if (!header_printed) { printf ("%s:\n", fn_name); header_printed = 1; } printf ("\t%llx\t%u\n", (indx - 1)*step + add0, buf[indx]); } this += buf[indx++]; } total += this; if (optBins) { if (optVerbose || this > 0) printf (" total\t\t\t\t%u\n", this); } else if ((this || optAll) && (fn_len = next_add-fn_add) != 0) { if (optVerbose) printf("%016llx %-40s %6i %8.4f\n", fn_add, fn_name,this,this/(double)fn_len); else printf("%6i %-40s %8.4f\n", this,fn_name,this/(double)fn_len); if (optSub) { unsigned long long scan; for (scan = (fn_add-add0)/step + 1; scan < (next_add-add0)/step; scan++) { unsigned long long addr; addr = (scan - 1)*step + add0; printf("\t%#llx\t%s+%#llx\t%u\n", addr, fn_name, addr - fn_add, buf[scan]); } } } fn_add = next_add; strcpy(fn_name,next_name); maplineno++; } /* clock ticks, out of kernel text - probably modules */ printf("%6i %s\n", buf[len/sizeof(*buf)-1], "*unknown*"); /* trailer */ if (optVerbose) printf("%016x %-40s %6i %8.4f\n", 0,"total",total,total/(double)(fn_add-add0)); else printf("%6i %-40s %8.4f\n", total,"total",total/(double)(fn_add-add0)); fclose(map); free(buf); return EXIT_SUCCESS; }
int sort_main(int argc, char **argv) { FILE *fp,*outfile=NULL; int linecount=0,i,flag; char *line,**lines=NULL,*optlist="ngMucszbrdfimS:T:o:k:t:"; int c; bb_default_error_retval = 2; /* Parse command line options */ while((c=getopt(argc,argv,optlist))>0) { line=index(optlist,c); if(!line) bb_show_usage(); switch(*line) { #ifdef CONFIG_FEATURE_SORT_BIG case 'o': if(outfile) bb_error_msg_and_die("Too many -o."); outfile=bb_xfopen(optarg,"w"); break; case 't': if(key_separator || optarg[1]) bb_error_msg_and_die("Too many -t."); key_separator=*optarg; break; /* parse sort key */ case 'k': { struct sort_key *key=add_key(); char *temp, *temp2; temp=optarg; for(i=0;*temp;) { /* Start of range */ key->range[2*i]=(unsigned short)strtol(temp,&temp,10); if(*temp=='.') key->range[(2*i)+1]=(unsigned short)strtol(temp+1,&temp,10); for(;*temp;temp++) { if(*temp==',' && !i++) { temp++; break; } /* no else needed: fall through to syntax error because comma isn't in optlist */ temp2=index(optlist,*temp); flag=(1<<(temp2-optlist)); if(!temp2 || (flag>FLAG_M && flag<FLAG_b)) bb_error_msg_and_die("Unknown key option."); /* b after , means strip _trailing_ space */ if(i && flag==FLAG_b) flag=FLAG_bb; key->flags|=flag; } } break; } #endif default: global_flags|=(1<<(line-optlist)); /* global b strips leading and trailing spaces */ if(global_flags&FLAG_b) global_flags|=FLAG_bb; break; } } /* Open input files and read data */ for(i=argv[optind] ? optind : optind-1;argv[i];i++) { if(i<optind || (*argv[i]=='-' && !argv[i][1])) fp=stdin; else fp=bb_xfopen(argv[i],"r"); for(;;) { line=GET_LINE(fp); if(!line) break; if(!(linecount&63)) lines=xrealloc(lines, sizeof(char *)*(linecount+64)); lines[linecount++]=line; } fclose(fp); } #ifdef CONFIG_FEATURE_SORT_BIG /* if no key, perform alphabetic sort */ if(!key_list) add_key()->range[0]=1; /* handle -c */ if(global_flags&FLAG_c) { int j=(global_flags&FLAG_u) ? -1 : 0; for(i=1;i<linecount;i++) if(compare_keys(&lines[i-1],&lines[i])>j) { fprintf(stderr,"Check line %d\n",i); return 1; } return 0; } #endif /* Perform the actual sort */ qsort(lines,linecount,sizeof(char *),compare_keys); /* handle -u */ if(global_flags&FLAG_u) { for(flag=0,i=1;i<linecount;i++) { if(!compare_keys(&lines[flag],&lines[i])) free(lines[i]); else lines[++flag]=lines[i]; } if(linecount) linecount=flag+1; } /* Print it */ if(!outfile) outfile=stdout; for(i=0;i<linecount;i++) fprintf(outfile,"%s\n",lines[i]); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
void displayroutes(int noresolve, int netstatfmt) { char devname[64], flags[16], sdest[16], sgw[16]; unsigned long int d, g, m; int flgs, ref, use, metric, mtu, win, ir; struct sockaddr_in s_addr; struct in_addr mask; FILE *fp = bb_xfopen("/proc/net/route", "r"); bb_printf("Kernel IP routing table\n" "Destination Gateway Genmask" " Flags %s Iface\n", netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ goto ERROR; /* Empty or missing line, or read error. */ } while (1) { int r; r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", devname, &d, &g, &flgs, &ref, &use, &metric, &m, &mtu, &win, &ir); if (r != 11) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; } ERROR: bb_error_msg_and_die("fscanf"); } if (!(flgs & RTF_UP)) { /* Skip interfaces that are down. */ continue; } set_flags(flags, (flgs & IPV4_MASK)); #ifdef RTF_REJECT if (flgs & RTF_REJECT) { flags[0] = '!'; } #endif memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = d; INET_rresolve(sdest, sizeof(sdest), &s_addr, (noresolve | 0x8000), m); /* Default instead of *. */ s_addr.sin_addr.s_addr = g; INET_rresolve(sgw, sizeof(sgw), &s_addr, (noresolve | 0x4000), m); /* Host instead of net. */ mask.s_addr = m; bb_printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); if (netstatfmt) { bb_printf("%5d %-5d %6d %s\n", mtu, win, ir, devname); } else { bb_printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); } } }
extern int patch_main(int argc, char **argv) { unsigned int patch_level = -1; char *patch_line; int ret = 0; /* Handle 'p' option */ if (argv[1] && (argv[1][0] == '-') && (argv[1][1] == 'p')) { patch_level = atoi(&argv[1][2]); } patch_line = bb_get_line_from_file(stdin); 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 = bb_get_line_from_file(stdin); } /* Extract the filename used before the patch was generated */ original_filename = extract_filename(patch_line, patch_level); free(patch_line); patch_line = bb_get_line_from_file(stdin); 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 = bb_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("Couldnt create file %s", backup_filename); } dst_stream = bb_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 = bb_xfopen(backup_filename, "r"); } else { src_stream = bb_xfopen(original_filename, "r"); } } printf("patching file %s\n", new_filename); /* Handle each hunk */ patch_line = bb_get_line_from_file(stdin); 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 = bb_get_line_from_file(stdin)) != NULL) { if ((*patch_line == '-') || (*patch_line == ' ')) { char *src_line = NULL; if (src_stream) { src_line = bb_get_line_from_file(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); 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 */ if (unlink(new_filename) == -1) { bb_perror_msg_and_die("Couldnt remove file %s", new_filename); } if (unlink(original_filename) == -1) { bb_perror_msg_and_die("Couldnt remove original file %s", new_filename); } } } } /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems */ return(ret); }
/* if fn is NULL then input is stdin and output is stdout */ static int convert(char *fn, int ConvType) { int c, fd; FILE *in, *out; if (fn != NULL) { in = bb_xfopen(fn, "rw"); /* The file is then created with mode read/write and permissions 0666 for glibc 2.0.6 and earlier or 0600 for glibc 2.0.7 and later. */ snprintf(tempFn, sizeof(tempFn), "%sXXXXXX", fn); /* sizeof tempFn is 4096, so it should be big enough to hold the full path. however if the output is truncated the subsequent call to mkstemp would fail. */ if ((fd = mkstemp(&tempFn[0])) == -1 || chmod(tempFn, 0600) == -1) { bb_perror_nomsg_and_die(); } out = fdopen(fd, "w+"); if (!out) { close(fd); remove(tempFn); } } else { in = stdin; out = stdout; } while ((c = fgetc(in)) != EOF) { if (c == '\r') continue; if (c == '\n') { if (ConvType == CT_UNIX2DOS) fputc('\r', out); fputc('\n', out); continue; } fputc(c, out); } if (fn != NULL) { if (fclose(in) < 0 || fclose(out) < 0) { bb_perror_nomsg(); remove(tempFn); return -2; } /* Assume they are both on the same filesystem (which * should be true since we put them into the same directory * so we _should_ be ok, but you never know... */ if (rename(tempFn, fn) < 0) { bb_perror_msg("cannot rename '%s' as '%s'", tempFn, fn); return -1; } } return 0; }
void displayroutes(int noresolve, int netstatfmt) { char buff[256]; int nl = 0; struct in_addr dest; struct in_addr gw; struct in_addr mask; int flgs, ref, use, metric, mtu, win, ir; char flags[64]; unsigned long int d, g, m; char sdest[16], sgw[16]; FILE *fp = bb_xfopen("/proc/net/route", "r"); if (noresolve) noresolve = 0x0fff; printf("Kernel IP routing table\n"); printf ("Destination Gateway Genmask Flags %s Iface\n", netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); while (fgets(buff, sizeof(buff), fp) != NULL) { if (nl) { int ifl = 0; int numeric; struct sockaddr_in s_addr; while (buff[ifl] != ' ' && buff[ifl] != '\t' && buff[ifl] != '\0') ifl++; buff[ifl] = 0; /* interface */ if (sscanf(buff + ifl + 1, "%lx%lx%X%d%d%d%lx%d%d%d", &d, &g, &flgs, &ref, &use, &metric, &m, &mtu, &win, &ir) != 10) { bb_error_msg_and_die("Unsuported kernel route format\n"); } ifl = 0; /* parse flags */ if (flgs & RTF_UP) { if (flgs & RTF_REJECT) flags[ifl++] = '!'; else flags[ifl++] = 'U'; if (flgs & RTF_GATEWAY) flags[ifl++] = 'G'; if (flgs & RTF_HOST) flags[ifl++] = 'H'; if (flgs & RTF_REINSTATE) flags[ifl++] = 'R'; if (flgs & RTF_DYNAMIC) flags[ifl++] = 'D'; if (flgs & RTF_MODIFIED) flags[ifl++] = 'M'; flags[ifl] = 0; dest.s_addr = d; gw.s_addr = g; mask.s_addr = m; memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_addr = dest; numeric = noresolve | 0x8000; /* default instead of * */ INET_rresolve(sdest, sizeof(sdest), &s_addr, numeric, m); numeric = noresolve | 0x4000; /* host instead of net */ s_addr.sin_addr = gw; INET_rresolve(sgw, sizeof(sgw), &s_addr, numeric, m); printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); if (netstatfmt) printf("%5d %-5d %6d %s\n", mtu, win, ir, buff); else printf("%-6d %-2d %7d %s\n", metric, ref, use, buff); } } nl++; } }
static void INET6_displayroutes(int noresolve) { char buff[256]; char iface[16], flags[16]; char addr6[128], naddr6[128]; struct sockaddr_in6 saddr6, snaddr6; int iflags, metric, refcnt, use, prefix_len, slen; int numeric; char addr6p[8][5], saddr6p[8][5], naddr6p[8][5]; FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r"); flags[0] = 'U'; if (noresolve) noresolve = 0x0fff; numeric = noresolve | 0x8000; /* default instead of * */ printf("Kernel IPv6 routing table\n" "Destination " "Next Hop " "Flags Metric Ref Use Iface\n"); while (fgets(buff, sizeof(buff), fp) != NULL) { int ifl; if (sscanf(buff, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " "%4s%4s%4s%4s%4s%4s%4s%4s %02x " "%4s%4s%4s%4s%4s%4s%4s%4s %08x %08x %08x %08x %s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], &prefix_len, saddr6p[0], saddr6p[1], saddr6p[2], saddr6p[3], saddr6p[4], saddr6p[5], saddr6p[6], saddr6p[7], &slen, naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3], naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7], &metric, &use, &refcnt, &iflags, iface) != 31) { bb_error_msg_and_die("Unsuported kernel route format\n"); } ifl = 1; /* parse flags */ if (!(iflags & RTF_UP)) continue; if (iflags & RTF_GATEWAY) flags[ifl++] = 'G'; if (iflags & RTF_HOST) flags[ifl++] = 'H'; if (iflags & RTF_DEFAULT) flags[ifl++] = 'D'; if (iflags & RTF_ADDRCONF) flags[ifl++] = 'A'; if (iflags & RTF_CACHE) flags[ifl++] = 'C'; flags[ifl] = 0; /* Fetch and resolve the target address. */ snprintf(addr6, sizeof(addr6), "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); inet_pton(AF_INET6, addr6, (struct sockaddr *) &saddr6.sin6_addr); saddr6.sin6_family = AF_INET6; INET6_rresolve(addr6, sizeof(addr6), (struct sockaddr_in6 *) &saddr6, numeric); snprintf(addr6, sizeof(addr6), "%s/%d", addr6, prefix_len); /* Fetch and resolve the nexthop address. */ snprintf(naddr6, sizeof(naddr6), "%s:%s:%s:%s:%s:%s:%s:%s", naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3], naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7]); inet_pton(AF_INET6, naddr6, (struct sockaddr *) &snaddr6.sin6_addr); snaddr6.sin6_family = AF_INET6; INET6_rresolve(naddr6, sizeof(naddr6), (struct sockaddr_in6 *) &snaddr6, numeric); /* Print the info. */ printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", addr6, naddr6, flags, metric, refcnt, use, iface); } }
int makedevs_main(int argc, char **argv) { FILE *table = stdin; char *rootdir = NULL; char *line = NULL; int linenum = 0; int ret = EXIT_SUCCESS; unsigned long flags; flags = bb_getopt_ulflags(argc, argv, "d:", &line); if (line) table = bb_xfopen(line, "r"); if (optind >= argc || (rootdir=argv[optind])==NULL) { bb_error_msg_and_die("root directory not specified"); } bb_xchdir(rootdir); umask(0); printf("rootdir=%s\n", rootdir); if (line) { printf("table='%s'\n", line); } else { printf("table=<stdin>\n"); } while ((line = bb_get_chomped_line_from_file(table))) { char type; unsigned int mode = 0755; unsigned int major = 0; unsigned int minor = 0; unsigned int count = 0; unsigned int increment = 0; unsigned int start = 0; char name[41]; char user[41]; char group[41]; char *full_name; uid_t uid; gid_t gid; linenum++; if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, &type, &mode, user, group, &major, &minor, &start, &increment, &count)) || ((major | minor | start | count | increment) > 255)) { if (*line=='\0' || *line=='#' || isspace(*line)) continue; bb_error_msg("line %d invalid: '%s'\n", linenum, line); ret = EXIT_FAILURE; continue; } if (name[0] == '#') { continue; } gid = (*group) ? get_ug_id(group, bb_xgetgrnam) : getgid(); uid = (*user) ? get_ug_id(user, bb_xgetpwnam) : getuid(); full_name = concat_path_file(rootdir, name); if (type == 'd') { bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } } else if (type == 'f') { struct stat st; if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) { bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; goto loop; } } else { dev_t rdev; if (type == 'p') { mode |= S_IFIFO; } else if (type == 'c') { mode |= S_IFCHR; } else if (type == 'b') { mode |= S_IFBLK; } else { bb_error_msg("line %d: unsupported file type %c", linenum, type); ret = EXIT_FAILURE; goto loop; } if (count > 0) { int i; char *full_name_inc; full_name_inc = xmalloc(strlen(full_name) + 4); for (i = start; i < count; i++) { sprintf(full_name_inc, "%s%d", full_name, i); rdev = (major << 8) + minor + (i * increment - start); if (mknod(full_name_inc, mode, rdev) == -1) { bb_perror_msg("line %d: could not create node %s", linenum, full_name_inc); ret = EXIT_FAILURE; } else if (chown(full_name_inc, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc); ret = EXIT_FAILURE; } if ((mode != -1) && (chmod(full_name_inc, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name_inc); ret = EXIT_FAILURE; } } free(full_name_inc); } else { rdev = (major << 8) + minor; if (mknod(full_name, mode, rdev) == -1) { bb_perror_msg("line %d: could not create node %s", linenum, full_name); ret = EXIT_FAILURE; } else if (chown(full_name, uid, gid) == -1) { bb_perror_msg("line %d: chown failed for %s", linenum, full_name); ret = EXIT_FAILURE; } if ((mode != -1) && (chmod(full_name, mode) < 0)){ bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); ret = EXIT_FAILURE; } } } loop: free(line); free(full_name); } fclose(table); return ret; }