int watchdog_main(int argc, char **argv) { char *t_arg; unsigned long flags; flags = bb_getopt_ulflags(argc, argv, "t:", &t_arg); if (flags & 1) timer_duration = bb_xgetlarg(t_arg, 10, 0, INT_MAX); /* We're only interested in the watchdog device .. */ if (optind < argc - 1 || argc == 1) bb_show_usage(); if (daemon(0, 1) < 0) bb_perror_msg_and_die("Failed forking watchdog daemon"); signal(SIGHUP, watchdog_shutdown); signal(SIGINT, watchdog_shutdown); fd = bb_xopen(argv[argc - 1], O_WRONLY); while (1) { /* * Make sure we clear the counter before sleeping, as the counter value * is undefined at this point -- PFM */ write(fd, "\0", 1); sleep(timer_duration); } watchdog_shutdown(0); return EXIT_SUCCESS; }
/* * addgroup will take a login_name as its first parameter. * * gid * * can be customized via command-line parameters. * ________________________________________________________________________ */ int addgroup_main(int argc, char **argv) { char *group; char *user; gid_t gid = 0; /* get remaining args */ if(bb_getopt_ulflags(argc, argv, "g:", &group)) { gid = bb_xgetlarg(group, 10, 0, LONG_MAX); } if (optind < argc) { group = argv[optind]; optind++; } else { bb_show_usage(); } if (optind < argc) { user = argv[optind]; } else { user = ""; } if_i_am_not_root(); /* werk */ return addgroup(bb_path_group_file, group, gid, user); }
int start_stop_daemon_main(int argc, char **argv) { unsigned long opt; char *signame = NULL; char *startas = NULL; bb_applet_long_options = ssd_long_options; bb_opt_complementaly = "K~S:S~K"; opt = bb_getopt_ulflags(argc, argv, "KSba:n:s:u:x:", &startas, &cmdname, &signame, &userspec, &execname); /* Check one and only one context option was given */ if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) { bb_show_usage(); } if (signame) { signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); } if (!execname && !userspec) bb_error_msg_and_die ("need at least one of -x or -u"); if (!startas) startas = execname; if ((opt & SSD_CTX_START) && !startas) bb_error_msg_and_die ("-S needs -x or -a"); argc -= optind; argv += optind; if (userspec && sscanf(userspec, "%d", &user_id) != 1) user_id = my_getpwnam(userspec); do_procfs(); if (opt & SSD_CTX_STOP) { do_stop(); return EXIT_SUCCESS; } if (found) { printf("%s already running.\n%d\n", execname ,found->pid); return EXIT_SUCCESS; } *--argv = startas; if (opt & SSD_OPT_BACKGROUND) { if (daemon(0, 0) == -1) bb_perror_msg_and_die ("unable to fork"); } setsid(); execv(startas, argv); bb_perror_msg_and_die ("unable to start %s", startas); }
int start_stop_daemon_main(int argc, char **argv) { int flags; char *signame = NULL; bb_applet_long_options = ssd_long_options; flags = bb_getopt_ulflags(argc, argv, "KSba:n:s:u:x:", &startas, &cmdname, &signame, &userspec, &execname); /* Be sneaky and avoid branching */ stop = (flags & 1); start = (flags & 2); fork_before_exec = (flags & 4); if (signame) { signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); } if (start == stop) bb_error_msg_and_die ("need exactly one of -S or -K"); if (!execname && !userspec) bb_error_msg_and_die ("need at least one of -x or -u"); if (!startas) startas = execname; if (start && !startas) bb_error_msg_and_die ("-S needs -x or -a"); argc -= optind; argv += optind; if (userspec && sscanf(userspec, "%d", &user_id) != 1) user_id = my_getpwnam(userspec); do_procfs(); if (stop) { do_stop(); return EXIT_SUCCESS; } if (found) { printf("%s already running.\n%d\n", execname ,found->pid); return EXIT_SUCCESS; } *--argv = startas; if (fork_before_exec) { if (daemon(0, 0) == -1) bb_perror_msg_and_die ("unable to fork"); } setsid(); execv(startas, argv); bb_perror_msg_and_die ("unable to start %s", startas); }
int chvt_main(int argc, char **argv) { int fd, num; if (argc != 2) { bb_show_usage(); } fd = get_console_fd(); num = bb_xgetlarg(argv[1], 10, 0, INT_MAX); if ((-1 == ioctl(fd, VT_ACTIVATE, num)) || (-1 == ioctl(fd, VT_WAITACTIVE, num))) { bb_perror_msg_and_die("ioctl"); } return EXIT_SUCCESS; }
/* Process options */ int run_parts_main(int argc, char **argv) { char **args = xmalloc(2 * sizeof(char *)); unsigned char test_mode = 0; unsigned short argcount = 1; int opt; umask(022); while ((opt = getopt_long (argc, argv, "tu:a:", runparts_long_options, NULL)) > 0) { switch (opt) { /* Enable test mode */ case 't': test_mode++; break; /* Set the umask of the programs executed */ case 'u': /* Check and set the umask of the program executed. As stated in the original * run-parts, the octal conversion in libc is not foolproof; it will take the * 8 and 9 digits under some circumstances. We'll just have to live with it. */ umask(bb_xgetlarg(optarg, 8, 0, 07777)); break; /* Pass an argument to the programs */ case 'a': /* Add an argument to the commands that we will call. * Called once for every argument. */ args = xrealloc(args, (argcount + 2) * (sizeof(char *))); args[argcount++] = optarg; break; default: bb_show_usage(); } } /* We require exactly one argument: the directory name */ if (optind != (argc - 1)) { bb_show_usage(); } args[0] = argv[optind]; args[argcount] = 0; return(run_parts(args, test_mode, environ)); }
int openvt_main(int argc, char **argv) { int fd; char vtname[sizeof VC_FORMAT + 2]; if (argc < 3) bb_show_usage(); /* check for Illegal vt number: < 1 or > 12 */ sprintf(vtname, VC_FORMAT,(int)bb_xgetlarg(argv[1], 10, 1, 12)); argv+=2; argc-=2; if(fork() == 0) { /* leave current vt */ #ifdef ESIX_5_3_2_D if (setpgrp() < 0) { #else if (setsid() < 0) { #endif bb_perror_msg_and_die("Unable to set new session"); } close(0); /* so that new vt becomes stdin */ /* and grab new one */ fd = bb_xopen(vtname, O_RDWR); /* Reassign stdout and sterr */ close(1); close(2); dup(fd); dup(fd); execvp(argv[0], argv); _exit(1); } return EXIT_SUCCESS; }
int nice_main(int argc, char **argv) { static const char Xetpriority_msg[] = "cannot %cet priority"; int old_priority, adjustment; errno = 0; /* Needed for getpriority error detection. */ old_priority = getpriority(PRIO_PROCESS, 0); if (errno) { bb_perror_msg_and_die(Xetpriority_msg, 'g'); } if (!*++argv) { /* No args, so (GNU) output current nice value. */ bb_printf("%d\n", old_priority); bb_fflush_stdout_and_exit(EXIT_SUCCESS); } adjustment = 10; /* Set default adjustment. */ if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */ if (argc < 4) { /* Missing priority and/or utility! */ bb_show_usage(); } adjustment = bb_xgetlarg(argv[1], 10, INT_MIN, INT_MAX); argv += 2; } { /* Set our priority. Handle integer wrapping for old + adjust. */ int new_priority = int_add_no_wrap(old_priority, adjustment); if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) { bb_perror_msg_and_die(Xetpriority_msg, 's'); } } execvp(*argv, argv); /* Now exec the desired program. */ /* The exec failed... */ bb_default_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */ bb_perror_msg_and_die("%s", *argv); }
extern int watchdog_main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "t:")) > 0) { switch (opt) { case 't': timer_duration = bb_xgetlarg(optarg, 10, 0, INT_MAX); break; default: bb_show_usage(); } } /* We're only interested in the watchdog device .. */ if (optind < argc - 1 || argc == 1) bb_show_usage(); if (daemon(0, 1) < 0) bb_perror_msg_and_die("Failed forking watchdog daemon"); signal(SIGHUP, watchdog_shutdown); signal(SIGINT, watchdog_shutdown); signal(SIGTERM, watchdog_safe_terminate); fd = bb_xopen(argv[argc - 1], O_WRONLY); while (1) { /* * Make sure we clear the counter before sleeping, as the counter value * is undefined at this point -- PFM */ write(fd, "\0", 1); sleep(timer_duration); } watchdog_shutdown(0); return EXIT_SUCCESS; }
int deallocvt_main(int argc, char *argv[]) { /* num = 0 deallocate all unused consoles */ int num = 0; switch(argc) { case 2: if((num = bb_xgetlarg(argv[1], 10, 0, INT_MAX)) == 0) bb_error_msg_and_die("0: illegal VT number"); /* Fallthrough */ case 1: break; default: bb_show_usage(); } if (-1 == ioctl( get_console_fd(), VT_DISALLOCATE, num )) { bb_perror_msg_and_die("VT_DISALLOCATE"); } return EXIT_SUCCESS; }
/* * addgroup will take a login_name as its first parameter. * * gid * * can be customized via command-line parameters. * ________________________________________________________________________ */ int addgroup_main(int argc, char **argv) { char *group; gid_t gid = 0; /* check for min, max and missing args and exit on error */ bb_opt_complementally = "-1:?2:?"; if (bb_getopt_ulflags(argc, argv, "g:", &group)) { gid = bb_xgetlarg(group, 10, 0, LONG_MAX); } /* move past the commandline options */ argv += optind; /* need to be root */ if(geteuid()) { bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); } /* werk */ return addgroup(argv[0], gid, (argv[1]) ? argv[1] : ""); }
int start_stop_daemon_main(int argc, char **argv) { unsigned long opt; char *signame = NULL; char *startas = NULL; bb_applet_long_options = ssd_long_options; /* Check required one context option was given */ bb_opt_complementally = "K:S:?:K--S:S--K"; opt = bb_getopt_ulflags(argc, argv, "KSbqma:n:s:u:x:p:", &startas, &cmdname, &signame, &userspec, &execname, &pidfile); quiet = opt & SSD_OPT_QUIET; if (signame) { signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); } if (!execname && !pidfile && !userspec && !cmdname) bb_error_msg_and_die ("need at least one of -x, -p, -u, or -n"); if (!startas) startas = execname; if ((opt & SSD_CTX_START) && !startas) bb_error_msg_and_die ("-S needs -x or -a"); if ((opt & SSD_OPT_MAKEPID) && pidfile == NULL) bb_error_msg_and_die ("-m needs -p"); argc -= optind; argv += optind; if (userspec && sscanf(userspec, "%d", &user_id) != 1) user_id = bb_xgetpwnam(userspec); if (opt & SSD_CTX_STOP) { do_stop(); return EXIT_SUCCESS; } do_procinit(); if (found) { if (!quiet) printf("%s already running.\n%d\n", execname ,found->pid); return EXIT_SUCCESS; } *--argv = startas; if (opt & SSD_OPT_BACKGROUND) { if (daemon(0, 0) == -1) bb_perror_msg_and_die ("unable to fork"); setsid(); } if (opt & SSD_OPT_MAKEPID) { /* user wants _us_ to make the pidfile */ FILE *pidf = fopen(pidfile, "w"); pid_t pidt = getpid(); if (pidf == NULL) bb_perror_msg_and_die("Unable to write pidfile '%s'", pidfile); fprintf(pidf, "%d\n", pidt); fclose(pidf); } execv(startas, argv); bb_perror_msg_and_die ("unable to start %s", startas); }
int mkswap_main(int argc, char **argv) { char *tmp; struct stat statbuf; int sz; int maxpages; int goodpages; #ifdef __sparc__ int force = 0; #endif init_signature_page(); /* get pagesize */ bb_opt_complementally = "?"; /* call bb_show_usage internally */ sz = bb_getopt_ulflags(argc, argv, "+cfv:", &tmp); if (sz & 1) check = 1; #ifdef __sparc__ if (sz & 2) force = 1; #endif #if ENABLE_FEATURE_MKSWAP_V0 if (sz & 4) { version = bb_xgetlarg(tmp, 10, 0, 1); } else { if (get_linux_version_code() < KERNEL_VERSION(2, 1, 117)) version = 0; else version = 1; } #endif argv += optind; argc -= optind; goodpages = pagesize / 1024; /* cache division */ while (argc--) { if (device_name) { PAGES = bb_xgetlarg(argv[0], 0, 10, sz * goodpages) / goodpages; argc = 0; /* ignore any surplus args.. */ } else { device_name = argv[0]; sz = get_size(device_name); argv++; } } if (!device_name) { bb_error_msg_and_die("error: Nowhere to set up swap on?"); } if (!PAGES) { PAGES = sz; } #if 0 maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES); #else if (!version) maxpages = V0_MAX_PAGES; else if (get_linux_version_code() >= KERNEL_VERSION(2,2,1)) maxpages = V1_MAX_PAGES; else { maxpages = V1_OLD_MAX_PAGES; if (maxpages > V1_MAX_PAGES) maxpages = V1_MAX_PAGES; } #endif if (PAGES > maxpages) { PAGES = maxpages; bb_error_msg("warning: truncating swap area to %ldkB", PAGES * goodpages); } DEV = bb_xopen3(device_name, O_RDWR, 0); if (fstat(DEV, &statbuf) < 0) bb_perror_msg_and_die("%s", device_name); if (!S_ISBLK(statbuf.st_mode)) check = 0; else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340) bb_error_msg_and_die("Will not try to make swapdevice on '%s'", device_name); #ifdef __sparc__ if (!force && version == 0) { /* Don't overwrite partition table unless forced */ unsigned char *buffer = (unsigned char *) signature_page; unsigned short *q, sum; if (read(DEV, buffer, 512) != 512) bb_error_msg_and_die("fatal: first page unreadable"); if (buffer[508] == 0xDA && buffer[509] == 0xBE) { q = (unsigned short *) (buffer + 510); for (sum = 0; q >= (unsigned short *) buffer;) sum ^= *q--; if (!sum) { bb_error_msg("Device '%s' contains a valid Sun disklabel.\n" "This probably means creating v0 swap would destroy your partition table\n" "No swap created. If you really want to create swap v0 on that device, use\n" "the -f option to force it.", device_name); return EXIT_FAILURE; } } } #endif if (version == 0 || check) check_blocks(); if (version == 0 && !bit_test_and_clear(signature_page, 0)) bb_error_msg_and_die("fatal: first page unreadable"); if (version == 1) { p->swap_version = version; p->last_page = PAGES - 1; p->nr_badpages = badpages; } goodpages = PAGES - badpages - 1; if (goodpages <= 0) bb_error_msg_and_die("Unable to set up swap-space: unreadable"); printf("Setting up swapspace version %d, size = %ld bytes\n", version, (long) (goodpages * pagesize)); write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2"); sz = ((version == 0) ? 0 : 1024); /* offset */ if (lseek(DEV, sz, SEEK_SET) != sz) bb_error_msg_and_die("unable to rewind swap-device"); goodpages = pagesize - sz; /* cache substraction */ if (write(DEV, (char *) signature_page + sz, goodpages) != goodpages) bb_error_msg_and_die("unable to write signature page"); /* * A subsequent swapon() will fail if the signature * is not actually on disk. (This is a kernel bug.) */ if (fsync(DEV)) bb_error_msg_and_die("fsync failed"); if (ENABLE_FEATURE_CLEAN_UP) { close(DEV); free(signature_page); } return EXIT_SUCCESS; }
extern int fold_main(int argc, char **argv) { /* If nonzero, try to break on whitespace. */ int break_spaces; /* If nonzero, at least one of the files we read was standard input. */ int have_read_stdin; int width = 80; int i; int optc; int errs = 0; break_spaces = count_bytes = have_read_stdin = 0; /* Turn any numeric options into -w options. */ for (i = 1; i < argc; i++) { char const *a = argv[i]; if (a[0] == '-') { if (a[1] == '-' && !a[2]) break; if (isdigit(a[1])) { char *s = xmalloc(strlen(a) + 2); s[0] = '-'; s[1] = 'w'; strcpy(s + 2, a + 1); argv[i] = s; } } } while ((optc = getopt(argc, argv, "bsw:")) > 0) { switch (optc) { case 'b': /* Count bytes rather than columns. */ count_bytes = 1; break; case 's': /* Break at word boundaries. */ break_spaces = 1; break; case 'w': { /* Line width. */ width = bb_xgetlarg(optarg, 10, 1, 10000); break; } default: bb_show_usage(); } } argv += optind; if (!*argv) { *--argv = "-"; } do { FILE *istream = bb_wfopen_input(*argv); if (istream != NULL) { int c; int column = 0; /* Screen column where next char will go. */ int offset_out = 0; /* Index in `line_out' for next char. */ static char *line_out = NULL; static int allocated_out = 0; while ((c = getc(istream)) != EOF) { if (offset_out + 1 >= allocated_out) { allocated_out += 1024; line_out = xrealloc(line_out, allocated_out); } if (c == '\n') { line_out[offset_out++] = c; fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); column = offset_out = 0; continue; } rescan: column = adjust_column(column, c); if (column > width) { /* This character would make the line too long. Print the line plus a newline, and make this character start the next line. */ if (break_spaces) { /* Look for the last blank. */ int logical_end; for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) { if (isblank(line_out[logical_end])) { break; } } if (logical_end >= 0) { /* Found a blank. Don't output the part after it. */ logical_end++; fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); putchar('\n'); /* Move the remainder to the beginning of the next line. The areas being copied here might overlap. */ memmove(line_out, line_out + logical_end, offset_out - logical_end); offset_out -= logical_end; for (column = i = 0; i < offset_out; i++) { column = adjust_column(column, line_out[i]); } goto rescan; } } else { if (offset_out == 0) { line_out[offset_out++] = c; continue; } } line_out[offset_out++] = '\n'; fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); column = offset_out = 0; goto rescan; } line_out[offset_out++] = c; } if (offset_out) { fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); } if (ferror(istream) || bb_fclose_nonstdin(istream)) { bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ errs |= EXIT_FAILURE; } } else { errs |= EXIT_FAILURE; } } while (*++argv); bb_fflush_stdout_and_exit(errs); }
int renice_main(int argc, char **argv) { static const char Xetpriority_msg[] = "%d : %cetpriority"; int retval = EXIT_SUCCESS; int which = PRIO_PROCESS; /* Default 'which' value. */ int use_relative = 0; int adjustment, new_priority; id_t who; ++argv; /* Check if we are using a relative adjustment. */ if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { use_relative = 1; ++argv; } if (!*argv) { /* No args? Then show usage. */ bb_show_usage(); } /* Get the priority adjustment (absolute or relative). */ adjustment = bb_xgetlarg(*argv, 10, INT_MIN, INT_MAX); while (*++argv) { /* Check for a mode switch. */ if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) { static const char opts[] = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER }; const char *p; if ((p = strchr(opts, argv[0][1]))) { which = p[4]; continue; } } /* Process an ID arg. */ if (which == PRIO_USER) { struct passwd *p; if (!(p = getpwnam(*argv))) { bb_error_msg("unknown user: %s", *argv); goto HAD_ERROR; } who = p->pw_uid; } else { char *e; errno = 0; who = strtoul(*argv, &e, 10); if (*e || (*argv == e) || errno) { bb_error_msg("bad value: %s", *argv); 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, who, 'g'); goto HAD_ERROR; } new_priority = int_add_no_wrap(old_priority, adjustment); } else { new_priority = adjustment; } if (setpriority(which, who, new_priority) == 0) { continue; } bb_perror_msg(Xetpriority_msg, who, '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; }
extern int fold_main(int argc, char **argv) { char *w_opt; int width = 80; int i; int errs = 0; #ifdef CONFIG_FEATURE_SUSv2_OBSOLETE /* Turn any numeric options into -w options. */ for (i = 1; i < argc; i++) { char const *a = argv[i]; if (a[0] == '-') { if (a[1] == '-' && !a[2]) break; if (isdigit(a[1])) { char *s = xmalloc(strlen(a) + 2); s[0] = '-'; s[1] = 'w'; strcpy(s + 2, a + 1); argv[i] = s; } } } #endif flags = bb_getopt_ulflags(argc, argv, "bsw:", &w_opt); if (flags & FLAG_WIDTH) width = bb_xgetlarg(w_opt, 10, 1, 10000); argv += optind; if (!*argv) { *--argv = "-"; } do { FILE *istream = bb_wfopen_input(*argv); if (istream != NULL) { int c; int column = 0; /* Screen column where next char will go. */ int offset_out = 0; /* Index in `line_out' for next char. */ static char *line_out = NULL; static int allocated_out = 0; while ((c = getc(istream)) != EOF) { if (offset_out + 1 >= allocated_out) { allocated_out += 1024; line_out = xrealloc(line_out, allocated_out); } if (c == '\n') { line_out[offset_out++] = c; fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); column = offset_out = 0; continue; } rescan: column = adjust_column(column, c); if (column > width) { /* This character would make the line too long. Print the line plus a newline, and make this character start the next line. */ if (flags & FLAG_BREAK_SPACES) { /* Look for the last blank. */ int logical_end; for (logical_end = offset_out - 1; logical_end >= 0; logical_end--) { if (isblank(line_out[logical_end])) { break; } } if (logical_end >= 0) { /* Found a blank. Don't output the part after it. */ logical_end++; fwrite(line_out, sizeof(char), (size_t) logical_end, stdout); putchar('\n'); /* Move the remainder to the beginning of the next line. The areas being copied here might overlap. */ memmove(line_out, line_out + logical_end, offset_out - logical_end); offset_out -= logical_end; for (column = i = 0; i < offset_out; i++) { column = adjust_column(column, line_out[i]); } goto rescan; } } else { if (offset_out == 0) { line_out[offset_out++] = c; continue; } } line_out[offset_out++] = '\n'; fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); column = offset_out = 0; goto rescan; } line_out[offset_out++] = c; } if (offset_out) { fwrite(line_out, sizeof(char), (size_t) offset_out, stdout); } if (ferror(istream) || bb_fclose_nonstdin(istream)) { bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ errs |= EXIT_FAILURE; } } else { errs |= EXIT_FAILURE; } } while (*++argv); bb_fflush_stdout_and_exit(errs); }