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]); }
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; }
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; }
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; }
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 */ }
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); }
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]); }
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); }
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 = ✓ switch (*action) { case 'x': case 'e': acts = "x"; break; case 'X': case 'E': acts = "x"; kll = 1; cbk = ✓ break; case 'D': acts = "d"; kll = 1; cbk = ✓ break; case 'T': acts = "tc"; kll = 1; cbk = ✓ break; case 'c': if (!str_diff(action, "check")) { act = 0; acts = "c"; cbk = ✓ 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 = ✓ break; } if (!str_diff(action, "start")) { acts = "u"; cbk = ✓ break; } if (!str_diff(action, "stop")) { acts = "d"; cbk = ✓ break; } act = &status; cbk = 0; break; case 'r': if (!str_diff(action, "restart")) { acts = "tcu"; cbk = ✓ break; } usage(); case 'f': if (!str_diff(action, "force-reload")) { acts = "tc"; kll = 1; cbk = ✓ break; } if (!str_diff(action, "force-restart")) { acts = "tcu"; kll = 1; cbk = ✓ break; } if (!str_diff(action, "force-shutdown")) { acts = "x"; kll = 1; cbk = ✓ break; } if (!str_diff(action, "force-stop")) { acts = "d"; kll = 1; cbk = ✓ 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; }