int chpst_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	INIT_G();

	if (applet_name[3] == 'd') envdir(argc, argv);
	if (applet_name[1] == 'o') softlimit(argc, argv);
	if (applet_name[0] == 's') setuidgid(argc, argv);
	if (applet_name[0] == 'e') envuidgid(argc, argv);
	// otherwise we are chpst

	{
		char *m,*d,*o,*p,*f,*c,*r,*t,*n;
		getopt32(argv, "+u:U:e:m:d:o:p:f:c:r:t:/:n:vP012",
				&set_user,&env_user,&env_dir,
				&m,&d,&o,&p,&f,&c,&r,&t,&root,&n);
		// if (option_mask32 & 0x1) // -u
		// if (option_mask32 & 0x2) // -U
		// if (option_mask32 & 0x4) // -e
		if (option_mask32 & 0x8) limits = limitl = limita = limitd = xatoul(m); // -m
		if (option_mask32 & 0x10) limitd = xatoul(d); // -d
		if (option_mask32 & 0x20) limito = xatoul(o); // -o
		if (option_mask32 & 0x40) limitp = xatoul(p); // -p
		if (option_mask32 & 0x80) limitf = xatoul(f); // -f
		if (option_mask32 & 0x100) limitc = xatoul(c); // -c
		if (option_mask32 & 0x200) limitr = xatoul(r); // -r
		if (option_mask32 & 0x400) limitt = xatoul(t); // -t
		// if (option_mask32 & 0x800) // -/
		if (option_mask32 & 0x1000) nicelvl = xatoi(n); // -n
		// The below consts should match #defines at top!
		//if (option_mask32 & 0x2000) OPT_verbose = 1; // -v
		//if (option_mask32 & 0x4000) OPT_pgrp = 1; // -P
		//if (option_mask32 & 0x8000) OPT_nostdin = 1; // -0
		//if (option_mask32 & 0x10000) OPT_nostdout = 1; // -1
		//if (option_mask32 & 0x20000) OPT_nostderr = 1; // -2
	}
	argv += optind;
	if (!argv || !*argv) bb_show_usage();

	if (OPT_pgrp) setsid();
	if (env_dir) edir(env_dir);
	if (root) {
		xchdir(root);
		xchroot(".");
	}
	slimit();
	if (nicelvl) {
		errno = 0;
		if (nice(nicelvl) == -1)
			bb_perror_msg_and_die("nice");
	}
	if (env_user) euidgid(env_user);
	if (set_user) suidgid(set_user);
	if (OPT_nostdin) close(0);
	if (OPT_nostdout) close(1);
	if (OPT_nostderr) close(2);
	BB_EXECVP(argv[0], argv);
	bb_perror_msg_and_die("exec %s", argv[0]);
}
Exemple #2
0
int chattr_main(int argc UNUSED_PARAM, char **argv)
{
	struct globals g;
	char *arg;

	memset(&g, 0, sizeof(g));

	/* parse the args */
	while ((arg = *++argv)) {
		/* take care of -R and -v <version> */
		if (arg[0] == '-'
		 && (arg[1] == 'R' || arg[1] == 'v')
		 && !arg[2]
		) {
			if (arg[1] == 'R') {
				g.recursive = 1;
				continue;
			}
			/* arg[1] == 'v' */
			if (!*++argv)
				bb_show_usage();
			g.version = xatoul(*argv);
			g.flags |= OPT_SET_VER;
			continue;
		}

		if (!decode_arg(arg, &g))
			break;
	}

	/* run sanity checks on all the arguments given us */
	if (!*argv)
		bb_show_usage();
	if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM)))
		bb_error_msg_and_die("= is incompatible with - and +");
	if (g.rf & g.af)
		bb_error_msg_and_die("can't set and unset a flag");
	if (!g.flags)
		bb_error_msg_and_die("must use '-v', =, - or +");

	/* now run chattr on all the files passed to us */
	do change_attributes(*argv, &g); while (*++argv);

	return EXIT_SUCCESS;
}
Exemple #3
0
int ping6_main(int argc, char **argv)
{
	char *opt_c, *opt_s, *opt_I;

	datalen = DEFDATALEN; /* initialized here rather than in global scope to work around gcc bug */

	/* exactly one argument needed, -v and -q don't mix */
	opt_complementary = "=1:q--v:v--q";
	getopt32(argc, argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
	if (option_mask32 & 4) pingcount = xatoul(opt_c); // -c
	if (option_mask32 & 8) datalen = xatou16(opt_s); // -s
	if (option_mask32 & 0x10) { // -I
		if_index = if_nametoindex(opt_I);
		if (!if_index)
			bb_error_msg_and_die(
				"%s: invalid interface name", opt_I);
	}

	myid = (int16_t)getpid();
	ping(argv[optind]);
	return EXIT_SUCCESS;
}
int split_main(int argc, char **argv)
{
	unsigned suffix_len = 2;
	char *pfx;
	char *count_p;
	const char *sfx;
	off_t cnt = 1000;
	off_t remaining = 0;
	unsigned opt;
	ssize_t bytes_read, to_write;
	char *src;

	opt_complementary = "?2";
	opt = getopt32(argv, "l:b:a:", &count_p, &count_p, &sfx);

	if (opt & SPLIT_OPT_l)
		cnt = xatoul(count_p);
	if (opt & SPLIT_OPT_b)
		cnt = xatoul_sfx(count_p, split_suffices);
	if (opt & SPLIT_OPT_a)
		suffix_len = xatou(sfx);
	sfx = "x";

	argv += optind;
	if (argv[0]) {
		if (argv[1])
			sfx = argv[1];
		xmove_fd(xopen(argv[0], O_RDONLY), 0);
	} else {
		argv[0] = (char *) bb_msg_standard_input;
	}

	if (NAME_MAX < strlen(sfx) + suffix_len)
		bb_error_msg_and_die("suffix too long");

	{
		char *char_p = xzalloc(suffix_len + 1);
		memset(char_p, 'a', suffix_len);
		pfx = xasprintf("%s%s", sfx, char_p);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(char_p);
	}

	while (1) {
		bytes_read = safe_read(0, read_buffer, READ_BUFFER_SIZE);
		if (!bytes_read)
			break;
		if (bytes_read < 0)
			bb_simple_perror_msg_and_die(argv[0]);
		src = read_buffer;
		do {
			if (!remaining) {
				if (!pfx)
					bb_error_msg_and_die("suffixes exhausted");
				xmove_fd(xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC), 1);
				pfx = next_file(pfx, suffix_len);
				remaining = cnt;
			}

			if (opt & SPLIT_OPT_b) {
				/* split by bytes */
				to_write = (bytes_read < remaining) ? bytes_read : remaining;
				remaining -= to_write;
			} else {
				/* split by lines */
				/* can be sped up by using _memrchr_
				 * and writing many lines at once... */
				char *end = memchr(src, '\n', bytes_read);
				if (end) {
					--remaining;
					to_write = end - src + 1;
				} else {
					to_write = bytes_read;
				}
			}

			xwrite(1, src, to_write);
			bytes_read -= to_write;
			src += to_write;
		} while (bytes_read);
	}
	return EXIT_SUCCESS;
}
Exemple #5
0
int ipcrm_main(int argc, char **argv)
{
	int c;
	int error = 0;

	/* if the command is executed without parameters, do nothing */
	if (argc == 1)
		return 0;
#if IPCRM_LEGACY
	/* check to see if the command is being invoked in the old way if so
	   then run the old code. Valid commands are msg, shm, sem. */
	{
		type_id what = 0; /* silence gcc */
		char w;

		w = argv[1][0];
		if ( ((w == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
		       || (argv[1][0] == 's'
		           && ((w = argv[1][1]) == 'h' || w == 'e')
		           && argv[1][2] == 'm')
		     ) && argv[1][3] == '\0'
		) {
			if (argc < 3)
				bb_show_usage();

			if (w == 'h')
				what = SHM;
			else if (w == 'm')
				what = MSG;
			else if (w == 'e')
				what = SEM;

			if (remove_ids(what, &argv[2]))
				fflush_stdout_and_exit(EXIT_FAILURE);
			printf("resource(s) deleted\n");
			return 0;
		}
	}
#endif /* IPCRM_LEGACY */

	/* process new syntax to conform with SYSV ipcrm */
	while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
		int result;
		int id = 0;
		int iskey = isupper(c);

		/* needed to delete semaphores */
		union semun arg;

		arg.val = 0;

		if ((c == '?') || (c == 'h')) {
			bb_show_usage();
		}

		/* we don't need case information any more */
		c = tolower(c);

		/* make sure the option is in range: allowed are q, m, s */
		if (c != 'q' && c != 'm' && c != 's') {
			bb_show_usage();
		}

		if (iskey) {
			/* keys are in hex or decimal */
			key_t key = xstrtoul(optarg, 0);

			if (key == IPC_PRIVATE) {
				error++;
				bb_error_msg("illegal key (%s)", optarg);
				continue;
			}

			/* convert key to id */
			id = ((c == 'q') ? msgget(key, 0) :
				  (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));

			if (id < 0) {
				const char *errmsg;

				error++;
				switch (errno) {
				case EACCES:
					errmsg = "permission denied for";
					break;
				case EIDRM:
					errmsg = "already removed";
					break;
				case ENOENT:
					errmsg = "invalid";
					break;
				default:
					errmsg = "unknown error in";
					break;
				}
				bb_error_msg("%s %s (%s)", errmsg, "key", optarg);
				continue;
			}
		} else {
			/* ids are in decimal */
			id = xatoul(optarg);
		}

		result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
				  (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
				  semctl(id, 0, IPC_RMID, arg));

		if (result) {
			const char *errmsg;
			const char *const what = iskey ? "key" : "id";

			error++;
			switch (errno) {
			case EACCES:
			case EPERM:
				errmsg = "permission denied for";
				break;
			case EINVAL:
				errmsg = "invalid";
				break;
			case EIDRM:
				errmsg = "already removed";
				break;
			default:
				errmsg = "unknown error in";
				break;
			}
			bb_error_msg("%s %s (%s)", errmsg, what, optarg);
			continue;
		}
	}

	/* print usage if we still have some arguments left over */
	if (optind != argc) {
		bb_show_usage();
	}

	/* exit value reflects the number of errors encountered */
	return error;
}
Exemple #6
0
int pidof_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned first = 1;
	unsigned opt;
#if ENABLE_FEATURE_PIDOF_OMIT
	llist_t *omits = NULL; /* list of pids to omit */
	opt_complementary = "o::";
#endif

	/* do unconditional option parsing */
	opt = getopt32(argv, ""
			IF_FEATURE_PIDOF_SINGLE ("s")
			IF_FEATURE_PIDOF_OMIT("o:", &omits));

#if ENABLE_FEATURE_PIDOF_OMIT
	/* fill omit list.  */
	{
		llist_t *omits_p = omits;
		while (1) {
			omits_p = llist_find_str(omits_p, "%PPID");
			if (!omits_p)
				break;
			/* are we asked to exclude the parent's process ID?  */
			omits_p->data = utoa((unsigned)getppid());
		}
	}
#endif
	/* Looks like everything is set to go.  */
	argv += optind;
	while (*argv) {
		pid_t *pidList;
		pid_t *pl;

		/* reverse the pidlist like GNU pidof does.  */
		pidList = pidlist_reverse(find_pid_by_name(*argv));
		for (pl = pidList; *pl; pl++) {
#if ENABLE_FEATURE_PIDOF_OMIT
			if (opt & OPT_OMIT) {
				llist_t *omits_p = omits;
				while (omits_p) {
					if (xatoul(omits_p->data) == (unsigned long)(*pl)) {
						goto omitting;
					}
					omits_p = omits_p->link;
				}
			}
#endif
			printf(" %u" + first, (unsigned)*pl);
			first = 0;
			if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE))
				break;
#if ENABLE_FEATURE_PIDOF_OMIT
 omitting: ;
#endif
		}
		free(pidList);
		argv++;
	}
	if (!first)
		bb_putchar('\n');

#if ENABLE_FEATURE_PIDOF_OMIT
	if (ENABLE_FEATURE_CLEAN_UP)
		llist_free(omits, NULL);
#endif
	return first; /* 1 (failure) - no processes found */
}
Exemple #7
0
int uniq_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
    FILE *in, *out;
    unsigned long dups, skip_fields, skip_chars, i;
    const char *s0, *e0, *s1, *e1, *input_filename;
    unsigned opt;

    enum {
        OPT_c = 0x1,
        OPT_d = 0x2,
        OPT_u = 0x4,
        OPT_f = 0x8,
        OPT_s = 0x10,
    };

    skip_fields = skip_chars = 0;

    opt = getopt32(argv, "cduf:s:", &s0, &s1);
    if (opt & OPT_f)
        skip_fields = xatoul(s0);
    if (opt & OPT_s)
        skip_chars = xatoul(s1);
    argv += optind;

    input_filename = *argv;

    in = xgetoptfile_uniq_s(argv, 0);
    if (*argv) {
        ++argv;
    }
    out = xgetoptfile_uniq_s(argv, 2);
    if (*argv && argv[1]) {
        bb_show_usage();
    }

    s1 = e1 = NULL;				/* prime the pump */

    do {
        s0 = s1;
        e0 = e1;
        dups = 0;

        /* gnu uniq ignores newlines */
        while ((s1 = xmalloc_getline(in)) != NULL) {
            e1 = s1;
            for (i = skip_fields; i; i--) {
                e1 = skip_whitespace(e1);
                e1 = skip_non_whitespace(e1);
            }
            for (i = skip_chars; *e1 && i; i--) {
                ++e1;
            }

            if (!s0 || strcmp(e0, e1)) {
                break;
            }

            ++dups;		 /* Note: Testing for overflow seems excessive. */
        }

        if (s0) {
            if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_e) */
                fprintf(out, "\0%d " + (opt & 1), dups + 1);
                fprintf(out, "%s\n", s0);
            }
            free((void *)s0);
        }
    } while (s1);

    die_if_ferror(in, input_filename);

    fflush_stdout_and_exit(EXIT_SUCCESS);
}
Exemple #8
0
static void softlimit(int argc, char **argv)
{
	char *a,*c,*d,*f,*l,*m,*o,*p,*r,*s,*t;
	getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:",
			&a,&c,&d,&f,&l,&m,&o,&p,&r,&s,&t);
	if (option_mask32 & 0x001) limita = xatoul(a); // -a
	if (option_mask32 & 0x002) limitc = xatoul(c); // -c
	if (option_mask32 & 0x004) limitd = xatoul(d); // -d
	if (option_mask32 & 0x008) limitf = xatoul(f); // -f
	if (option_mask32 & 0x010) limitl = xatoul(l); // -l
	if (option_mask32 & 0x020) limits = limitl = limita = limitd = xatoul(m); // -m
	if (option_mask32 & 0x040) limito = xatoul(o); // -o
	if (option_mask32 & 0x080) limitp = xatoul(p); // -p
	if (option_mask32 & 0x100) limitr = xatoul(r); // -r
	if (option_mask32 & 0x200) limits = xatoul(s); // -s
	if (option_mask32 & 0x400) limitt = xatoul(t); // -t
	argv += optind;
	if (!argv[0]) bb_show_usage();
	slimit();
	BB_EXECVP(argv[0], argv);
	bb_perror_msg_and_die("exec %s", argv[0]);
}
Exemple #9
0
int head_main(int argc, char **argv)
{
	unsigned long count = 10;
	unsigned long i;
#if ENABLE_FEATURE_FANCY_HEAD
	int count_bytes = 0;
	int header_threshhold = 1;
#endif

	FILE *fp;
	const char *fmt;
	char *p;
	int opt;
	int c;
	int retval = EXIT_SUCCESS;

#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
	/* Allow legacy syntax of an initial numeric option without -n. */
	if (argc > 1 && argv[1][0] == '-'
	 && isdigit(argv[1][1])
	) {
		--argc;
		++argv;
		p = (*argv) + 1;
		goto GET_COUNT;
	}
#endif

	/* No size benefit in converting this to getopt32 */
	while ((opt = getopt(argc, argv, head_opts)) > 0) {
		switch (opt) {
#if ENABLE_FEATURE_FANCY_HEAD
		case 'q':
			header_threshhold = INT_MAX;
			break;
		case 'v':
			header_threshhold = -1;
			break;
		case 'c':
			count_bytes = 1;
			/* fall through */
#endif
		case 'n':
			p = optarg;
#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
 GET_COUNT:
#endif

#if !ENABLE_FEATURE_FANCY_HEAD
			count = xatoul(p);
#else
			count = xatoul_sfx(p, head_suffixes);
#endif
			break;
		default:
			bb_show_usage();
		}
	}

	argv += optind;
	if (!*argv) {
		*--argv = "-";
	}

	fmt = header_fmt_str + 1;
#if ENABLE_FEATURE_FANCY_HEAD
	if (argc - optind <= header_threshhold) {
		header_threshhold = 0;
	}
#else
	if (argc <= optind + 1) {
		fmt += 11;
	}
	/* Now define some things here to avoid #ifdefs in the code below.
	 * These should optimize out of the if conditions below. */
#define header_threshhold   1
#define count_bytes         0
#endif

	do {
		fp = fopen_or_warn_stdin(*argv);
		if (fp) {
			if (fp == stdin) {
				*argv = (char *) bb_msg_standard_input;
			}
			if (header_threshhold) {
				printf(fmt, *argv);
			}
			i = count;
			while (i && ((c = getc(fp)) != EOF)) {
				if (count_bytes || (c == '\n')) {
					--i;
				}
				putchar(c);
			}
			if (fclose_if_not_stdin(fp)) {
				bb_perror_msg("%s", *argv);	/* Avoid multibyte problems. */
				retval = EXIT_FAILURE;
			}
			die_if_ferror_stdout();
		}
		fmt = header_fmt_str;
	} while (*++argv);

	fflush_stdout_and_exit(retval);
}
Exemple #10
0
int sv_main(int argc, char **argv)
{
	unsigned opt;
	unsigned i, want_exit;
	char *x;

	for (i = strlen(*argv); i; --i)
		if ((*argv)[i-1] == '/')
			break;
	*argv += i;
	service = argv;
	services = 1;
	if ((x = getenv("SVDIR"))) varservice = x;
	if ((x = getenv("SVWAIT"))) waitsec = xatoul(x);
	/* TODO: V can be handled internally by getopt_ulflags */
	opt = getopt32(argc, argv, "w:vV", &x);
	if (opt & 1) waitsec = xatoul(x);
	if (opt & 2) verbose = 1;
	if (opt & 4) usage();
	if (!(action = *argv++)) usage();
	--argc;
	service = argv; services = argc;
	if (!*service) usage();

	taia_now(&tnow); tstart = tnow;
	if ((curdir = open_read(".")) == -1)
		fatal_cannot("open current directory");

	act = &control; acts = "s";
	if (verbose) cbk = &check;
	switch (*action) {
	case 'x': case 'e':
		acts = "x"; break;
	case 'X': case 'E':
		acts = "x"; kll = 1; cbk = &check; break;
	case 'D':
		acts = "d"; kll = 1; cbk = &check; break;
	case 'T':
		acts = "tc"; kll = 1; cbk = &check; break;
	case 'c':
		if (!str_diff(action, "check")) {
			act = 0;
			acts = "c";
			cbk = &check;
			break;
		}
	case 'u': case 'd': case 'o': case 't': case 'p': case 'h':
	case 'a': case 'i': case 'k': case 'q': case '1': case '2':
		action[1] = 0; acts = action; break;
	case 's':
		if (!str_diff(action, "shutdown")) {
			acts = "x";
			cbk = &check;
			break;
		}
		if (!str_diff(action, "start")) {
			acts = "u";
			cbk = &check;
			break;
		}
		if (!str_diff(action, "stop")) {
			acts = "d";
			cbk = &check;
			break;
		}
		act = &status; cbk = 0; break;
	case 'r':
		if (!str_diff(action, "restart")) {
			acts = "tcu";
			cbk = &check;
			break;
		}
		usage();
	case 'f':
		if (!str_diff(action, "force-reload"))
			{ acts = "tc"; kll = 1; cbk = &check; break; }
		if (!str_diff(action, "force-restart"))
			{ acts = "tcu"; kll = 1; cbk = &check; break; }
		if (!str_diff(action, "force-shutdown"))
			{ acts = "x"; kll = 1; cbk = &check; break; }
		if (!str_diff(action, "force-stop"))
			{ acts = "d"; kll = 1; cbk = &check; break; }
	default:
		usage();
	}

	servicex = service;
	for (i = 0; i < services; ++i) {
		if ((**service != '/') && (**service != '.')) {
			if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
				fail("cannot change to service directory");
				*service = 0;
			}
		} else if (chdir(*service) == -1) {
			fail("cannot change to service directory");
			*service = 0;
		}
		if (*service) if (act && (act(acts) == -1)) *service = 0;
		if (fchdir(curdir) == -1) fatal_cannot("change to original directory");
		service++;
	}

	if (*cbk)
		for (;;) {
			taia_sub(&tdiff, &tnow, &tstart);
			service = servicex; want_exit = 1;
			for (i = 0; i < services; ++i, ++service) {
				if (!*service) continue;
				if ((**service != '/') && (**service != '.')) {
					if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
						fail("cannot change to service directory");
						*service = 0;
					}
				} else if (chdir(*service) == -1) {
					fail("cannot change to service directory");
					*service = 0;
				}
				if (*service) { if (cbk(acts) != 0) *service = 0; else want_exit = 0; }
				if (*service && taia_approx(&tdiff) > waitsec) {
					kll ? printf(KILL) : printf(TIMEOUT);
					if (svstatus_get() > 0) { svstatus_print(*service); ++rc; }
					puts(""); /* will also flush the output */
					if (kll) control("k");
					*service = 0;
				}
				if (fchdir(curdir) == -1)
					fatal_cannot("change to original directory");
			}
			if (want_exit) break;
			usleep(420000);
			taia_now(&tnow);
		}
	return rc > 99 ? 99 : rc;
}