int id_main(int argc, char **argv) { struct passwd *p; uid_t uid; gid_t gid; unsigned long flags; short status; /* Don't allow -n -r -nr -ug -rug -nug -rnug */ /* Don't allow more than one username */ bb_opt_complementally = "?1:?:u--g:g--u:r?ug:n?ug"; flags = bb_getopt_ulflags(argc, argv, "rnug"); /* This values could be overwritten later */ uid = geteuid(); gid = getegid(); if (flags & PRINT_REAL) { uid = getuid(); gid = getgid(); } if(argv[optind]) { p=getpwnam(argv[optind]); /* bb_xgetpwnam is needed because it exits on failure */ uid = bb_xgetpwnam(argv[optind]); gid = p->pw_gid; /* in this case PRINT_REAL is the same */ } if(flags & (JUST_GROUP | JUST_USER)) { /* JUST_GROUP and JUST_USER are mutually exclusive */ if(flags & NAME_NOT_NUMBER) { /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); } else { bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); } /* exit */ bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /* Print full info like GNU id */ /* bb_getpwuid doesn't exit on failure here */ status=printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u'); putchar(' '); /* bb_getgrgid doesn't exit on failure here */ status|=printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); putchar('\n'); bb_fflush_stdout_and_exit(status); }
int realpath_main(int argc, char **argv) { int retval = EXIT_SUCCESS; #if PATH_MAX > (BUFSIZ+1) RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX); # define resolved_path_MUST_FREE 1 #else #define resolved_path bb_common_bufsiz1 # define resolved_path_MUST_FREE 0 #endif if (--argc == 0) { bb_show_usage(); } do { argv++; if (realpath(*argv, resolved_path) != NULL) { puts(resolved_path); } else { retval = EXIT_FAILURE; bb_perror_msg("%s", *argv); } } while (--argc); #if ENABLE_FEATURE_CLEAN_UP && resolved_path_MUST_FREE RELEASE_CONFIG_BUFFER(resolved_path); #endif bb_fflush_stdout_and_exit(retval); }
int route_main(int argc, char **argv) { unsigned long opt; int what; char *family; /* First, remap '-net' and '-host' to avoid getopt problems. */ { char **p = argv; while (*++p) { if ((strcmp(*p, "-net") == 0) || (strcmp(*p, "-host") == 0)) { p[0][0] = '#'; } } } opt = bb_getopt_ulflags(argc, argv, "A:ne", &family); if ((opt & ROUTE_OPT_A) && strcmp(family, "inet")) { #ifdef CONFIG_FEATURE_IPV6 if (strcmp(family, "inet6") == 0) { opt |= ROUTE_OPT_INET6; /* Set flag for ipv6. */ } else #endif bb_show_usage(); } argv += optind; /* No more args means display the routing table. */ if (!*argv) { int noresolve = (opt & ROUTE_OPT_n) ? 0x0fff : 0; #ifdef CONFIG_FEATURE_IPV6 if (opt & ROUTE_OPT_INET6) INET6_displayroutes(noresolve); else #endif displayroutes(noresolve, opt & ROUTE_OPT_e); bb_xferror_stdout(); bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /* Check verb. At the moment, must be add, del, or delete. */ what = kw_lookup(tbl_verb, &argv); if (!what || !*argv) { /* Unknown verb or no more args. */ bb_show_usage(); } #ifdef CONFIG_FEATURE_IPV6 if (opt & ROUTE_OPT_INET6) INET6_setroute(what, argv); else #endif INET_setroute(what, argv); return EXIT_SUCCESS; }
int whoami_main(int argc, char **argv) { if (argc > 1) bb_show_usage(); puts(bb_getpwuid(NULL, geteuid(), -1)); /* exits on error */ bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int dirname_main(int argc, char **argv) { if (argc != 2) { bb_show_usage(); } puts(dirname(argv[1])); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int length_main(int argc, char **argv) { if ((argc != 2) || (**(++argv) == '-')) { bb_show_usage(); } bb_printf("%lu\n", (unsigned long)strlen(*argv)); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int sort_main(int argc, char **argv) { FILE *fp; char *line, **lines = NULL; int i, nlines = 0, inc; int (*compare)(const void *, const void *) = compare_ascii; int flags; bb_default_error_retval = 2; flags = bb_getopt_ulflags(argc, argv, "nru"); if (flags & 1) { compare = compare_numeric; } argv += optind; if (!*argv) { *--argv = "-"; } do { fp = xgetoptfile_sort_uniq(argv, "r"); while ((line = bb_get_chomped_line_from_file(fp)) != NULL) { lines = xrealloc(lines, sizeof(char *) * (nlines + 1)); lines[nlines++] = line; } bb_xferror(fp, *argv); bb_fclose_nonstdin(fp); } while (*++argv); /* sort it */ qsort(lines, nlines, sizeof(char *), compare); /* print it */ i = 0; --nlines; if ((inc = 1 - (flags & 2)) < 0) { /* reverse */ i = nlines; } flags &= 4; while (nlines >= 0) { if (!flags || !nlines || strcmp(lines[i+inc], lines[i])) { puts(lines[i]); } i += inc; --nlines; } bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int env_main(int argc, char** argv) { static char *cleanenv[1] = { NULL }; char **ep, *p; unsigned long opt; llist_t *unset_env = NULL; extern char **environ; bb_opt_complementally = "u::"; #if ENABLE_FEATURE_ENV_LONG_OPTIONS bb_applet_long_options = env_long_options; #endif opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env); argv += optind; if (*argv && (argv[0][0] == '-') && !argv[0][1]) { opt |= 1; ++argv; } if(opt & 1) environ = cleanenv; else if(opt & 2) { while(unset_env) { unsetenv(unset_env->data); unset_env = unset_env->link; } } while (*argv && ((p = strchr(*argv, '=')) != NULL)) { if (putenv(*argv) < 0) { bb_perror_msg_and_die("putenv"); } ++argv; } if (*argv) { execvp(*argv, argv); /* SUSv3-mandated exit codes. */ bb_default_error_retval = (errno == ENOENT) ? 127 : 126; bb_perror_msg_and_die("%s", *argv); } for (ep = environ; *ep; ep++) { puts(*ep); } bb_fflush_stdout_and_exit(0); }
extern int env_main(int argc, char** argv) { char **ep, *p; char *cleanenv[1] = { NULL }; unsigned long opt; llist_t *unset_env; extern char **environ; bb_opt_complementaly = "u*"; bb_applet_long_options = env_long_options; opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env); argv += optind; if (*argv && (argv[0][0] == '-') && !argv[0][1]) { opt |= 1; ++argv; } if(opt & 1) environ = cleanenv; else if(opt & 2) { while(unset_env) { unsetenv(unset_env->data); unset_env = unset_env->link; } } while (*argv && ((p = strchr(*argv, '=')) != NULL)) { if (putenv(*argv) < 0) { bb_perror_msg_and_die("putenv"); } ++argv; } if (*argv) { int er; execvp(*argv, argv); er = errno; bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ return (er == ENOENT) ? 127 : 126; /* SUSv3-mandated exit codes. */ } for (ep = environ; *ep; ep++) { puts(*ep); } bb_fflush_stdout_and_exit(0); }
int logname_main(int argc, char ATTRIBUTE_UNUSED **argv) { const char *p; if (argc > 1) { bb_show_usage(); } if ((p = getlogin()) != NULL) { puts(p); bb_fflush_stdout_and_exit(EXIT_SUCCESS); } bb_perror_msg_and_die("getlogin"); }
extern int whoami_main(int argc, char **argv) { char user[9]; uid_t uid; if (argc > 1) bb_show_usage(); uid = geteuid(); if (my_getpwuid(user, uid)) { puts(user); bb_fflush_stdout_and_exit(EXIT_SUCCESS); } bb_error_msg_and_die("cannot find username for UID %u", (unsigned) uid); }
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 basename_main(int argc, char **argv) { size_t m, n; char *s; if (((unsigned int)(argc-2)) >= 2) { bb_show_usage(); } s = bb_get_last_path_component(*++argv); if (*++argv) { n = strlen(*argv); m = strlen(s); if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { s[m-n] = '\0'; } } puts(s); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int uniq_main(int argc, char **argv) { FILE *in, *out; unsigned long dups, skip_fields, skip_chars, i, uniq_flags; const char *s0, *e0, *s1, *e1, *input_filename; int opt; uniq_flags = skip_fields = skip_chars = 0; while ((opt = getopt(argc, argv, uniq_opts)) > 0) { if ((opt == 'f') || (opt == 's')) { int t = bb_xgetularg10(optarg); if (opt == 'f') { skip_fields = t; } else { skip_chars = t; } } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { uniq_flags |= s0[4]; } else { bb_show_usage(); } } input_filename = *(argv += optind); 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 = bb_get_chomped_line_from_file(in)) != NULL) { e1 = s1; for (i=skip_fields ; i ; i--) { e1 = bb_skip_whitespace(e1); while (*e1 && !isspace(*e1)) { ++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 (!(uniq_flags & (2 << !!dups))) { bb_fprintf(out, "\0%d " + (uniq_flags & 1), dups + 1); bb_fprintf(out, "%s\n", s0); } free((void *)s0); } } while (s1); bb_xferror(in, input_filename); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
extern int id_main(int argc, char **argv) { struct passwd *p; uid_t uid; gid_t gid; unsigned long flags; short status; #ifdef CONFIG_SELINUX int is_flask_enabled_flag = is_flask_enabled(); #endif bb_opt_complementaly = "u~g:g~u"; flags = bb_getopt_ulflags(argc, argv, "rnug"); if ((flags & BB_GETOPT_ERROR) /* Don't allow -n -r -nr */ || (flags <= 3 && flags > 0) /* Don't allow more than one username */ || (argc > optind + 1)) bb_show_usage(); /* This values could be overwritten later */ uid = geteuid(); gid = getegid(); if (flags & PRINT_REAL) { uid = getuid(); gid = getgid(); } if(argv[optind]) { p=getpwnam(argv[optind]); /* my_getpwnam is needed because it exits on failure */ uid = my_getpwnam(argv[optind]); gid = p->pw_gid; /* in this case PRINT_REAL is the same */ } if(flags & (JUST_GROUP | JUST_USER)) { /* JUST_GROUP and JUST_USER are mutually exclusive */ if(flags & NAME_NOT_NUMBER) { /* my_getpwuid and my_getgrgid exit on failure so puts cannot segfault */ puts((flags & JUST_USER) ? my_getpwuid(NULL, uid, -1 ) : my_getgrgid(NULL, gid, -1 )); } else { bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); } /* exit */ bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /* Print full info like GNU id */ /* my_getpwuid doesn't exit on failure here */ status=printf_full(uid, my_getpwuid(NULL, uid, 0), 'u'); putchar(' '); /* my_getgrgid doesn't exit on failure here */ status|=printf_full(gid, my_getgrgid(NULL, gid, 0), 'g'); #ifdef CONFIG_SELINUX if(is_flask_enabled_flag) { security_id_t mysid = getsecsid(); char context[80]; int len = sizeof(context); context[0] = '\0'; if(security_sid_to_context(mysid, context, &len)) strcpy(context, "unknown"); bb_printf(" context=%s", context); } #endif putchar('\n'); bb_fflush_stdout_and_exit(status); }
extern int id_main(int argc, char **argv) { char user[9], group[9]; long pwnam, grnam; int uid, gid; int flags; #ifdef CONFIG_SELINUX int is_flask_enabled_flag = is_flask_enabled(); #endif flags = bb_getopt_ulflags(argc, argv, "ugrn"); if (((flags & (JUST_USER | JUST_GROUP)) == (JUST_USER | JUST_GROUP)) || (argc > optind + 1) ) { bb_show_usage(); } if (argv[optind] == NULL) { if (flags & PRINT_REAL) { uid = getuid(); gid = getgid(); } else { uid = geteuid(); gid = getegid(); } my_getpwuid(user, uid); } else { safe_strncpy(user, argv[optind], sizeof(user)); gid = my_getpwnamegid(user); } my_getgrgid(group, gid); pwnam=my_getpwnam(user); grnam=my_getgrnam(group); if (flags & (JUST_GROUP | JUST_USER)) { char *s = group; if (flags & JUST_USER) { s = user; grnam = pwnam; } if (flags & NAME_NOT_NUMBER) { puts(s); } else { printf("%ld\n", grnam); } } else { #ifdef CONFIG_SELINUX printf("uid=%ld(%s) gid=%ld(%s)", pwnam, user, grnam, group); if(is_flask_enabled_flag) { security_id_t mysid = getsecsid(); char context[80]; int len = sizeof(context); context[0] = '\0'; if(security_sid_to_context(mysid, context, &len)) strcpy(context, "unknown"); printf(" context=%s\n", context); } else printf("\n"); #else printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group); #endif } bb_fflush_stdout_and_exit(0); }
int head_main(int argc, char **argv) { unsigned long count = 10; unsigned long i; #ifdef CONFIG_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; /* Allow legacy syntax of an initial numeric option without -n. */ if ((argc > 1) && (argv[1][0] == '-') /* && (isdigit)(argv[1][1]) */ && (((unsigned int)(argv[1][1] - '0')) <= 9) ) { --argc; ++argv; p = (*argv) + 1; goto GET_COUNT; } while ((opt = getopt(argc, argv, head_opts)) > 0) { switch(opt) { #ifdef CONFIG_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; GET_COUNT: count = bb_xgetularg10(p); break; default: bb_show_usage(); } } argv += optind; if (!*argv) { *--argv = "-"; } fmt = header_fmt_str + 1; #ifdef CONFIG_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 { if ((fp = bb_wfopen_input(*argv)) != NULL) { if (fp == stdin) { *argv = (char *) bb_msg_standard_input; } if (header_threshhold) { bb_printf(fmt, *argv); } i = count; while (i && ((c = getc(fp)) != EOF)) { if (count_bytes || (c == '\n')) { --i; } putchar(c); } if (bb_fclose_nonstdin(fp)) { bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ retval = EXIT_FAILURE; } bb_xferror_stdout(); } fmt = header_fmt_str; } while (*++argv); bb_fflush_stdout_and_exit(retval); }
int last_main(int argc, char **argv) { struct utmp ut; int n, file = STDIN_FILENO; time_t t_tmp; if (argc > 1) { bb_show_usage(); } file = bb_xopen(_PATH_WTMP, O_RDONLY); printf("%-10s %-14s %-18s %-12.12s %s\n", "USER", "TTY", "HOST", "LOGIN", "TIME"); while ((n = safe_read(file, (void*)&ut, sizeof(struct utmp))) != 0) { if (n != sizeof(struct utmp)) { bb_perror_msg_and_die("short read"); } if (strncmp(ut.ut_line, "~", 1) == 0) { if (strncmp(ut.ut_user, "shutdown", 8) == 0) ut.ut_type = SHUTDOWN_TIME; else if (strncmp(ut.ut_user, "reboot", 6) == 0) ut.ut_type = BOOT_TIME; else if (strncmp(ut.ut_user, "runlevel", 7) == 0) ut.ut_type = RUN_LVL; } else { if (!ut.ut_name[0] || strcmp(ut.ut_name, "LOGIN") == 0 || ut.ut_name[0] == 0) { /* Don't bother. This means we can't find how long * someone was logged in for. Oh well. */ continue; } if (ut.ut_type != DEAD_PROCESS && ut.ut_name[0] && ut.ut_line[0]) { ut.ut_type = USER_PROCESS; } if (strcmp(ut.ut_name, "date") == 0) { if (ut.ut_line[0] == '|') ut.ut_type = OLD_TIME; if (ut.ut_line[0] == '{') ut.ut_type = NEW_TIME; } } if (ut.ut_type!=USER_PROCESS) { switch (ut.ut_type) { case OLD_TIME: case NEW_TIME: case RUN_LVL: case SHUTDOWN_TIME: continue; case BOOT_TIME: strcpy(ut.ut_line, "system boot"); break; } } t_tmp = (time_t)ut.ut_tv.tv_sec; printf("%-10s %-14s %-18s %-12.12s\n", ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); } bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
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); }
int cal_main(int argc, char **argv) { struct tm *local_time; struct tm zero_tm; time_t now; int month, year, flags, i; char *month_names[12]; char day_headings[28]; /* 28 for julian, 21 for nonjulian */ char buf[40]; #ifdef CONFIG_LOCALE_SUPPORT setlocale(LC_TIME, ""); #endif flags = bb_getopt_ulflags(argc, argv, "jy"); julian = flags & 1; argv += optind; month = 0; if ((argc -= optind) > 2) { bb_show_usage(); } if (!argc) { time(&now); local_time = localtime(&now); year = local_time->tm_year + 1900; if (!(flags & 2)) { month = local_time->tm_mon + 1; } } else { if (argc == 2) { month = bb_xgetularg10_bnd(*argv++, 1, 12); } year = bb_xgetularg10_bnd(*argv, 1, 9999); } blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); i = 0; do { zero_tm.tm_mon = i; strftime(buf, sizeof(buf), "%B", &zero_tm); month_names[i] = bb_xstrdup(buf); if (i < 7) { zero_tm.tm_wday = i; strftime(buf, sizeof(buf), "%a", &zero_tm); strncpy(day_headings + i * (3+julian) + julian, buf, 2); } } while (++i < 12); if (month) { int row, len, days[MAXDAYS]; int *dp = days; char lineout[30]; day_array(month, year, dp); len = sprintf(lineout, "%s %d", month_names[month - 1], year); bb_printf("%*s%s\n%s\n", ((7*julian + WEEK_LEN) - len) / 2, "", lineout, day_headings); for (row = 0; row < 6; row++) { build_row(lineout, dp)[0] = '\0'; dp += 7; trim_trailing_spaces_and_print(lineout); } } else { int row, which_cal, week_len, days[12][MAXDAYS]; int *dp; char lineout[80]; sprintf(lineout, "%d", year); center(lineout, (WEEK_LEN * 3 + HEAD_SEP * 2) + julian * (J_WEEK_LEN * 2 + HEAD_SEP - (WEEK_LEN * 3 + HEAD_SEP * 2)), 0); puts("\n"); /* two \n's */ for (i = 0; i < 12; i++) { day_array(i + 1, year, days[i]); } blank_string(lineout, sizeof(lineout)); week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN); for (month = 0; month < 12; month += 3-julian) { center(month_names[month], week_len, HEAD_SEP); if (!julian) { center(month_names[month + 1], week_len, HEAD_SEP); } center(month_names[month + 2 - julian], week_len, 0); bb_printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); if (!julian) { bb_printf("%*s%s", HEAD_SEP, "", day_headings); } putchar('\n'); for (row = 0; row < (6*7); row += 7) { for (which_cal = 0; which_cal < 3-julian; which_cal++) { dp = days[month + which_cal] + row; build_row(lineout + which_cal * (week_len + 2), dp); } /* blank_string took care of nul termination. */ trim_trailing_spaces_and_print(lineout); } } } bb_fflush_stdout_and_exit(0); }
int id_main(int argc, char **argv) { struct passwd *p; uid_t uid; gid_t gid; unsigned long flags; short status; #ifdef CONFIG_SELINUX security_context_t scontext; #endif /* Don't allow -n -r -nr -ug -rug -nug -rnug */ /* Don't allow more than one username */ bb_opt_complementally = "?1:?:u--g:g--u:r?ug:n?ug"; flags = bb_getopt_ulflags(argc, argv, "rnugZ"); /* This values could be overwritten later */ uid = geteuid(); gid = getegid(); if (flags & PRINT_REAL) { uid = getuid(); gid = getgid(); } if(argv[optind]) { p=getpwnam(argv[optind]); /* bb_xgetpwnam is needed because it exits on failure */ uid = bb_xgetpwnam(argv[optind]); gid = p->pw_gid; /* in this case PRINT_REAL is the same */ } #ifdef CONFIG_SELINUX if(flags & (JUST_GROUP | JUST_USER | JUST_CONTEXT )) { #else if(flags & (JUST_GROUP | JUST_USER )) { #endif /* JUST_GROUP and JUST_USER are mutually exclusive */ if(flags & NAME_NOT_NUMBER) { /* bb_getpwuid and bb_getgrgid exit on failure so puts cannot segfault */ puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1 )); } else { if (flags & JUST_USER){ bb_printf("%u\n",uid); } if (flags & JUST_GROUP){ bb_printf("%u\n",gid); } } #ifdef CONFIG_SELINUX if(flags & JUST_CONTEXT){ if( !is_selinux_enabled() ) { bb_error_msg_and_die("Sorry, --context (-Z) can be used only on " "a selinux-enabled kernel.\n" ); } if (argc - optind == 1){ bb_error_msg("cannot print security context when user specified"); bb_fflush_stdout_and_exit(EXIT_FAILURE); } if (getcon(&scontext)){ bb_error_msg("can't get process context"); bb_fflush_stdout_and_exit(EXIT_FAILURE); } bb_printf("%s\n", scontext); } #endif /* exit */ bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /* Print full info like GNU id */ /* bb_getpwuid doesn't exit on failure here */ status=printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u'); putchar(' '); /* bb_getgrgid doesn't exit on failure here */ status|=printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); #ifdef CONFIG_SELINUX if ( is_selinux_enabled() ) { security_context_t mysid; char context[80]; int len = sizeof(context); getcon(&mysid); context[0] = '\0'; if (mysid) { len = strlen(mysid)+1; safe_strncpy(context, mysid, len); freecon(mysid); }else{ safe_strncpy(context, "unknown",8); } bb_printf(" context=%s", context); } #endif putchar('\n'); bb_fflush_stdout_and_exit(status); }
int uniq_main(int argc, char **argv) { FILE *in, *out; /* Note: Ignore the warning about dups and e0 being used uninitialized. * They will be initialized on the fist pass of the loop (since s0 is NULL). */ unsigned long dups, skip_fields, skip_chars, i; const char *s0, *e0, *s1, *e1, *input_filename; int opt; int uniq_flags = 6; /* -u */ skip_fields = skip_chars = 0; while ((opt = getopt(argc, argv, uniq_opts)) > 0) { if (opt == 'f') { skip_fields = bb_xgetularg10(optarg); } else if (opt == 's') { skip_chars = bb_xgetularg10(optarg); } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { uniq_flags &= s0[4]; uniq_flags |= s0[7]; } else { bb_show_usage(); } } input_filename = *(argv += optind); in = xgetoptfile_sort_uniq(argv, "r"); if (*argv) { ++argv; } out = xgetoptfile_sort_uniq(argv, "w"); if (*argv && argv[1]) { bb_show_usage(); } s0 = NULL; /* gnu uniq ignores newlines */ while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) { e1 = s1; for (i=skip_fields ; i ; i--) { e1 = bb_skip_whitespace(e1); while (*e1 && !isspace(*e1)) { ++e1; } } for (i = skip_chars ; *e1 && i ; i--) { ++e1; } if (s0) { if (strcmp(e0, e1) == 0) { ++dups; /* Note: Testing for overflow seems excessive. */ continue; } DO_LAST: if ((dups && (uniq_flags & 2)) || (!dups && (uniq_flags & 4))) { bb_fprintf(out, "\0%7d\t" + (uniq_flags & 1), dups + 1); bb_fprintf(out, "%s\n", s0); } free((void *)s0); } s0 = s1; e0 = e1; dups = 0; } if (s0) { e1 = NULL; goto DO_LAST; } bb_xferror(in, input_filename); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
int du_main(int argc, char **argv) { long total; int slink_depth_save; int print_final_total; char *smax_print_depth; unsigned long opt; #ifdef CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */ #ifdef CONFIG_FEATURE_HUMAN_READABLE disp_hr = 512; #else disp_k = 0; #endif } #endif /* Note: SUSv3 specifies that -a and -s options can not be used together * in strictly conforming applications. However, it also says that some * du implementations may produce output when -a and -s are used together. * gnu du exits with an error code in this case. We choose to simply * ignore -a. This is consistent with -s being equivalent to -d 0. */ #ifdef CONFIG_FEATURE_HUMAN_READABLE bb_opt_complementally = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; opt = bb_getopt_ulflags(argc, argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth); if((opt & (1 << 9))) { /* -h opt */ disp_hr = 0; } if((opt & (1 << 10))) { /* -m opt */ disp_hr = MEGABYTE; } if((opt & (1 << 2))) { /* -k opt */ disp_hr = KILOBYTE; } #else bb_opt_complementally = "H-L:L-H:s-d:d-s"; opt = bb_getopt_ulflags(argc, argv, "aHkLsx" "d:" "lc", &smax_print_depth); #if !defined CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K if((opt & (1 << 2))) { /* -k opt */ disp_k = 1; } #endif #endif if((opt & (1 << 0))) { /* -a opt */ print_files = INT_MAX; } if((opt & (1 << 1))) { /* -H opt */ slink_depth = 1; } if((opt & (1 << 3))) { /* -L opt */ slink_depth = INT_MAX; } if((opt & (1 << 4))) { /* -s opt */ max_print_depth = 0; } one_file_system = opt & (1 << 5); /* -x opt */ if((opt & (1 << 6))) { /* -d opt */ max_print_depth = bb_xgetularg10_bnd(smax_print_depth, 0, INT_MAX); } if((opt & (1 << 7))) { /* -l opt */ count_hardlinks = INT_MAX; } print_final_total = opt & (1 << 8); /* -c opt */ /* go through remaining args (if any) */ argv += optind; if (optind >= argc) { *--argv = "."; if (slink_depth == 1) { slink_depth = 0; } } slink_depth_save = slink_depth; total = 0; do { total += du(*argv); slink_depth = slink_depth_save; } while (*++argv); #ifdef CONFIG_FEATURE_CLEAN_UP reset_ino_dev_hashtable(); #endif if (print_final_total) { print(total, "total"); } bb_fflush_stdout_and_exit(status); }
int cmp_main(int argc, char **argv) { FILE *fp1, *fp2, *outfile = stdout; const char *filename1, *filename2; const char *fmt; int c1, c2, char_pos, line_pos; int opt_flags; int exit_val = 0; bb_default_error_retval = 2; /* 1 is returned if files are different. */ opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { bb_show_usage(); } fp1 = cmp_xfopen_input(filename1 = *(argv += optind)); filename2 = "-"; if (*++argv) { filename2 = *argv; } fp2 = cmp_xfopen_input(filename2); if (fp1 == fp2) { /* Paranioa check... stdin == stdin? */ /* Note that we don't bother reading stdin. Neither does gnu wc. * But perhaps we should, so that other apps down the chain don't * get the input. Consider 'echo hello | (cmp - - && cat -)'. */ return 0; } fmt = fmt_differ; if (opt_flags == OPT_l) { fmt = fmt_l_opt; } char_pos = 0; line_pos = 1; do { c1 = getc(fp1); c2 = getc(fp2); ++char_pos; if (c1 != c2) { /* Remember -- a read error may have occurred. */ exit_val = 1; /* But assume the files are different for now. */ if (c2 == EOF) { /* We know that fp1 isn't at EOF or in an error state. But to * save space below, things are setup to expect an EOF in fp1 * if an EOF occurred. So, swap things around. */ fp1 = fp2; filename1 = filename2; c1 = c2; } if (c1 == EOF) { bb_xferror(fp1, filename1); fmt = fmt_eof; /* Well, no error, so it must really be EOF. */ outfile = stderr; /* There may have been output to stdout (option -l), so * make sure we fflush before writing to stderr. */ bb_xfflush_stdout(); } if (opt_flags != OPT_s) { if (opt_flags == OPT_l) { line_pos = c1; /* line_pos is unused in the -l case. */ } bb_fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2); if (opt_flags) { /* This must be -l since not -s. */ /* If we encountered and EOF, the while check will catch it. */ continue; } } break; } if (c1 == '\n') { ++line_pos; } } while (c1 != EOF); bb_xferror(fp1, filename1); bb_xferror(fp2, filename2); bb_fflush_stdout_and_exit(exit_val); }
extern int df_main(int argc, char **argv) { long blocks_used; long blocks_percent_used; #ifdef CONFIG_FEATURE_HUMAN_READABLE unsigned long df_disp_hr = KILOBYTE; #endif int status = EXIT_SUCCESS; unsigned long opt; FILE *mount_table; struct mntent *mount_entry; struct statfs s; static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */ const char *disp_units_hdr = hdr_1k; char df_entry[200] = {0}; // Added by Nick Wang, 01/05/2005 int entry_len = 0; // Added by Nick Wang, 01/05/2005 printf("busybox df_main: start\n"); #ifdef CONFIG_FEATURE_HUMAN_READABLE bb_opt_complementaly = "h-km:k-hm:m-hk"; opt = bb_getopt_ulflags(argc, argv, "hmk"); if(opt & 1) { df_disp_hr = 0; disp_units_hdr = " Size"; } if(opt & 2) { df_disp_hr = MEGABYTE; disp_units_hdr = "1M-blocks"; } #else opt = bb_getopt_ulflags(argc, argv, "k"); #endif bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", "", disp_units_hdr); mount_table = NULL; argv += optind; if (optind >= argc) { if (!(mount_table = setmntent(bb_path_mtab_file, "r"))) { bb_perror_msg_and_die(bb_path_mtab_file); } } do { const char *device; const char *mount_point; if (mount_table) { if (!(mount_entry = getmntent(mount_table))) { endmntent(mount_table); break; } } else { if (!(mount_point = *argv++)) { break; } if (!(mount_entry = find_mount_point(mount_point, bb_path_mtab_file))) { bb_error_msg("%s: can't find mount point.", mount_point); SET_ERROR: status = EXIT_FAILURE; continue; } } device = mount_entry->mnt_fsname; mount_point = mount_entry->mnt_dir; if (statfs(mount_point, &s) != 0) { bb_perror_msg("%s", mount_point); goto SET_ERROR; } if ((s.f_blocks > 0) || !mount_table){ blocks_used = s.f_blocks - s.f_bfree; blocks_percent_used = 0; if (blocks_used + s.f_bavail) { blocks_percent_used = (((long long) blocks_used) * 100 + (blocks_used + s.f_bavail)/2 ) / (blocks_used + s.f_bavail); } if (strcmp(device, "rootfs") == 0) { continue; } else if (strcmp(device, "/dev/root") == 0) { /* Adjusts device to be the real root device, * or leaves device alone if it can't find it */ if ((device = find_real_root_device_name(device)) == NULL) { goto SET_ERROR; } } #ifdef CONFIG_FEATURE_HUMAN_READABLE bb_printf("%-21s%9s ", device, make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); sprintf(df_entry, "%-21s%9s ", device, make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); entry_len = strlen(df_entry); bb_printf("%9s ", make_human_readable_str( (s.f_blocks - s.f_bfree), s.f_bsize, df_disp_hr)); sprintf(df_entry + entry_len, "%9s ", make_human_readable_str( (s.f_blocks - s.f_bfree), s.f_bsize, df_disp_hr)); entry_len = strlen(df_entry); bb_printf("%9s %3ld%% %s\n", make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), blocks_percent_used, mount_point); sprintf(df_entry + entry_len, "%9s %3ld%% %s\n", make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), blocks_percent_used, mount_point); entry_len = strlen(df_entry); // output df table to file, Added By Nick Wang, 01/05/02005 { FILE *fp; if ((fp = fopen("/var/.sys-df", "a")) != NULL) fprintf(fp, "%s\n", df_entry); (void) fclose(fp); } // Added End #else bb_printf("%-21s%9ld %9ld %9ld %3ld%% %s\n", device, kscale(s.f_blocks, s.f_bsize), kscale(s.f_blocks-s.f_bfree, s.f_bsize), kscale(s.f_bavail, s.f_bsize), blocks_percent_used, mount_point); #endif } } while (1); bb_fflush_stdout_and_exit(status); }
int echo_main(int argc, char** argv) { (void)bb_echo(argc, argv); bb_fflush_stdout_and_exit(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 which_main(int argc, char **argv) { int status; size_t i, count; char *path_list; if (argc <= 1 || **(argv + 1) == '-') { bb_show_usage(); } argc--; path_list = getenv("PATH"); if (path_list != NULL) { size_t path_len = strlen(path_list); char *new_list = NULL; count = 1; for (i = 0; i <= path_len; i++) { char *this_i = &path_list[i]; if (*this_i == ':') { /* ^::[^:] == \.: */ if (!i && (*(this_i + 1) == ':')) { *this_i = '.'; continue; } *this_i = 0; count++; /* ^:[^:] == \.0 and [^:]::[^:] == 0\.0 and [^:]:$ == 0\.0 */ if (!i || (*(this_i + 1) == ':') || (i == path_len-1)) { new_list = xrealloc(new_list, path_len += 1); if (i) { memmove(&new_list[i+2], &path_list[i+1], path_len-i); new_list[i+1] = '.'; memmove(new_list, path_list, i); } else { memmove(&new_list[i+1], &path_list[i], path_len-i); new_list[i] = '.'; } path_list = new_list; } } } } else { path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin"; count = 5; } status = EXIT_SUCCESS; while (argc-- > 0) { struct stat stat_b; char *buf; char *path_n; int found = 0; argv++; path_n = path_list; buf = *argv; /* if filename is either absolute or contains slashes, * stat it */ if (strchr(buf, '/') != NULL && is_executable_file(buf, &stat_b)) { found++; } else { /* Couldn't access file and file doesn't contain slashes */ for (i = 0; i < count; i++) { buf = concat_path_file(path_n, *argv); if (is_executable_file(buf, &stat_b)) { found++; break; } free(buf); path_n += (strlen(path_n) + 1); } } if (found) { puts(buf); } else { status = EXIT_FAILURE; } } bb_fflush_stdout_and_exit(status); }
int sort_main(int argc, char **argv) { FILE *fp,*outfile=NULL; int linecount=0,i,flag; char *line,**lines=NULL,*optlist="ngMucszbrdfimS:T:o:k:t:"; int c; bb_default_error_retval = 2; /* Parse command line options */ while((c=getopt(argc,argv,optlist))>0) { line=index(optlist,c); if(!line) bb_show_usage(); switch(*line) { #ifdef CONFIG_FEATURE_SORT_BIG case 'o': if(outfile) bb_error_msg_and_die("Too many -o."); outfile=bb_xfopen(optarg,"w"); break; case 't': if(key_separator || optarg[1]) bb_error_msg_and_die("Too many -t."); key_separator=*optarg; break; /* parse sort key */ case 'k': { struct sort_key *key=add_key(); char *temp, *temp2; temp=optarg; for(i=0;*temp;) { /* Start of range */ key->range[2*i]=(unsigned short)strtol(temp,&temp,10); if(*temp=='.') key->range[(2*i)+1]=(unsigned short)strtol(temp+1,&temp,10); for(;*temp;temp++) { if(*temp==',' && !i++) { temp++; break; } /* no else needed: fall through to syntax error because comma isn't in optlist */ temp2=index(optlist,*temp); flag=(1<<(temp2-optlist)); if(!temp2 || (flag>FLAG_M && flag<FLAG_b)) bb_error_msg_and_die("Unknown key option."); /* b after , means strip _trailing_ space */ if(i && flag==FLAG_b) flag=FLAG_bb; key->flags|=flag; } } break; } #endif default: global_flags|=(1<<(line-optlist)); /* global b strips leading and trailing spaces */ if(global_flags&FLAG_b) global_flags|=FLAG_bb; break; } } /* Open input files and read data */ for(i=argv[optind] ? optind : optind-1;argv[i];i++) { if(i<optind || (*argv[i]=='-' && !argv[i][1])) fp=stdin; else fp=bb_xfopen(argv[i],"r"); for(;;) { line=GET_LINE(fp); if(!line) break; if(!(linecount&63)) lines=xrealloc(lines, sizeof(char *)*(linecount+64)); lines[linecount++]=line; } fclose(fp); } #ifdef CONFIG_FEATURE_SORT_BIG /* if no key, perform alphabetic sort */ if(!key_list) add_key()->range[0]=1; /* handle -c */ if(global_flags&FLAG_c) { int j=(global_flags&FLAG_u) ? -1 : 0; for(i=1;i<linecount;i++) if(compare_keys(&lines[i-1],&lines[i])>j) { fprintf(stderr,"Check line %d\n",i); return 1; } return 0; } #endif /* Perform the actual sort */ qsort(lines,linecount,sizeof(char *),compare_keys); /* handle -u */ if(global_flags&FLAG_u) { for(flag=0,i=1;i<linecount;i++) { if(!compare_keys(&lines[flag],&lines[i])) free(lines[i]); else lines[++flag]=lines[i]; } if(linecount) linecount=flag+1; } /* Print it */ if(!outfile) outfile=stdout; for(i=0;i<linecount;i++) fprintf(outfile,"%s\n",lines[i]); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }