/* chown-like: * "user" sets uid only, * ":group" sets gid only * "user:"******"user:group" sets uid and gid * ('unset' uid or gid is actually set to -1) */ void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) { char *group; u->uid = -1; u->gid = -1; /* Check if there is a group name */ group = strchr(user_group, '.'); /* deprecated? */ if (!group) group = strchr(user_group, ':'); else *group = ':'; /* replace '.' with ':' */ /* Parse "user[:[group]]" */ if (!group) { /* "user" */ u->uid = get_ug_id(user_group, xuname2uid); } else if (group == user_group) { /* ":group" */ u->gid = get_ug_id(group + 1, xgroup2gid); } else { if (!group[1]) /* "user:"******"unknown user/group %s", user_group); } }
int chgrp_main(int argc, char **argv) { long gid; int recursiveFlag; int retval = EXIT_SUCCESS; recursiveFlag = bb_getopt_ulflags(argc, argv, "R"); if (argc - optind < 2) { bb_show_usage(); } argv += optind; /* Find the selected group */ gid = get_ug_id(*argv, my_getgrnam); ++argv; /* Ok, ready to do the deed now */ do { if (! recursive_action (*argv, recursiveFlag, FALSE, FALSE, fileAction, fileAction, &gid)) { retval = EXIT_FAILURE; } } while (*++argv); return retval; }
int chown_main(int argc, char **argv) { int flags; int retval = EXIT_SUCCESS; char *groupName; flags = bb_getopt_ulflags(argc, argv, "Rh"); if (flags & FLAG_h) chown_func = lchown; if (argc - optind < 2) { bb_show_usage(); } argv += optind; /* First, check if there is a group name here */ if ((groupName = strchr(*argv, '.')) == NULL) { groupName = strchr(*argv, ':'); } /* Check for the username and groupname */ if (groupName) { *groupName++ = '\0'; gid = get_ug_id(groupName, bb_xgetgrnam); } if (--groupName != *argv) uid = get_ug_id(*argv, bb_xgetpwnam); ++argv; /* Ok, ready to do the deed now */ do { if (! recursive_action (*argv, (flags & FLAG_R), FALSE, FALSE, fileAction, fileAction, NULL)) { retval = EXIT_FAILURE; } } while (*++argv); return retval; }
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 install_main(int argc, char **argv) { struct stat statbuf; mode_t mode; uid_t uid; gid_t gid; char *arg, *last; const char *gid_str; const char *uid_str; const char *mode_str; int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; int opts; int min_args = 1; int ret = EXIT_SUCCESS; int isdir = 0; #if ENABLE_SELINUX security_context_t scontext; bool use_default_selinux_context = 1; #endif enum { OPT_c = 1 << 0, OPT_v = 1 << 1, OPT_b = 1 << 2, OPT_MKDIR_LEADING = 1 << 3, OPT_DIRECTORY = 1 << 4, OPT_PRESERVE_TIME = 1 << 5, OPT_STRIP = 1 << 6, OPT_GROUP = 1 << 7, OPT_MODE = 1 << 8, OPT_OWNER = 1 << 9, #if ENABLE_SELINUX OPT_SET_SECURITY_CONTEXT = 1 << 10, OPT_PRESERVE_SECURITY_CONTEXT = 1 << 11, #endif }; #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS applet_long_options = install_longopts; #endif opt_complementary = "s--d:d--s" IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")); /* -c exists for backwards compatibility, it's needed */ /* -v is ignored ("print name of each created directory") */ /* -b is ignored ("make a backup of each existing destination file") */ opts = getopt32(argv, "cvb" "Ddpsg:m:o:" IF_SELINUX("Z:"), &gid_str, &mode_str, &uid_str IF_SELINUX(, &scontext)); argc -= optind; argv += optind; #if ENABLE_SELINUX if (opts & (OPT_PRESERVE_SECURITY_CONTEXT|OPT_SET_SECURITY_CONTEXT)) { selinux_or_die(); use_default_selinux_context = 0; if (opts & OPT_PRESERVE_SECURITY_CONTEXT) { copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; } if (opts & OPT_SET_SECURITY_CONTEXT) { setfscreatecon_or_die(scontext); copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT; } } #endif /* preserve access and modification time, this is GNU behaviour, * BSD only preserves modification time */ if (opts & OPT_PRESERVE_TIME) { copy_flags |= FILEUTILS_PRESERVE_STATUS; } mode = 0755; /* GNU coreutils 6.10 compat */ if (opts & OPT_MODE) bb_parse_mode(mode_str, &mode); uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); last = argv[argc - 1]; if (!(opts & OPT_DIRECTORY)) { argv[argc - 1] = NULL; min_args++; /* coreutils install resolves link in this case, don't use lstat */ isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); } if (argc < min_args) bb_show_usage(); while ((arg = *argv++) != NULL) { char *dest = last; if (opts & OPT_DIRECTORY) { dest = arg; /* GNU coreutils 6.9 does not set uid:gid * on intermediate created directories * (only on last one) */ if (bb_make_directory(dest, 0755, FILEUTILS_RECUR)) { ret = EXIT_FAILURE; goto next; } } else { if (opts & OPT_MKDIR_LEADING) { char *ddir = xstrdup(dest); bb_make_directory(dirname(ddir), 0755, FILEUTILS_RECUR); /* errors are not checked. copy_file * will fail if dir is not created. */ free(ddir); } if (isdir) dest = concat_path_file(last, bb_basename(arg)); if (copy_file(arg, dest, copy_flags) != 0) { /* copy is not made */ ret = EXIT_FAILURE; goto next; } if (opts & OPT_STRIP) { char *args[4]; args[0] = (char*)"strip"; args[1] = (char*)"-p"; /* -p --preserve-dates */ args[2] = dest; args[3] = NULL; if (spawn_and_wait(args)) { bb_perror_msg("strip"); ret = EXIT_FAILURE; } } } /* Set the file mode (always, not only with -m). * GNU coreutils 6.10 is not affected by umask. */ if (chmod(dest, mode) == -1) { bb_perror_msg("can't change %s of %s", "permissions", dest); ret = EXIT_FAILURE; } #if ENABLE_SELINUX if (use_default_selinux_context) setdefaultfilecon(dest); #endif /* Set the user and group id */ if ((opts & (OPT_OWNER|OPT_GROUP)) && lchown(dest, uid, gid) == -1 ) { bb_perror_msg("can't change %s of %s", "ownership", dest); ret = EXIT_FAILURE; } next: if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); } return ret; }
int makedevs_main(int argc UNUSED_PARAM, char **argv) { parser_t *parser; char *line = (char *)"-"; int ret = EXIT_SUCCESS; opt_complementary = "=1"; /* exactly one param */ getopt32(argv, "d:", &line); argv += optind; xchdir(*argv); /* ensure root dir exists */ umask(0); printf("rootdir=%s\ntable=", *argv); if (NOT_LONE_DASH(line)) { printf("'%s'\n", line); } else { puts("<stdin>"); } parser = config_open(line); while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) { int linenum; char type; unsigned mode = 0755; unsigned major = 0; unsigned minor = 0; unsigned count = 0; unsigned increment = 0; unsigned start = 0; char name[41]; char user[41]; char group[41]; char *full_name = name; uid_t uid; gid_t gid; linenum = parser->lineno; if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, &type, &mode, user, group, &major, &minor, &start, &increment, &count)) || ((unsigned)(major | minor | start | count | increment) > 255) ) { bb_error_msg("invalid line %d: '%s'", linenum, line); ret = EXIT_FAILURE; continue; } gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid(); uid = (*user) ? get_ug_id(user, xuname2uid) : getuid(); /* We are already in the right root dir, * so make absolute paths relative */ if ('/' == *full_name) full_name++; if (type == 'd') { bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); if (chown(full_name, uid, gid) == -1) { chown_fail: bb_perror_msg("line %d: can't chown %s", linenum, full_name); ret = EXIT_FAILURE; continue; } if (chmod(full_name, mode) < 0) { chmod_fail: bb_perror_msg("line %d: can't chmod %s", linenum, full_name); ret = EXIT_FAILURE; continue; } } 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; continue; } if (chown(full_name, uid, gid) < 0) goto chown_fail; if (chmod(full_name, mode) < 0) goto chmod_fail; } else { dev_t rdev; unsigned i; char *full_name_inc; 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; continue; } full_name_inc = xmalloc(strlen(full_name) + sizeof(int)*3 + 2); if (count) count--; for (i = start; i <= start + count; i++) { sprintf(full_name_inc, count ? "%s%u" : "%s", full_name, i); rdev = makedev(major, minor + (i - start) * increment); if (mknod(full_name_inc, mode, rdev) != 0 && errno != EEXIST ) { bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc); ret = EXIT_FAILURE; } else if (chown(full_name_inc, uid, gid) < 0) { bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc); ret = EXIT_FAILURE; } else if (chmod(full_name_inc, mode) < 0) { bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc); ret = EXIT_FAILURE; } } free(full_name_inc); } } if (ENABLE_FEATURE_CLEAN_UP) config_close(parser); return ret; }
extern int install_main(int argc, char **argv) { struct stat statbuf; mode_t mode; uid_t uid; gid_t gid; char *gid_str = "-1"; char *uid_str = "-1"; char *mode_str = "0755"; int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; int ret = EXIT_SUCCESS; int flags; int i; bb_applet_long_options = install_long_options; bb_opt_complementaly = "s~d:d~s"; /* -c exists for backwards compatability, its needed */ flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */ /* Check valid options were given */ if(flags & 0x80000000UL) { bb_show_usage(); } /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ if (flags & INSTALL_OPT_PRESERVE_TIME) { copy_flags |= FILEUTILS_PRESERVE_STATUS; } bb_parse_mode(mode_str, &mode); gid = get_ug_id(gid_str, my_getgrnam); uid = get_ug_id(uid_str, my_getpwnam); umask(0); /* Create directories * dont use bb_make_directory() as it cant change uid or gid * perhaps bb_make_directory() should be improved. */ if (flags & INSTALL_OPT_DIRECTORY) { for (argv += optind; *argv; argv++) { char *old_argv_ptr = *argv + 1; char *argv_ptr; do { argv_ptr = strchr(old_argv_ptr, '/'); old_argv_ptr = argv_ptr; if (argv_ptr) { *argv_ptr = '\0'; old_argv_ptr++; } if (mkdir(*argv, mode) == -1) { if (errno != EEXIST) { bb_perror_msg("coulnt create %s", *argv); ret = EXIT_FAILURE; break; } } else if (lchown(*argv, uid, gid) == -1) { bb_perror_msg("cannot change ownership of %s", *argv); ret = EXIT_FAILURE; break; } if (argv_ptr) { *argv_ptr = '/'; } } while (old_argv_ptr); } return(ret); } cp_mv_stat2(argv[argc - 1], &statbuf, lstat); for (i = optind; i < argc - 1; i++) { unsigned char *dest; if (S_ISDIR(statbuf.st_mode)) { dest = concat_path_file(argv[argc - 1], basename(argv[i])); } else { dest = argv[argc - 1]; } ret |= copy_file(argv[i], dest, copy_flags); /* Set the file mode */ if (chmod(dest, mode) == -1) { bb_perror_msg("cannot change permissions of %s", dest); ret = EXIT_FAILURE; } /* Set the user and group id */ if (lchown(dest, uid, gid) == -1) { bb_perror_msg("cannot change ownership of %s", dest); ret = EXIT_FAILURE; } if (flags & INSTALL_OPT_STRIP) { if (execlp("strip", "strip", dest, NULL) == -1) { bb_error_msg("strip failed"); ret = EXIT_FAILURE; } } } return(ret); }
int install_main(int argc, char **argv) { struct stat statbuf; mode_t mode; uid_t uid; gid_t gid; const char *gid_str; const char *uid_str; const char *mode_str; int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; int ret = EXIT_SUCCESS, flags, i, isdir; enum { OPT_CMD = 0x1, OPT_DIRECTORY = 0x2, OPT_PRESERVE_TIME = 0x4, OPT_STRIP = 0x8, OPT_GROUP = 0x10, OPT_MODE = 0x20, OPT_OWNER = 0x40, }; #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS applet_long_options = install_long_options; #endif opt_complementary = "?:s--d:d--s"; /* -c exists for backwards compatibility, its needed */ flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ if (flags & OPT_PRESERVE_TIME) { copy_flags |= FILEUTILS_PRESERVE_STATUS; } mode = 0666; if (flags & OPT_MODE) bb_parse_mode(mode_str, &mode); uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); if (flags & (OPT_OWNER|OPT_GROUP)) umask(0); /* Create directories * don't use bb_make_directory() as it can't change uid or gid * perhaps bb_make_directory() should be improved. */ if (flags & OPT_DIRECTORY) { for (argv += optind; *argv; argv++) { char *old_argv_ptr = *argv + 1; char *argv_ptr; do { argv_ptr = strchr(old_argv_ptr, '/'); old_argv_ptr = argv_ptr; if (argv_ptr) { *argv_ptr = '\0'; old_argv_ptr++; } if (mkdir(*argv, mode | 0111) == -1) { if (errno != EEXIST) { bb_perror_msg("cannot create %s", *argv); ret = EXIT_FAILURE; break; } } if ((flags & (OPT_OWNER|OPT_GROUP)) && lchown(*argv, uid, gid) == -1 ) { bb_perror_msg("cannot change ownership of %s", *argv); ret = EXIT_FAILURE; break; } if (argv_ptr) { *argv_ptr = '/'; } } while (old_argv_ptr); } return ret; } isdir = lstat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); for (i = optind; i < argc - 1; i++) { char *dest; dest = argv[argc - 1]; if (isdir) dest = concat_path_file(argv[argc - 1], basename(argv[i])); ret |= copy_file(argv[i], dest, copy_flags); /* Set the file mode */ if ((flags & OPT_MODE) && chmod(dest, mode) == -1) { bb_perror_msg("cannot change permissions of %s", dest); ret = EXIT_FAILURE; } /* Set the user and group id */ if ((flags & (OPT_OWNER|OPT_GROUP)) && lchown(dest, uid, gid) == -1 ) { bb_perror_msg("cannot change ownership of %s", dest); ret = EXIT_FAILURE; } if (flags & OPT_STRIP) { if (execlp("strip", "strip", dest, NULL) == -1) { bb_perror_msg("strip"); ret = EXIT_FAILURE; } } if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); } return ret; }
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; }