From: Denys Vlasenko Date: Wed, 12 Apr 2017 12:16:29 +0000 (+0200) Subject: Sort more misplaced applets into coreutils or util-linux X-Git-Tag: 1_27_0~52 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=0cecbe7d5de237a6c699c67ae53ae2e2481eff43;p=oweals%2Fbusybox.git Sort more misplaced applets into coreutils or util-linux No code changes Surprisingly, nice and renice are coming from different packages :) Signed-off-by: Denys Vlasenko --- diff --git a/coreutils/cal.c b/coreutils/cal.c deleted file mode 100644 index af02608f0..000000000 --- a/coreutils/cal.c +++ /dev/null @@ -1,390 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Calendar implementation for busybox - * - * See original copyright at the end of this file - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ -/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) - * - * Major size reduction... over 50% (>1.5k) on i386. - */ -//config:config CAL -//config: bool "cal" -//config: default y -//config: help -//config: cal is used to display a monthly calendar. - -//applet:IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_CAL) += cal.o - -/* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ -/* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream - * BB_AUDIT BUG: version in util-linux seems to be broken as well. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ - -//usage:#define cal_trivial_usage -//usage: "[-jy] [[MONTH] YEAR]" -//usage:#define cal_full_usage "\n\n" -//usage: "Display a calendar\n" -//usage: "\n -j Use julian dates" -//usage: "\n -y Display the entire year" - -#include "libbb.h" -#include "unicode.h" - -/* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ - -#define THURSDAY 4 /* for reformation */ -#define SATURDAY 6 /* 1 Jan 1 was a Saturday */ - -#define FIRST_MISSING_DAY 639787 /* 3 Sep 1752 */ -#define NUMBER_MISSING_DAYS 11 /* 11 day correction */ - -#define MAXDAYS 42 /* max slots in a month array */ -#define SPACE -1 /* used in day array */ - -static const unsigned char days_in_month[] ALIGN1 = { - 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -static const unsigned char sep1752[] ALIGN1 = { - 1, 2, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30 -}; - -/* Set to 0 or 1 in main */ -#define julian ((unsigned)option_mask32) - -/* leap year -- account for Gregorian reformation in 1752 */ -static int leap_year(unsigned yr) -{ - if (yr <= 1752) - return !(yr % 4); - return (!(yr % 4) && (yr % 100)) || !(yr % 400); -} - -/* number of centuries since 1700, not inclusive */ -#define centuries_since_1700(yr) \ - ((yr) > 1700 ? (yr) / 100 - 17 : 0) - -/* number of centuries since 1700 whose modulo of 400 is 0 */ -#define quad_centuries_since_1700(yr) \ - ((yr) > 1600 ? ((yr) - 1600) / 400 : 0) - -/* number of leap years between year 1 and this year, not inclusive */ -#define leap_years_since_year_1(yr) \ - ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) - -static void center(char *, unsigned, unsigned); -static void day_array(unsigned, unsigned, unsigned *); -static void trim_trailing_spaces_and_print(char *); - -static void blank_string(char *buf, size_t buflen); -static char *build_row(char *p, unsigned *dp); - -#define DAY_LEN 3 /* 3 spaces per day */ -#define J_DAY_LEN (DAY_LEN + 1) -#define WEEK_LEN 20 /* 7 * 3 - one space at the end */ -#define J_WEEK_LEN (WEEK_LEN + 7) -#define HEAD_SEP 2 /* spaces between day headings */ - -int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int cal_main(int argc UNUSED_PARAM, char **argv) -{ - struct tm zero_tm; - time_t now; - unsigned month, year, flags, i; - char *month_names[12]; - /* normal heading: */ - /* "Su Mo Tu We Th Fr Sa" */ - /* -j heading: */ - /* " Su Mo Tu We Th Fr Sa" */ - char day_headings[ENABLE_UNICODE_SUPPORT ? 28 * 6 : 28]; - IF_UNICODE_SUPPORT(char *hp = day_headings;) - char buf[40]; - - init_unicode(); - - flags = getopt32(argv, "jy"); - /* This sets julian = flags & 1: */ - option_mask32 &= 1; - month = 0; - argv += optind; - - if (!argv[0]) { - struct tm *ptm; - - time(&now); - ptm = localtime(&now); - year = ptm->tm_year + 1900; - if (!(flags & 2)) { /* no -y */ - month = ptm->tm_mon + 1; - } - } else { - if (argv[1]) { - if (argv[2]) { - bb_show_usage(); - } - if (!(flags & 2)) { /* no -y */ - month = xatou_range(*argv, 1, 12); - } - argv++; - } - year = xatou_range(*argv, 1, 9999); - } - - blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); - - i = 0; - do { - zero_tm.tm_mon = i; - /* full month name according to locale */ - strftime(buf, sizeof(buf), "%B", &zero_tm); - month_names[i] = xstrdup(buf); - - if (i < 7) { - zero_tm.tm_wday = i; - /* abbreviated weekday name according to locale */ - strftime(buf, sizeof(buf), "%a", &zero_tm); -#if ENABLE_UNICODE_SUPPORT - if (julian) - *hp++ = ' '; - { - char *two_wchars = unicode_conv_to_printable_fixedwidth(/*NULL,*/ buf, 2); - strcpy(hp, two_wchars); - free(two_wchars); - } - hp += strlen(hp); - *hp++ = ' '; -#else - strncpy(day_headings + i * (3+julian) + julian, buf, 2); -#endif - } - } while (++i < 12); - IF_UNICODE_SUPPORT(hp[-1] = '\0';) - - if (month) { - unsigned row, len, days[MAXDAYS]; - unsigned *dp = days; - char lineout[30]; - - day_array(month, year, dp); - len = sprintf(lineout, "%s %u", month_names[month - 1], year); - 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 { - unsigned row, which_cal, week_len, days[12][MAXDAYS]; - unsigned *dp; - char lineout[80]; - - sprintf(lineout, "%u", 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); - printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); - if (!julian) { - printf("%*s%s", HEAD_SEP, "", day_headings); - } - bb_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); - } - } - } - - fflush_stdout_and_exit(EXIT_SUCCESS); -} - -/* - * day_array -- - * Fill in an array of 42 integers with a calendar. Assume for a moment - * that you took the (maximum) 6 rows in a calendar and stretched them - * out end to end. You would have 42 numbers or spaces. This routine - * builds that array for any month from Jan. 1 through Dec. 9999. - */ -static void day_array(unsigned month, unsigned year, unsigned *days) -{ - unsigned long temp; - unsigned i; - unsigned day, dw, dm; - - memset(days, SPACE, MAXDAYS * sizeof(int)); - - if ((month == 9) && (year == 1752)) { - /* Assumes the Gregorian reformation eliminates - * 3 Sep. 1752 through 13 Sep. 1752. - */ - unsigned j_offset = julian * 244; - size_t oday = 0; - - do { - days[oday+2] = sep1752[oday] + j_offset; - } while (++oday < sizeof(sep1752)); - - return; - } - - /* day_in_year - * return the 1 based day number within the year - */ - day = 1; - if ((month > 2) && leap_year(year)) { - ++day; - } - - i = month; - while (i) { - day += days_in_month[--i]; - } - - /* day_in_week - * return the 0 based day number for any date from 1 Jan. 1 to - * 31 Dec. 9999. Assumes the Gregorian reformation eliminates - * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all - * missing days. - */ - temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day; - if (temp < FIRST_MISSING_DAY) { - dw = ((temp - 1 + SATURDAY) % 7); - } else { - dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); - } - - if (!julian) { - day = 1; - } - - dm = days_in_month[month]; - if ((month == 2) && leap_year(year)) { - ++dm; - } - - do { - days[dw++] = day++; - } while (--dm); -} - -static void trim_trailing_spaces_and_print(char *s) -{ - char *p = s; - - while (*p) { - ++p; - } - while (p != s) { - --p; - if (!isspace(*p)) { - p[1] = '\0'; - break; - } - } - - puts(s); -} - -static void center(char *str, unsigned len, unsigned separate) -{ - unsigned n = strlen(str); - len -= n; - printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, ""); -} - -static void blank_string(char *buf, size_t buflen) -{ - memset(buf, ' ', buflen); - buf[buflen-1] = '\0'; -} - -static char *build_row(char *p, unsigned *dp) -{ - unsigned col, val, day; - - memset(p, ' ', (julian + DAY_LEN) * 7); - - col = 0; - do { - day = *dp++; - if (day != SPACE) { - if (julian) { - ++p; - if (day >= 100) { - *p = '0'; - p[-1] = (day / 100) + '0'; - day %= 100; - } - } - val = day / 10; - if (val > 0) { - *p = val + '0'; - } - *++p = day % 10 + '0'; - p += 2; - } else { - p += DAY_LEN + julian; - } - } while (++col < 7); - - return p; -} - -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kim Letkeman. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ diff --git a/coreutils/mktemp.c b/coreutils/mktemp.c new file mode 100644 index 000000000..65353697a --- /dev/null +++ b/coreutils/mktemp.c @@ -0,0 +1,122 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini mktemp implementation for busybox + * + * + * Copyright (C) 2000 by Daniel Jacobowitz + * Written by Daniel Jacobowitz + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +/* Coreutils 6.12 man page says: + * mktemp [OPTION]... [TEMPLATE] + * Create a temporary file or directory, safely, and print its name. If + * TEMPLATE is not specified, use tmp.XXXXXXXXXX. + * -d, --directory + * create a directory, not a file + * -q, --quiet + * suppress diagnostics about file/dir-creation failure + * -u, --dry-run + * do not create anything; merely print a name (unsafe) + * --tmpdir[=DIR] + * interpret TEMPLATE relative to DIR. If DIR is not specified, + * use $TMPDIR if set, else /tmp. With this option, TEMPLATE must + * not be an absolute name. Unlike with -t, TEMPLATE may contain + * slashes, but even here, mktemp still creates only the final com- + * ponent. + * -p DIR use DIR as a prefix; implies -t [deprecated] + * -t interpret TEMPLATE as a single file name component, relative to + * a directory: $TMPDIR, if set; else the directory specified via + * -p; else /tmp [deprecated] + */ +//config:config MKTEMP +//config: bool "mktemp" +//config: default y +//config: help +//config: mktemp is used to create unique temporary files + +//applet:IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o + +//usage:#define mktemp_trivial_usage +//usage: "[-dt] [-p DIR] [TEMPLATE]" +//usage:#define mktemp_full_usage "\n\n" +//usage: "Create a temporary file with name based on TEMPLATE and print its name.\n" +//usage: "TEMPLATE must end with XXXXXX (e.g. [/dir/]nameXXXXXX).\n" +//usage: "Without TEMPLATE, -t tmp.XXXXXX is assumed.\n" +//usage: "\n -d Make directory, not file" +//usage: "\n -q Fail silently on errors" +//usage: "\n -t Prepend base directory name to TEMPLATE" +//usage: "\n -p DIR Use DIR as a base directory (implies -t)" +//usage: "\n -u Do not create anything; print a name" +//usage: "\n" +//usage: "\nBase directory is: -p DIR, else $TMPDIR, else /tmp" +//usage: +//usage:#define mktemp_example_usage +//usage: "$ mktemp /tmp/temp.XXXXXX\n" +//usage: "/tmp/temp.mWiLjM\n" +//usage: "$ ls -la /tmp/temp.mWiLjM\n" +//usage: "-rw------- 1 andersen andersen 0 Apr 25 17:10 /tmp/temp.mWiLjM\n" + +#include "libbb.h" + +int mktemp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int mktemp_main(int argc UNUSED_PARAM, char **argv) +{ + const char *path; + char *chp; + unsigned opts; + enum { + OPT_d = 1 << 0, + OPT_q = 1 << 1, + OPT_t = 1 << 2, + OPT_p = 1 << 3, + OPT_u = 1 << 4, + }; + + path = getenv("TMPDIR"); + if (!path || path[0] == '\0') + path = "/tmp"; + + opt_complementary = "?1"; /* 1 argument max */ + opts = getopt32(argv, "dqtp:u", &path); + + chp = argv[optind]; + if (!chp) { + /* GNU coreutils 8.4: + * bare "mktemp" -> "mktemp -t tmp.XXXXXX" + */ + chp = xstrdup("tmp.XXXXXX"); + opts |= OPT_t; + } +#if 0 + /* Don't allow directory separator in template */ + if ((opts & OPT_t) && bb_basename(chp) != chp) { + errno = EINVAL; + goto error; + } +#endif + if (opts & (OPT_t|OPT_p)) + chp = concat_path_file(path, chp); + + if (opts & OPT_u) { + chp = mktemp(chp); + if (chp[0] == '\0') + goto error; + } else if (opts & OPT_d) { + if (mkdtemp(chp) == NULL) + goto error; + } else { + if (mkstemp(chp) < 0) + goto error; + } + puts(chp); + return EXIT_SUCCESS; + error: + if (opts & OPT_q) + return EXIT_FAILURE; + /* don't use chp as it gets mangled in case of error */ + bb_perror_nomsg_and_die(); +} diff --git a/debianutils/mktemp.c b/debianutils/mktemp.c deleted file mode 100644 index 65353697a..000000000 --- a/debianutils/mktemp.c +++ /dev/null @@ -1,122 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Mini mktemp implementation for busybox - * - * - * Copyright (C) 2000 by Daniel Jacobowitz - * Written by Daniel Jacobowitz - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -/* Coreutils 6.12 man page says: - * mktemp [OPTION]... [TEMPLATE] - * Create a temporary file or directory, safely, and print its name. If - * TEMPLATE is not specified, use tmp.XXXXXXXXXX. - * -d, --directory - * create a directory, not a file - * -q, --quiet - * suppress diagnostics about file/dir-creation failure - * -u, --dry-run - * do not create anything; merely print a name (unsafe) - * --tmpdir[=DIR] - * interpret TEMPLATE relative to DIR. If DIR is not specified, - * use $TMPDIR if set, else /tmp. With this option, TEMPLATE must - * not be an absolute name. Unlike with -t, TEMPLATE may contain - * slashes, but even here, mktemp still creates only the final com- - * ponent. - * -p DIR use DIR as a prefix; implies -t [deprecated] - * -t interpret TEMPLATE as a single file name component, relative to - * a directory: $TMPDIR, if set; else the directory specified via - * -p; else /tmp [deprecated] - */ -//config:config MKTEMP -//config: bool "mktemp" -//config: default y -//config: help -//config: mktemp is used to create unique temporary files - -//applet:IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o - -//usage:#define mktemp_trivial_usage -//usage: "[-dt] [-p DIR] [TEMPLATE]" -//usage:#define mktemp_full_usage "\n\n" -//usage: "Create a temporary file with name based on TEMPLATE and print its name.\n" -//usage: "TEMPLATE must end with XXXXXX (e.g. [/dir/]nameXXXXXX).\n" -//usage: "Without TEMPLATE, -t tmp.XXXXXX is assumed.\n" -//usage: "\n -d Make directory, not file" -//usage: "\n -q Fail silently on errors" -//usage: "\n -t Prepend base directory name to TEMPLATE" -//usage: "\n -p DIR Use DIR as a base directory (implies -t)" -//usage: "\n -u Do not create anything; print a name" -//usage: "\n" -//usage: "\nBase directory is: -p DIR, else $TMPDIR, else /tmp" -//usage: -//usage:#define mktemp_example_usage -//usage: "$ mktemp /tmp/temp.XXXXXX\n" -//usage: "/tmp/temp.mWiLjM\n" -//usage: "$ ls -la /tmp/temp.mWiLjM\n" -//usage: "-rw------- 1 andersen andersen 0 Apr 25 17:10 /tmp/temp.mWiLjM\n" - -#include "libbb.h" - -int mktemp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int mktemp_main(int argc UNUSED_PARAM, char **argv) -{ - const char *path; - char *chp; - unsigned opts; - enum { - OPT_d = 1 << 0, - OPT_q = 1 << 1, - OPT_t = 1 << 2, - OPT_p = 1 << 3, - OPT_u = 1 << 4, - }; - - path = getenv("TMPDIR"); - if (!path || path[0] == '\0') - path = "/tmp"; - - opt_complementary = "?1"; /* 1 argument max */ - opts = getopt32(argv, "dqtp:u", &path); - - chp = argv[optind]; - if (!chp) { - /* GNU coreutils 8.4: - * bare "mktemp" -> "mktemp -t tmp.XXXXXX" - */ - chp = xstrdup("tmp.XXXXXX"); - opts |= OPT_t; - } -#if 0 - /* Don't allow directory separator in template */ - if ((opts & OPT_t) && bb_basename(chp) != chp) { - errno = EINVAL; - goto error; - } -#endif - if (opts & (OPT_t|OPT_p)) - chp = concat_path_file(path, chp); - - if (opts & OPT_u) { - chp = mktemp(chp); - if (chp[0] == '\0') - goto error; - } else if (opts & OPT_d) { - if (mkdtemp(chp) == NULL) - goto error; - } else { - if (mkstemp(chp) < 0) - goto error; - } - puts(chp); - return EXIT_SUCCESS; - error: - if (opts & OPT_q) - return EXIT_FAILURE; - /* don't use chp as it gets mangled in case of error */ - bb_perror_nomsg_and_die(); -} diff --git a/init/mesg.c b/init/mesg.c deleted file mode 100644 index 45c13b8e0..000000000 --- a/init/mesg.c +++ /dev/null @@ -1,76 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * mesg implementation for busybox - * - * Copyright (c) 2002 Manuel Novoa III - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -//config:config MESG -//config: bool "mesg" -//config: default y -//config: help -//config: Mesg controls access to your terminal by others. It is typically -//config: used to allow or disallow other users to write to your terminal -//config: -//config:config FEATURE_MESG_ENABLE_ONLY_GROUP -//config: bool "Enable writing to tty only by group, not by everybody" -//config: default y -//config: depends on MESG -//config: help -//config: Usually, ttys are owned by group "tty", and "write" tool is -//config: setgid to this group. This way, "mesg y" only needs to enable -//config: "write by owning group" bit in tty mode. -//config: -//config: If you set this option to N, "mesg y" will enable writing -//config: by anybody at all. This is not recommended. - -//applet:IF_MESG(APPLET(mesg, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_MESG) += mesg.o - -//usage:#define mesg_trivial_usage -//usage: "[y|n]" -//usage:#define mesg_full_usage "\n\n" -//usage: "Control write access to your terminal\n" -//usage: " y Allow write access to your terminal\n" -//usage: " n Disallow write access to your terminal" - -#include "libbb.h" - -#if ENABLE_FEATURE_MESG_ENABLE_ONLY_GROUP -#define S_IWGRP_OR_S_IWOTH S_IWGRP -#else -#define S_IWGRP_OR_S_IWOTH (S_IWGRP | S_IWOTH) -#endif - -int mesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int mesg_main(int argc UNUSED_PARAM, char **argv) -{ - struct stat sb; - mode_t m; - char c = 0; - - argv++; - - if (argv[0] - && (argv[1] || ((c = argv[0][0]) != 'y' && c != 'n')) - ) { - bb_show_usage(); - } - - if (!isatty(STDIN_FILENO)) - bb_error_msg_and_die("not a tty"); - - xfstat(STDIN_FILENO, &sb, "stderr"); - if (c == 0) { - puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); - return EXIT_SUCCESS; - } - m = (c == 'y') ? sb.st_mode | S_IWGRP_OR_S_IWOTH - : sb.st_mode & ~(S_IWGRP|S_IWOTH); - if (fchmod(STDIN_FILENO, m) != 0) - bb_perror_nomsg_and_die(); - return EXIT_SUCCESS; -} diff --git a/procps/renice.c b/procps/renice.c deleted file mode 100644 index 64213c680..000000000 --- a/procps/renice.c +++ /dev/null @@ -1,148 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * renice implementation for busybox - * - * Copyright (C) 2005 Manuel Novoa III - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -/* Notes: - * Setting an absolute priority was obsoleted in SUSv2 and removed - * in SUSv3. However, the common linux version of renice does - * absolute and not relative. So we'll continue supporting absolute, - * although the stdout logging has been removed since both SUSv2 and - * SUSv3 specify that stdout isn't used. - * - * This version is lenient in that it doesn't require any IDs. The - * options -p, -g, and -u are treated as mode switches for the - * following IDs (if any). Multiple switches are allowed. - */ -//config:config RENICE -//config: bool "renice" -//config: default y -//config: help -//config: Renice alters the scheduling priority of one or more running -//config: processes. - -//applet:IF_RENICE(APPLET(renice, BB_DIR_USR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_RENICE) += renice.o - -//usage:#define renice_trivial_usage -//usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." -//usage:#define renice_full_usage "\n\n" -//usage: "Change scheduling priority of a running process\n" -//usage: "\n -n Add PRIORITY to current nice value" -//usage: "\n Without -n, nice value is set to PRIORITY" -//usage: "\n -p Process ids (default)" -//usage: "\n -g Process group ids" -//usage: "\n -u Process user names" - -#include "libbb.h" -#include - -void BUG_bad_PRIO_PROCESS(void); -void BUG_bad_PRIO_PGRP(void); -void BUG_bad_PRIO_USER(void); - -int renice_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int renice_main(int argc UNUSED_PARAM, char **argv) -{ - static const char Xetpriority_msg[] ALIGN1 = "%cetpriority"; - - int retval = EXIT_SUCCESS; - int which = PRIO_PROCESS; /* Default 'which' value. */ - int use_relative = 0; - int adjustment, new_priority; - unsigned who; - char *arg; - - /* Yes, they are not #defines in glibc 2.4! #if won't work */ - if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX) - BUG_bad_PRIO_PROCESS(); - if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX) - BUG_bad_PRIO_PGRP(); - if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX) - BUG_bad_PRIO_USER(); - - arg = *++argv; - - /* Check if we are using a relative adjustment. */ - if (arg && arg[0] == '-' && arg[1] == 'n') { - use_relative = 1; - if (!arg[2]) - arg = *++argv; - else - arg += 2; - } - - if (!arg) { /* No args? Then show usage. */ - bb_show_usage(); - } - - /* Get the priority adjustment (absolute or relative). */ - adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2); - - while ((arg = *++argv) != NULL) { - /* Check for a mode switch. */ - if (arg[0] == '-' && arg[1]) { - static const char opts[] ALIGN1 = { - 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER - }; - const char *p = strchr(opts, arg[1]); - if (p) { - which = p[4]; - if (!arg[2]) - continue; - arg += 2; - } - } - - /* Process an ID arg. */ - if (which == PRIO_USER) { - struct passwd *p; - p = getpwnam(arg); - if (!p) { - bb_error_msg("unknown user %s", arg); - goto HAD_ERROR; - } - who = p->pw_uid; - } else { - who = bb_strtou(arg, NULL, 10); - if (errno) { - bb_error_msg("invalid number '%s'", arg); - goto HAD_ERROR; - } - } - - /* Get priority to use, and set it. */ - if (use_relative) { - int old_priority; - - errno = 0; /* Needed for getpriority error detection. */ - old_priority = getpriority(which, who); - if (errno) { - bb_perror_msg(Xetpriority_msg, 'g'); - goto HAD_ERROR; - } - - new_priority = old_priority + adjustment; - } else { - new_priority = adjustment; - } - - if (setpriority(which, who, new_priority) == 0) { - continue; - } - - bb_perror_msg(Xetpriority_msg, 's'); - HAD_ERROR: - retval = EXIT_FAILURE; - } - - /* No need to check for errors outputing to stderr since, if it - * was used, the HAD_ERROR label was reached and retval was set. */ - - return retval; -} diff --git a/util-linux/cal.c b/util-linux/cal.c new file mode 100644 index 000000000..af02608f0 --- /dev/null +++ b/util-linux/cal.c @@ -0,0 +1,390 @@ +/* vi: set sw=4 ts=4: */ +/* + * Calendar implementation for busybox + * + * See original copyright at the end of this file + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) + * + * Major size reduction... over 50% (>1.5k) on i386. + */ +//config:config CAL +//config: bool "cal" +//config: default y +//config: help +//config: cal is used to display a monthly calendar. + +//applet:IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CAL) += cal.o + +/* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ +/* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream + * BB_AUDIT BUG: version in util-linux seems to be broken as well. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ + +//usage:#define cal_trivial_usage +//usage: "[-jy] [[MONTH] YEAR]" +//usage:#define cal_full_usage "\n\n" +//usage: "Display a calendar\n" +//usage: "\n -j Use julian dates" +//usage: "\n -y Display the entire year" + +#include "libbb.h" +#include "unicode.h" + +/* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ + +#define THURSDAY 4 /* for reformation */ +#define SATURDAY 6 /* 1 Jan 1 was a Saturday */ + +#define FIRST_MISSING_DAY 639787 /* 3 Sep 1752 */ +#define NUMBER_MISSING_DAYS 11 /* 11 day correction */ + +#define MAXDAYS 42 /* max slots in a month array */ +#define SPACE -1 /* used in day array */ + +static const unsigned char days_in_month[] ALIGN1 = { + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +static const unsigned char sep1752[] ALIGN1 = { + 1, 2, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30 +}; + +/* Set to 0 or 1 in main */ +#define julian ((unsigned)option_mask32) + +/* leap year -- account for Gregorian reformation in 1752 */ +static int leap_year(unsigned yr) +{ + if (yr <= 1752) + return !(yr % 4); + return (!(yr % 4) && (yr % 100)) || !(yr % 400); +} + +/* number of centuries since 1700, not inclusive */ +#define centuries_since_1700(yr) \ + ((yr) > 1700 ? (yr) / 100 - 17 : 0) + +/* number of centuries since 1700 whose modulo of 400 is 0 */ +#define quad_centuries_since_1700(yr) \ + ((yr) > 1600 ? ((yr) - 1600) / 400 : 0) + +/* number of leap years between year 1 and this year, not inclusive */ +#define leap_years_since_year_1(yr) \ + ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) + +static void center(char *, unsigned, unsigned); +static void day_array(unsigned, unsigned, unsigned *); +static void trim_trailing_spaces_and_print(char *); + +static void blank_string(char *buf, size_t buflen); +static char *build_row(char *p, unsigned *dp); + +#define DAY_LEN 3 /* 3 spaces per day */ +#define J_DAY_LEN (DAY_LEN + 1) +#define WEEK_LEN 20 /* 7 * 3 - one space at the end */ +#define J_WEEK_LEN (WEEK_LEN + 7) +#define HEAD_SEP 2 /* spaces between day headings */ + +int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int cal_main(int argc UNUSED_PARAM, char **argv) +{ + struct tm zero_tm; + time_t now; + unsigned month, year, flags, i; + char *month_names[12]; + /* normal heading: */ + /* "Su Mo Tu We Th Fr Sa" */ + /* -j heading: */ + /* " Su Mo Tu We Th Fr Sa" */ + char day_headings[ENABLE_UNICODE_SUPPORT ? 28 * 6 : 28]; + IF_UNICODE_SUPPORT(char *hp = day_headings;) + char buf[40]; + + init_unicode(); + + flags = getopt32(argv, "jy"); + /* This sets julian = flags & 1: */ + option_mask32 &= 1; + month = 0; + argv += optind; + + if (!argv[0]) { + struct tm *ptm; + + time(&now); + ptm = localtime(&now); + year = ptm->tm_year + 1900; + if (!(flags & 2)) { /* no -y */ + month = ptm->tm_mon + 1; + } + } else { + if (argv[1]) { + if (argv[2]) { + bb_show_usage(); + } + if (!(flags & 2)) { /* no -y */ + month = xatou_range(*argv, 1, 12); + } + argv++; + } + year = xatou_range(*argv, 1, 9999); + } + + blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); + + i = 0; + do { + zero_tm.tm_mon = i; + /* full month name according to locale */ + strftime(buf, sizeof(buf), "%B", &zero_tm); + month_names[i] = xstrdup(buf); + + if (i < 7) { + zero_tm.tm_wday = i; + /* abbreviated weekday name according to locale */ + strftime(buf, sizeof(buf), "%a", &zero_tm); +#if ENABLE_UNICODE_SUPPORT + if (julian) + *hp++ = ' '; + { + char *two_wchars = unicode_conv_to_printable_fixedwidth(/*NULL,*/ buf, 2); + strcpy(hp, two_wchars); + free(two_wchars); + } + hp += strlen(hp); + *hp++ = ' '; +#else + strncpy(day_headings + i * (3+julian) + julian, buf, 2); +#endif + } + } while (++i < 12); + IF_UNICODE_SUPPORT(hp[-1] = '\0';) + + if (month) { + unsigned row, len, days[MAXDAYS]; + unsigned *dp = days; + char lineout[30]; + + day_array(month, year, dp); + len = sprintf(lineout, "%s %u", month_names[month - 1], year); + 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 { + unsigned row, which_cal, week_len, days[12][MAXDAYS]; + unsigned *dp; + char lineout[80]; + + sprintf(lineout, "%u", 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); + printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); + if (!julian) { + printf("%*s%s", HEAD_SEP, "", day_headings); + } + bb_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); + } + } + } + + fflush_stdout_and_exit(EXIT_SUCCESS); +} + +/* + * day_array -- + * Fill in an array of 42 integers with a calendar. Assume for a moment + * that you took the (maximum) 6 rows in a calendar and stretched them + * out end to end. You would have 42 numbers or spaces. This routine + * builds that array for any month from Jan. 1 through Dec. 9999. + */ +static void day_array(unsigned month, unsigned year, unsigned *days) +{ + unsigned long temp; + unsigned i; + unsigned day, dw, dm; + + memset(days, SPACE, MAXDAYS * sizeof(int)); + + if ((month == 9) && (year == 1752)) { + /* Assumes the Gregorian reformation eliminates + * 3 Sep. 1752 through 13 Sep. 1752. + */ + unsigned j_offset = julian * 244; + size_t oday = 0; + + do { + days[oday+2] = sep1752[oday] + j_offset; + } while (++oday < sizeof(sep1752)); + + return; + } + + /* day_in_year + * return the 1 based day number within the year + */ + day = 1; + if ((month > 2) && leap_year(year)) { + ++day; + } + + i = month; + while (i) { + day += days_in_month[--i]; + } + + /* day_in_week + * return the 0 based day number for any date from 1 Jan. 1 to + * 31 Dec. 9999. Assumes the Gregorian reformation eliminates + * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all + * missing days. + */ + temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day; + if (temp < FIRST_MISSING_DAY) { + dw = ((temp - 1 + SATURDAY) % 7); + } else { + dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); + } + + if (!julian) { + day = 1; + } + + dm = days_in_month[month]; + if ((month == 2) && leap_year(year)) { + ++dm; + } + + do { + days[dw++] = day++; + } while (--dm); +} + +static void trim_trailing_spaces_and_print(char *s) +{ + char *p = s; + + while (*p) { + ++p; + } + while (p != s) { + --p; + if (!isspace(*p)) { + p[1] = '\0'; + break; + } + } + + puts(s); +} + +static void center(char *str, unsigned len, unsigned separate) +{ + unsigned n = strlen(str); + len -= n; + printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, ""); +} + +static void blank_string(char *buf, size_t buflen) +{ + memset(buf, ' ', buflen); + buf[buflen-1] = '\0'; +} + +static char *build_row(char *p, unsigned *dp) +{ + unsigned col, val, day; + + memset(p, ' ', (julian + DAY_LEN) * 7); + + col = 0; + do { + day = *dp++; + if (day != SPACE) { + if (julian) { + ++p; + if (day >= 100) { + *p = '0'; + p[-1] = (day / 100) + '0'; + day %= 100; + } + } + val = day / 10; + if (val > 0) { + *p = val + '0'; + } + *++p = day % 10 + '0'; + p += 2; + } else { + p += DAY_LEN + julian; + } + } while (++col < 7); + + return p; +} + +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Kim Letkeman. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff --git a/util-linux/mesg.c b/util-linux/mesg.c new file mode 100644 index 000000000..45c13b8e0 --- /dev/null +++ b/util-linux/mesg.c @@ -0,0 +1,76 @@ +/* vi: set sw=4 ts=4: */ +/* + * mesg implementation for busybox + * + * Copyright (c) 2002 Manuel Novoa III + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config MESG +//config: bool "mesg" +//config: default y +//config: help +//config: Mesg controls access to your terminal by others. It is typically +//config: used to allow or disallow other users to write to your terminal +//config: +//config:config FEATURE_MESG_ENABLE_ONLY_GROUP +//config: bool "Enable writing to tty only by group, not by everybody" +//config: default y +//config: depends on MESG +//config: help +//config: Usually, ttys are owned by group "tty", and "write" tool is +//config: setgid to this group. This way, "mesg y" only needs to enable +//config: "write by owning group" bit in tty mode. +//config: +//config: If you set this option to N, "mesg y" will enable writing +//config: by anybody at all. This is not recommended. + +//applet:IF_MESG(APPLET(mesg, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MESG) += mesg.o + +//usage:#define mesg_trivial_usage +//usage: "[y|n]" +//usage:#define mesg_full_usage "\n\n" +//usage: "Control write access to your terminal\n" +//usage: " y Allow write access to your terminal\n" +//usage: " n Disallow write access to your terminal" + +#include "libbb.h" + +#if ENABLE_FEATURE_MESG_ENABLE_ONLY_GROUP +#define S_IWGRP_OR_S_IWOTH S_IWGRP +#else +#define S_IWGRP_OR_S_IWOTH (S_IWGRP | S_IWOTH) +#endif + +int mesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int mesg_main(int argc UNUSED_PARAM, char **argv) +{ + struct stat sb; + mode_t m; + char c = 0; + + argv++; + + if (argv[0] + && (argv[1] || ((c = argv[0][0]) != 'y' && c != 'n')) + ) { + bb_show_usage(); + } + + if (!isatty(STDIN_FILENO)) + bb_error_msg_and_die("not a tty"); + + xfstat(STDIN_FILENO, &sb, "stderr"); + if (c == 0) { + puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); + return EXIT_SUCCESS; + } + m = (c == 'y') ? sb.st_mode | S_IWGRP_OR_S_IWOTH + : sb.st_mode & ~(S_IWGRP|S_IWOTH); + if (fchmod(STDIN_FILENO, m) != 0) + bb_perror_nomsg_and_die(); + return EXIT_SUCCESS; +} diff --git a/util-linux/renice.c b/util-linux/renice.c new file mode 100644 index 000000000..64213c680 --- /dev/null +++ b/util-linux/renice.c @@ -0,0 +1,148 @@ +/* vi: set sw=4 ts=4: */ +/* + * renice implementation for busybox + * + * Copyright (C) 2005 Manuel Novoa III + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +/* Notes: + * Setting an absolute priority was obsoleted in SUSv2 and removed + * in SUSv3. However, the common linux version of renice does + * absolute and not relative. So we'll continue supporting absolute, + * although the stdout logging has been removed since both SUSv2 and + * SUSv3 specify that stdout isn't used. + * + * This version is lenient in that it doesn't require any IDs. The + * options -p, -g, and -u are treated as mode switches for the + * following IDs (if any). Multiple switches are allowed. + */ +//config:config RENICE +//config: bool "renice" +//config: default y +//config: help +//config: Renice alters the scheduling priority of one or more running +//config: processes. + +//applet:IF_RENICE(APPLET(renice, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_RENICE) += renice.o + +//usage:#define renice_trivial_usage +//usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." +//usage:#define renice_full_usage "\n\n" +//usage: "Change scheduling priority of a running process\n" +//usage: "\n -n Add PRIORITY to current nice value" +//usage: "\n Without -n, nice value is set to PRIORITY" +//usage: "\n -p Process ids (default)" +//usage: "\n -g Process group ids" +//usage: "\n -u Process user names" + +#include "libbb.h" +#include + +void BUG_bad_PRIO_PROCESS(void); +void BUG_bad_PRIO_PGRP(void); +void BUG_bad_PRIO_USER(void); + +int renice_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int renice_main(int argc UNUSED_PARAM, char **argv) +{ + static const char Xetpriority_msg[] ALIGN1 = "%cetpriority"; + + int retval = EXIT_SUCCESS; + int which = PRIO_PROCESS; /* Default 'which' value. */ + int use_relative = 0; + int adjustment, new_priority; + unsigned who; + char *arg; + + /* Yes, they are not #defines in glibc 2.4! #if won't work */ + if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX) + BUG_bad_PRIO_PROCESS(); + if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX) + BUG_bad_PRIO_PGRP(); + if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX) + BUG_bad_PRIO_USER(); + + arg = *++argv; + + /* Check if we are using a relative adjustment. */ + if (arg && arg[0] == '-' && arg[1] == 'n') { + use_relative = 1; + if (!arg[2]) + arg = *++argv; + else + arg += 2; + } + + if (!arg) { /* No args? Then show usage. */ + bb_show_usage(); + } + + /* Get the priority adjustment (absolute or relative). */ + adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2); + + while ((arg = *++argv) != NULL) { + /* Check for a mode switch. */ + if (arg[0] == '-' && arg[1]) { + static const char opts[] ALIGN1 = { + 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER + }; + const char *p = strchr(opts, arg[1]); + if (p) { + which = p[4]; + if (!arg[2]) + continue; + arg += 2; + } + } + + /* Process an ID arg. */ + if (which == PRIO_USER) { + struct passwd *p; + p = getpwnam(arg); + if (!p) { + bb_error_msg("unknown user %s", arg); + goto HAD_ERROR; + } + who = p->pw_uid; + } else { + who = bb_strtou(arg, NULL, 10); + if (errno) { + bb_error_msg("invalid number '%s'", arg); + goto HAD_ERROR; + } + } + + /* Get priority to use, and set it. */ + if (use_relative) { + int old_priority; + + errno = 0; /* Needed for getpriority error detection. */ + old_priority = getpriority(which, who); + if (errno) { + bb_perror_msg(Xetpriority_msg, 'g'); + goto HAD_ERROR; + } + + new_priority = old_priority + adjustment; + } else { + new_priority = adjustment; + } + + if (setpriority(which, who, new_priority) == 0) { + continue; + } + + bb_perror_msg(Xetpriority_msg, 's'); + HAD_ERROR: + retval = EXIT_FAILURE; + } + + /* No need to check for errors outputing to stderr since, if it + * was used, the HAD_ERROR label was reached and retval was set. */ + + return retval; +}