Пример #1
0
/* 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);
	}
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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;
}