Sort more misplaced applets into coreutils or util-linux
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Apr 2017 12:16:29 +0000 (14:16 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Apr 2017 12:16:29 +0000 (14:16 +0200)
No code changes

Surprisingly, nice and renice are coming from different packages :)

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
coreutils/cal.c [deleted file]
coreutils/mktemp.c [new file with mode: 0644]
debianutils/mktemp.c [deleted file]
init/mesg.c [deleted file]
procps/renice.c [deleted file]
util-linux/cal.c [new file with mode: 0644]
util-linux/mesg.c [new file with mode: 0644]
util-linux/renice.c [new file with mode: 0644]

diff --git a/coreutils/cal.c b/coreutils/cal.c
deleted file mode 100644 (file)
index af02608..0000000
+++ /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 (file)
index 0000000..6535369
--- /dev/null
@@ -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 <dan@debian.org>
+ *
+ * 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 (file)
index 6535369..0000000
+++ /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 <dan@debian.org>
- *
- * 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 (file)
index 45c13b8..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * mesg implementation for busybox
- *
- * Copyright (c) 2002 Manuel Novoa III  <mjn3@codepoet.org>
- *
- * 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 (file)
index 64213c6..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * renice implementation for busybox
- *
- * Copyright (C) 2005  Manuel Novoa III  <mjn3@codepoet.org>
- *
- * 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 <sys/resource.h>
-
-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 (file)
index 0000000..af02608
--- /dev/null
@@ -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 (file)
index 0000000..45c13b8
--- /dev/null
@@ -0,0 +1,76 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * mesg implementation for busybox
+ *
+ * Copyright (c) 2002 Manuel Novoa III  <mjn3@codepoet.org>
+ *
+ * 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 (file)
index 0000000..64213c6
--- /dev/null
@@ -0,0 +1,148 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * renice implementation for busybox
+ *
+ * Copyright (C) 2005  Manuel Novoa III  <mjn3@codepoet.org>
+ *
+ * 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 <sys/resource.h>
+
+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;
+}