int tune2fs_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opts;
	const char *label, *str_c, *str_i, *str_C;
	struct ext2_super_block *sb;
	int fd;

	opt_complementary = "=1";
	opts = getopt32(argv, "L:c:i:C:", &label, &str_c, &str_i, &str_C);
	if (!opts)
		bb_show_usage();
	argv += optind; // argv[0] -- device

	// read superblock
	fd = xopen(argv[0], O_RDWR);
	xlseek(fd, 1024, SEEK_SET);
	sb = xzalloc(1024);
	xread(fd, sb, 1024);

	// mangle superblock
	//STORE_LE(sb->s_wtime, time(NULL)); - why bother?

	if (opts & OPT_C) {
		int n = xatoi_range(str_C, 1, 0xfffe);
		if (n == 0) n = 1;
		STORE_LE(sb->s_mnt_count, (unsigned)n);
	}

	// set the label
	if (opts & OPT_L)
		safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name));

	if (opts & OPT_c) {
		int n = xatoi_range(str_c, -1, 0xfffe);
		if (n == 0)
			n = -1;
		STORE_LE(sb->s_max_mnt_count, (unsigned)n);
	}

	if (opts & OPT_i) {
		unsigned n = xatou_range(str_i, 0, (unsigned)0xffffffff / (24*60*60)) * 24*60*60;
		STORE_LE(sb->s_checkinterval, n);
	}

	// write superblock
	xlseek(fd, 1024, SEEK_SET);
	xwrite(fd, sb, 1024);

	if (ENABLE_FEATURE_CLEAN_UP) {
		free(sb);
	}

	xclose(fd);
	return EXIT_SUCCESS;
}
示例#2
0
int nice_main(int argc, char **argv)
{
	int old_priority, adjustment;

	old_priority = getpriority(PRIO_PROCESS, 0);

	if (!*++argv) {	/* No args, so (GNU) output current nice value. */
		printf("%d\n", old_priority);
		fflush_stdout_and_exit(EXIT_SUCCESS);
	}

	adjustment = 10;			/* Set default adjustment. */

	if (argv[0][0] == '-') {
		if (argv[0][1] == 'n') { /* -n */
			if (argv[0][2]) { /* -nNNNN (w/o space) */
				argv[0] += 2; argv--; argc++;
			}
		} else { /* -NNN (NNN may be negative) == -n NNN */
			argv[0] += 1; argv--; argc++;
		}
		if (argc < 4) {			/* Missing priority and/or utility! */
			bb_show_usage();
		}
		adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
		argv += 2;
	}

	{  /* Set our priority. */
		int prio = old_priority + adjustment;

		if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
			bb_perror_msg_and_die("setpriority(%d)", prio);
		}
	}

	execvp(*argv, argv);		/* Now exec the desired program. */

	/* The exec failed... */
	xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
	bb_perror_msg_and_die("%s", *argv);
}
示例#3
0
int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opt;
	char *signame;
	char *startas;
	char *chuid;
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
//	char *retry_arg = NULL;
//	int retries = -1;
	char *opt_N;
#endif

	INIT_G();

	opt = GETOPT32(argv, "^"
		"KSbqtma:n:s:u:c:x:p:"
		IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
			/* -K or -S is required; they are mutually exclusive */
			/* -p is required if -m is given */
			/* -xpun (at least one) is required if -K is given */
			/* -xa (at least one) is required if -S is given */
			/* -q turns off -v */
			"\0"
			"K:S:K--S:S--K:m?p:K?xpun:S?xa"
			IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"),
		LONGOPTS
		&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile
		IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
		/* We accept and ignore -R <param> / --retry <param> */
		IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL)
	);

	if (opt & OPT_s) {
		signal_nr = get_signum(signame);
		if (signal_nr < 0) bb_show_usage();
	}

	if (!(opt & OPT_a))
		startas = execname;
	if (!execname) /* in case -a is given and -x is not */
		execname = startas;
	if (execname) {
		G.execname_sizeof = strlen(execname) + 1;
		G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1);
	}

//	IF_FEATURE_START_STOP_DAEMON_FANCY(
//		if (retry_arg)
//			retries = xatoi_positive(retry_arg);
//	)
	//argc -= optind;
	argv += optind;

	if (userspec) {
		user_id = bb_strtou(userspec, NULL, 10);
		if (errno)
			user_id = xuname2uid(userspec);
	}
	/* Both start and stop need to know current processes */
	do_procinit();

	if (opt & CTX_STOP) {
		int i = do_stop();
		return (opt & OPT_OKNODO) ? 0 : (i <= 0);
	}

	if (G.found_procs) {
		if (!QUIET)
			printf("%s is already running\n%u\n", execname, (unsigned)G.found_procs->pid);
		return !(opt & OPT_OKNODO);
	}

#ifdef OLDER_VERSION_OF_X
	if (execname)
		xstat(execname, &G.execstat);
#endif

	*--argv = startas;
	if (opt & OPT_BACKGROUND) {
#if BB_MMU
		bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_DOUBLE_FORK);
		/* DAEMON_DEVNULL_STDIO is superfluous -
		 * it's always done by bb_daemonize() */
#else
		/* Daemons usually call bb_daemonize_or_rexec(), but SSD can do
		 * without: SSD is not itself a daemon, it _execs_ a daemon.
		 * The usual NOMMU problem of "child can't run indefinitely,
		 * it must exec" does not bite us: we exec anyway.
		 */
		pid_t pid = xvfork();
		if (pid != 0) {
			/* parent */
			/* why _exit? the child may have changed the stack,
			 * so "return 0" may do bad things */
			_exit(EXIT_SUCCESS);
		}
		/* Child */
		setsid(); /* detach from controlling tty */
		/* Redirect stdio to /dev/null, close extra FDs */
		bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS);
#endif
	}
	if (opt & OPT_MAKEPID) {
		/* User wants _us_ to make the pidfile */
		write_pidfile(pidfile);
	}
	if (opt & OPT_c) {
		struct bb_uidgid_t ugid;
		parse_chown_usergroup_or_die(&ugid, chuid);
		if (ugid.uid != (uid_t) -1L) {
			struct passwd *pw = xgetpwuid(ugid.uid);
			if (ugid.gid != (gid_t) -1L)
				pw->pw_gid = ugid.gid;
			/* initgroups, setgid, setuid: */
			change_identity(pw);
		} else if (ugid.gid != (gid_t) -1L) {
			xsetgid(ugid.gid);
			setgroups(1, &ugid.gid);
		}
	}
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
	if (opt & OPT_NICELEVEL) {
		/* Set process priority */
		int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
		if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
			bb_perror_msg_and_die("setpriority(%d)", prio);
		}
	}
#endif
	execvp(startas, argv);
	bb_perror_msg_and_die("can't execute '%s'", startas);
}
示例#4
0
int renice_main(int argc, char **argv)
{
	static const char Xetpriority_msg[] ALIGN1 = "%cetpriority";

	int retval = EXIT_SUCCESS;
	int which = PRIO_PROCESS;	/* Default 'which' value. */
	int use_relative = 0;
	int adjustment, new_priority;
	unsigned who;
	char *arg;

	/* Yes, they are not #defines in glibc 2.4! #if won't work */
	if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX)
		BUG_bad_PRIO_PROCESS();
	if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX)
		BUG_bad_PRIO_PGRP();
	if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX)
		BUG_bad_PRIO_USER();

	arg = *++argv;

	/* Check if we are using a relative adjustment. */
	if (arg && arg[0] == '-' && arg[1] == 'n') {
		use_relative = 1;
		if (!arg[2])
			arg = *++argv;
		else
			arg += 2;
	}

	if (!arg) {				/* No args?  Then show usage. */
		bb_show_usage();
	}

	/* Get the priority adjustment (absolute or relative). */
	adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2);

	while ((arg = *++argv) != NULL) {
		/* Check for a mode switch. */
		if (arg[0] == '-' && arg[1]) {
			static const char opts[] ALIGN1 = {
				'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER
			};
			const char *p = strchr(opts, arg[1]);
			if (p) {
				which = p[4];
				if (!arg[2])
					continue;
				arg += 2;
			}
		}

		/* Process an ID arg. */
		if (which == PRIO_USER) {
			struct passwd *p;
			p = getpwnam(arg);
			if (!p) {
				bb_error_msg("unknown user: %s", arg);
				goto HAD_ERROR;
			}
			who = p->pw_uid;
		} else {
			who = bb_strtou(arg, NULL, 10);
			if (errno) {
				bb_error_msg("bad value: %s", arg);
				goto HAD_ERROR;
			}
		}

		/* Get priority to use, and set it. */
		if (use_relative) {
			int old_priority;

			errno = 0;	 /* Needed for getpriority error detection. */
			old_priority = getpriority(which, who);
			if (errno) {
				bb_perror_msg(Xetpriority_msg, 'g');
				goto HAD_ERROR;
			}

			new_priority = old_priority + adjustment;
		} else {
			new_priority = adjustment;
		}

		if (setpriority(which, who, new_priority) == 0) {
			continue;
		}

		bb_perror_msg(Xetpriority_msg, 's');
 HAD_ERROR:
		retval = EXIT_FAILURE;
	}

	/* No need to check for errors outputing to stderr since, if it
	 * was used, the HAD_ERROR label was reached and retval was set. */

	return retval;
}