aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2017-08-22 14:56:12 +0100
committerRon Yorston <rmy@pobox.com>2017-08-22 14:56:12 +0100
commitce9af1cc5ea23f754587448cf35b5120c77bfeef (patch)
tree69e5eaba5e75ab909ed92d5045393471b8ff3c13 /miscutils
parentc170026700eabb10147dd848c45c06995b43a32e (diff)
parente837a0dbbebf4229306df98fe9ee3b9bb30630c4 (diff)
downloadbusybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.tar.gz
busybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.tar.bz2
busybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/adjtimex.c39
-rw-r--r--miscutils/chat.c4
-rw-r--r--miscutils/conspy.c6
-rw-r--r--miscutils/crond.c14
-rw-r--r--miscutils/crontab.c5
-rw-r--r--miscutils/flash_eraseall.c4
-rw-r--r--miscutils/flash_lock_unlock.c1
-rw-r--r--miscutils/flashcp.c4
-rw-r--r--miscutils/i2c_tools.c26
-rw-r--r--miscutils/lsscsi.c5
-rw-r--r--miscutils/makedevs.c5
-rw-r--r--miscutils/man.c3
-rw-r--r--miscutils/microcom.c4
-rw-r--r--miscutils/nandwrite.c13
-rw-r--r--miscutils/partprobe.c2
-rw-r--r--miscutils/raidautorun.c2
-rw-r--r--miscutils/runlevel.c2
-rw-r--r--miscutils/setserial.c97
-rw-r--r--miscutils/time.c15
-rw-r--r--miscutils/ttysize.c2
-rw-r--r--miscutils/ubi_tools.c91
-rw-r--r--miscutils/ubirename.c6
-rw-r--r--miscutils/watchdog.c5
23 files changed, 197 insertions, 158 deletions
diff --git a/miscutils/adjtimex.c b/miscutils/adjtimex.c
index 04ba5636f..c1718e909 100644
--- a/miscutils/adjtimex.c
+++ b/miscutils/adjtimex.c
@@ -1,6 +1,6 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * adjtimex.c - read, and possibly modify, the Linux kernel `timex' variables. 3 * adjtimex.c - read, and possibly modify, the Linux kernel 'timex' variables.
4 * 4 *
5 * Originally written: October 1997 5 * Originally written: October 1997
6 * Last hack: March 2001 6 * Last hack: March 2001
@@ -18,7 +18,7 @@
18//config: Adjtimex reads and optionally sets adjustment parameters for 18//config: Adjtimex reads and optionally sets adjustment parameters for
19//config: the Linux clock adjustment algorithm. 19//config: the Linux clock adjustment algorithm.
20 20
21//applet:IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) 21//applet:IF_ADJTIMEX(APPLET_NOFORK(adjtimex, adjtimex, BB_DIR_SBIN, BB_SUID_DROP, adjtimex))
22 22
23//kbuild:lib-$(CONFIG_ADJTIMEX) += adjtimex.o 23//kbuild:lib-$(CONFIG_ADJTIMEX) += adjtimex.o
24 24
@@ -90,13 +90,15 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv)
90 unsigned opt; 90 unsigned opt;
91 char *opt_o, *opt_f, *opt_p, *opt_t; 91 char *opt_o, *opt_f, *opt_p, *opt_t;
92 struct timex txc; 92 struct timex txc;
93 int i, ret; 93 int ret;
94 const char *descript; 94 const char *descript;
95 95
96 opt_complementary = "=0"; /* no valid non-option parameters */ 96 memset(&txc, 0, sizeof(txc));
97 opt = getopt32(argv, "qo:f:p:t:", 97
98 &opt_o, &opt_f, &opt_p, &opt_t); 98 opt = getopt32(argv, "^" "qo:f:p:t:"
99 txc.modes = 0; 99 "\0" "=0"/*no valid non-option args*/,
100 &opt_o, &opt_f, &opt_p, &opt_t
101 );
100 //if (opt & 0x1) // -q 102 //if (opt & 0x1) // -q
101 if (opt & 0x2) { // -o 103 if (opt & 0x2) { // -o
102 txc.offset = xatol(opt_o); 104 txc.offset = xatol(opt_o);
@@ -115,15 +117,19 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv)
115 txc.modes |= ADJ_TICK; 117 txc.modes |= ADJ_TICK;
116 } 118 }
117 119
118 ret = adjtimex(&txc); 120 /* It's NOFORK applet because the code is very simple:
121 * just some printf. No opens, no allocs.
122 * If you need to make it more complex, feel free to downgrade to NOEXEC
123 */
119 124
120 if (ret < 0) { 125 ret = adjtimex(&txc);
126 if (ret < 0)
121 bb_perror_nomsg_and_die(); 127 bb_perror_nomsg_and_die();
122 }
123 128
124 if (!(opt & OPT_quiet)) { 129 if (!(opt & OPT_quiet)) {
125 const char *sep; 130 const char *sep;
126 const char *name; 131 const char *name;
132 int i;
127 133
128 printf( 134 printf(
129 " mode: %d\n" 135 " mode: %d\n"
@@ -132,8 +138,9 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv)
132 " maxerror: %ld\n" 138 " maxerror: %ld\n"
133 " esterror: %ld\n" 139 " esterror: %ld\n"
134 " status: %d (", 140 " status: %d (",
135 txc.modes, txc.offset, txc.freq, txc.maxerror, 141 txc.modes, txc.offset, txc.freq, txc.maxerror,
136 txc.esterror, txc.status); 142 txc.esterror, txc.status
143 );
137 144
138 /* representative output of next code fragment: 145 /* representative output of next code fragment:
139 * "PLL | PPSTIME" 146 * "PLL | PPSTIME"
@@ -159,9 +166,11 @@ int adjtimex_main(int argc UNUSED_PARAM, char **argv)
159 " time.tv_sec: %ld\n" 166 " time.tv_sec: %ld\n"
160 " time.tv_usec: %ld\n" 167 " time.tv_usec: %ld\n"
161 " return value: %d (%s)\n", 168 " return value: %d (%s)\n",
162 txc.constant, 169 txc.constant,
163 txc.precision, txc.tolerance, txc.tick, 170 txc.precision, txc.tolerance, txc.tick,
164 (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript); 171 (long)txc.time.tv_sec, (long)txc.time.tv_usec,
172 ret, descript
173 );
165 } 174 }
166 175
167 return 0; 176 return 0;
diff --git a/miscutils/chat.c b/miscutils/chat.c
index 216a899a0..1446a040c 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -82,8 +82,8 @@
82//usage: "EXPECT [SEND [EXPECT [SEND...]]]" 82//usage: "EXPECT [SEND [EXPECT [SEND...]]]"
83//usage:#define chat_full_usage "\n\n" 83//usage:#define chat_full_usage "\n\n"
84//usage: "Useful for interacting with a modem connected to stdin/stdout.\n" 84//usage: "Useful for interacting with a modem connected to stdin/stdout.\n"
85//usage: "A script consists of one or more \"expect-send\" pairs of strings,\n" 85//usage: "A script consists of \"expect-send\" argument pairs.\n"
86//usage: "each pair is a pair of arguments. Example:\n" 86//usage: "Example:\n"
87//usage: "chat '' ATZ OK ATD123456 CONNECT '' ogin: pppuser word: ppppass '~'" 87//usage: "chat '' ATZ OK ATD123456 CONNECT '' ogin: pppuser word: ppppass '~'"
88 88
89#include "libbb.h" 89#include "libbb.h"
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index 47b9e7207..a0e0d4e4b 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -367,7 +367,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
367 unsigned ttynum; 367 unsigned ttynum;
368 int poll_timeout_ms; 368 int poll_timeout_ms;
369#if ENABLE_LONG_OPTS 369#if ENABLE_LONG_OPTS
370 static const char getopt_longopts[] ALIGN1 = 370 static const char conspy_longopts[] ALIGN1 =
371 "viewonly\0" No_argument "v" 371 "viewonly\0" No_argument "v"
372 "createdevice\0" No_argument "c" 372 "createdevice\0" No_argument "c"
373 "neverquit\0" No_argument "Q" 373 "neverquit\0" No_argument "Q"
@@ -377,8 +377,6 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
377 "follow\0" No_argument "f" 377 "follow\0" No_argument "f"
378 "framebuffer\0" No_argument "F" 378 "framebuffer\0" No_argument "F"
379 ; 379 ;
380
381 applet_long_options = getopt_longopts;
382#endif 380#endif
383#define keybuf bb_common_bufsiz1 381#define keybuf bb_common_bufsiz1
384 setup_common_bufsiz(); 382 setup_common_bufsiz();
@@ -387,7 +385,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
387 strcpy(G.vcsa_name, DEV_VCSA); 385 strcpy(G.vcsa_name, DEV_VCSA);
388 386
389 // numeric params 387 // numeric params
390 opts = getopt32(argv, "vcQsndfFx:+y:+", &G.x, &G.y); 388 opts = getopt32long(argv, "vcQsndfFx:+y:+", conspy_longopts, &G.x, &G.y);
391 argv += optind; 389 argv += optind;
392 ttynum = 0; 390 ttynum = 0;
393 if (argv[0]) { 391 if (argv[0]) {
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 48e429976..f6580a9d4 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -1021,13 +1021,17 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
1021 1021
1022 INIT_G(); 1022 INIT_G();
1023 1023
1024 /* "-b after -f is ignored", and so on for every pair a-b */ 1024 opts = getopt32(argv, "^"
1025 opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") 1025 "l:L:fbSc:" IF_FEATURE_CROND_D("d:")
1026 "\0"
1027 /* "-b after -f is ignored", and so on for every pair a-b */
1028 "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l")
1026 /* -l and -d have numeric param */ 1029 /* -l and -d have numeric param */
1027 ":l+" IF_FEATURE_CROND_D(":d+"); 1030 ":l+" IF_FEATURE_CROND_D(":d+")
1028 opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), 1031 ,
1029 &G.log_level, &G.log_filename, &G.crontab_dir_name 1032 &G.log_level, &G.log_filename, &G.crontab_dir_name
1030 IF_FEATURE_CROND_D(,&G.log_level)); 1033 IF_FEATURE_CROND_D(,&G.log_level)
1034 );
1031 /* both -d N and -l N set the same variable: G.log_level */ 1035 /* both -d N and -l N set the same variable: G.log_level */
1032 1036
1033 if (!(opts & OPT_f)) { 1037 if (!(opts & OPT_f)) {
diff --git a/miscutils/crontab.c b/miscutils/crontab.c
index 804cb57f2..4787fa08f 100644
--- a/miscutils/crontab.c
+++ b/miscutils/crontab.c
@@ -99,8 +99,9 @@ int crontab_main(int argc UNUSED_PARAM, char **argv)
99 OPT_ler = OPT_l + OPT_e + OPT_r, 99 OPT_ler = OPT_l + OPT_e + OPT_r,
100 }; 100 };
101 101
102 opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ 102 opt_ler = getopt32(argv, "^" "u:c:lerd" "\0" "?1:dr"/*max one arg; -d implies -r*/,
103 opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); 103 &user_name, &crontab_dir
104 );
104 argv += optind; 105 argv += optind;
105 106
106 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ 107 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c
index af9ebea24..a6ce41f27 100644
--- a/miscutils/flash_eraseall.c
+++ b/miscutils/flash_eraseall.c
@@ -17,6 +17,7 @@
17//config: This utility is used to erase the whole MTD device. 17//config: This utility is used to erase the whole MTD device.
18 18
19//applet:IF_FLASH_ERASEALL(APPLET(flash_eraseall, BB_DIR_USR_SBIN, BB_SUID_DROP)) 19//applet:IF_FLASH_ERASEALL(APPLET(flash_eraseall, BB_DIR_USR_SBIN, BB_SUID_DROP))
20/* not NOEXEC: if flash operation stalls, use less memory in "hung" process */
20 21
21//kbuild:lib-$(CONFIG_FLASH_ERASEALL) += flash_eraseall.o 22//kbuild:lib-$(CONFIG_FLASH_ERASEALL) += flash_eraseall.o
22 23
@@ -81,8 +82,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
81 unsigned int flags; 82 unsigned int flags;
82 char *mtd_name; 83 char *mtd_name;
83 84
84 opt_complementary = "=1"; 85 flags = getopt32(argv, "^" "jNq" "\0" "=1");
85 flags = getopt32(argv, "jNq");
86 86
87 mtd_name = argv[optind]; 87 mtd_name = argv[optind];
88 fd = xopen(mtd_name, O_RDWR); 88 fd = xopen(mtd_name, O_RDWR);
diff --git a/miscutils/flash_lock_unlock.c b/miscutils/flash_lock_unlock.c
index 374eed5f6..6f2c049f4 100644
--- a/miscutils/flash_lock_unlock.c
+++ b/miscutils/flash_lock_unlock.c
@@ -20,6 +20,7 @@
20// APPLET_ODDNAME:name main location suid_type help 20// APPLET_ODDNAME:name main location suid_type help
21//applet:IF_FLASH_LOCK( APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock)) 21//applet:IF_FLASH_LOCK( APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock))
22//applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock)) 22//applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock))
23/* not NOEXEC: if flash operation stalls, use less memory in "hung" process */
23 24
24//kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o 25//kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o
25//kbuild:lib-$(CONFIG_FLASH_UNLOCK) += flash_lock_unlock.o 26//kbuild:lib-$(CONFIG_FLASH_UNLOCK) += flash_lock_unlock.o
diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c
index d4ac62df4..858cee194 100644
--- a/miscutils/flashcp.c
+++ b/miscutils/flashcp.c
@@ -14,6 +14,7 @@
14//config: This utility is used to copy images into a MTD device. 14//config: This utility is used to copy images into a MTD device.
15 15
16//applet:IF_FLASHCP(APPLET(flashcp, BB_DIR_USR_SBIN, BB_SUID_DROP)) 16//applet:IF_FLASHCP(APPLET(flashcp, BB_DIR_USR_SBIN, BB_SUID_DROP))
17/* not NOEXEC: if flash operation stalls, use less memory in "hung" process */
17 18
18//kbuild:lib-$(CONFIG_FLASHCP) += flashcp.o 19//kbuild:lib-$(CONFIG_FLASHCP) += flashcp.o
19 20
@@ -68,8 +69,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv)
68 RESERVE_CONFIG_UBUFFER(buf, BUFSIZE); 69 RESERVE_CONFIG_UBUFFER(buf, BUFSIZE);
69 RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE); 70 RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE);
70 71
71 opt_complementary = "=2"; /* exactly 2 non-option args: file, dev */ 72 /*opts =*/ getopt32(argv, "^" "v" "\0" "=2"/*exactly 2 non-option args: file,dev*/);
72 /*opts =*/ getopt32(argv, "v");
73 argv += optind; 73 argv += optind;
74// filename = *argv++; 74// filename = *argv++;
75// devicename = *argv; 75// devicename = *argv;
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index ca2580e92..30f606e8e 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -42,6 +42,7 @@
42//applet:IF_I2CSET(APPLET(i2cset, BB_DIR_USR_SBIN, BB_SUID_DROP)) 42//applet:IF_I2CSET(APPLET(i2cset, BB_DIR_USR_SBIN, BB_SUID_DROP))
43//applet:IF_I2CDUMP(APPLET(i2cdump, BB_DIR_USR_SBIN, BB_SUID_DROP)) 43//applet:IF_I2CDUMP(APPLET(i2cdump, BB_DIR_USR_SBIN, BB_SUID_DROP))
44//applet:IF_I2CDETECT(APPLET(i2cdetect, BB_DIR_USR_SBIN, BB_SUID_DROP)) 44//applet:IF_I2CDETECT(APPLET(i2cdetect, BB_DIR_USR_SBIN, BB_SUID_DROP))
45/* not NOEXEC: if hw operation stalls, use less memory in "hung" process */
45 46
46//kbuild:lib-$(CONFIG_I2CGET) += i2c_tools.o 47//kbuild:lib-$(CONFIG_I2CGET) += i2c_tools.o
47//kbuild:lib-$(CONFIG_I2CSET) += i2c_tools.o 48//kbuild:lib-$(CONFIG_I2CSET) += i2c_tools.o
@@ -454,14 +455,12 @@ int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
454int i2cget_main(int argc UNUSED_PARAM, char **argv) 455int i2cget_main(int argc UNUSED_PARAM, char **argv)
455{ 456{
456 const unsigned opt_f = (1 << 0), opt_y = (1 << 1); 457 const unsigned opt_f = (1 << 0), opt_y = (1 << 1);
457 const char *const optstr = "fy";
458 458
459 int bus_num, bus_addr, data_addr = -1, status; 459 int bus_num, bus_addr, data_addr = -1, status;
460 int mode = I2C_SMBUS_BYTE, pec = 0, fd; 460 int mode = I2C_SMBUS_BYTE, pec = 0, fd;
461 unsigned opts; 461 unsigned opts;
462 462
463 opt_complementary = "-2:?4"; /* from 2 to 4 args */ 463 opts = getopt32(argv, "^" "fy" "\0" "-2:?4"/*from 2 to 4 args*/);
464 opts = getopt32(argv, optstr);
465 argv += optind; 464 argv += optind;
466 465
467 bus_num = i2c_bus_lookup(argv[0]); 466 bus_num = i2c_bus_lookup(argv[0]);
@@ -543,7 +542,6 @@ int i2cset_main(int argc, char **argv)
543{ 542{
544 const unsigned opt_f = (1 << 0), opt_y = (1 << 1), 543 const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
545 opt_m = (1 << 2), opt_r = (1 << 3); 544 opt_m = (1 << 2), opt_r = (1 << 3);
546 const char *const optstr = "fym:r";
547 545
548 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0; 546 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
549 int val, blen = 0, mask = 0, fd, status; 547 int val, blen = 0, mask = 0, fd, status;
@@ -551,8 +549,7 @@ int i2cset_main(int argc, char **argv)
551 char *opt_m_arg = NULL; 549 char *opt_m_arg = NULL;
552 unsigned opts; 550 unsigned opts;
553 551
554 opt_complementary = "-3"; /* from 3 to ? args */ 552 opts = getopt32(argv, "^" "fym:r" "\0" "-3"/*from 3 to ? args*/, &opt_m_arg);
555 opts = getopt32(argv, optstr, &opt_m_arg);
556 argv += optind; 553 argv += optind;
557 argc -= optind; 554 argc -= optind;
558 555
@@ -904,7 +901,6 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
904{ 901{
905 const unsigned opt_f = (1 << 0), opt_y = (1 << 1), 902 const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
906 opt_r = (1 << 2); 903 opt_r = (1 << 2);
907 const char *const optstr = "fyr:";
908 904
909 int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0; 905 int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0;
910 unsigned first = 0x00, last = 0xff, opts; 906 unsigned first = 0x00, last = 0xff, opts;
@@ -912,8 +908,11 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
912 char *opt_r_str, *dash; 908 char *opt_r_str, *dash;
913 int fd, res; 909 int fd, res;
914 910
915 opt_complementary = "-2:?3"; /* from 2 to 3 args */ 911 opts = getopt32(argv, "^"
916 opts = getopt32(argv, optstr, &opt_r_str); 912 "fyr:"
913 "\0" "-2:?3" /* from 2 to 3 args */,
914 &opt_r_str
915 );
917 argv += optind; 916 argv += optind;
918 917
919 bus_num = i2c_bus_lookup(argv[0]); 918 bus_num = i2c_bus_lookup(argv[0]);
@@ -1207,15 +1206,16 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv)
1207 const unsigned opt_y = (1 << 0), opt_a = (1 << 1), 1206 const unsigned opt_y = (1 << 0), opt_a = (1 << 1),
1208 opt_q = (1 << 2), opt_r = (1 << 3), 1207 opt_q = (1 << 2), opt_r = (1 << 3),
1209 opt_F = (1 << 4), opt_l = (1 << 5); 1208 opt_F = (1 << 4), opt_l = (1 << 5);
1210 const char *const optstr = "yaqrFl";
1211 1209
1212 int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd; 1210 int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd;
1213 unsigned first = 0x03, last = 0x77, opts; 1211 unsigned first = 0x03, last = 0x77, opts;
1214 unsigned long funcs; 1212 unsigned long funcs;
1215 1213
1216 opt_complementary = "q--r:r--q:" /* mutually exclusive */ 1214 opts = getopt32(argv, "^"
1217 "?3"; /* up to 3 args */ 1215 "yaqrFl"
1218 opts = getopt32(argv, optstr); 1216 "\0"
1217 "q--r:r--q:"/*mutually exclusive*/ "?3"/*up to 3 args*/
1218 );
1219 argv += optind; 1219 argv += optind;
1220 1220
1221 if (opts & opt_l) 1221 if (opts & opt_l)
diff --git a/miscutils/lsscsi.c b/miscutils/lsscsi.c
index b69ff1eef..d7cd51056 100644
--- a/miscutils/lsscsi.c
+++ b/miscutils/lsscsi.c
@@ -16,7 +16,7 @@
16//config: 16//config:
17//config: This version uses sysfs (/sys/bus/scsi/devices) only. 17//config: This version uses sysfs (/sys/bus/scsi/devices) only.
18 18
19//applet:IF_LSSCSI(APPLET(lsscsi, BB_DIR_USR_BIN, BB_SUID_DROP)) 19//applet:IF_LSSCSI(APPLET_NOEXEC(lsscsi, lsscsi, BB_DIR_USR_BIN, BB_SUID_DROP, lsscsi))
20 20
21//kbuild:lib-$(CONFIG_LSSCSI) += lsscsi.o 21//kbuild:lib-$(CONFIG_LSSCSI) += lsscsi.o
22 22
@@ -37,9 +37,8 @@ static char *get_line(const char *filename, char *buf, unsigned *bufsize_p)
37 if (sz < 0) 37 if (sz < 0)
38 sz = 0; 38 sz = 0;
39 buf[sz] = '\0'; 39 buf[sz] = '\0';
40 trim(buf);
41 40
42 sz = strlen(buf) + 1; 41 sz = (trim(buf) - buf) + 1;
43 bufsize -= sz; 42 bufsize -= sz;
44 buf += sz; 43 buf += sz;
45 buf[0] = '\0'; 44 buf[0] = '\0';
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index c2f86df01..80975c652 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -38,7 +38,7 @@
38//config: 38//config:
39//config:endchoice 39//config:endchoice
40 40
41//applet:IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) 41//applet:IF_MAKEDEVS(APPLET_NOEXEC(makedevs, makedevs, BB_DIR_SBIN, BB_SUID_DROP, makedevs))
42 42
43//kbuild:lib-$(CONFIG_MAKEDEVS) += makedevs.o 43//kbuild:lib-$(CONFIG_MAKEDEVS) += makedevs.o
44 44
@@ -183,8 +183,7 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv)
183 char *line = (char *)"-"; 183 char *line = (char *)"-";
184 int ret = EXIT_SUCCESS; 184 int ret = EXIT_SUCCESS;
185 185
186 opt_complementary = "=1"; /* exactly one param */ 186 getopt32(argv, "^" "d:" "\0" "=1", &line);
187 getopt32(argv, "d:", &line);
188 argv += optind; 187 argv += optind;
189 188
190 xchdir(*argv); /* ensure root dir exists */ 189 xchdir(*argv); /* ensure root dir exists */
diff --git a/miscutils/man.c b/miscutils/man.c
index f68784767..68a75c6d7 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -257,8 +257,7 @@ int man_main(int argc UNUSED_PARAM, char **argv)
257 257
258 INIT_G(); 258 INIT_G();
259 259
260 opt_complementary = "-1"; /* at least one argument */ 260 opt = getopt32(argv, "^+" "aw" "\0" "-1"/*at least one arg*/);
261 opt = getopt32(argv, "+aw");
262 argv += optind; 261 argv += optind;
263 262
264 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); 263 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9");
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index 14b9f3baf..b87f3273f 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -74,7 +74,9 @@ int microcom_main(int argc UNUSED_PARAM, char **argv)
74 unsigned opts; 74 unsigned opts;
75 75
76 // fetch options 76 // fetch options
77 opts = getopt32(argv, "Xs:+d:+t:+", &speed, &delay, &timeout); 77 opts = getopt32(argv, "^" "Xs:+d:+t:+" "\0" "=1",
78 &speed, &delay, &timeout
79 );
78// argc -= optind; 80// argc -= optind;
79 argv += optind; 81 argv += optind;
80 82
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c
index 14b1ed056..80a005821 100644
--- a/miscutils/nandwrite.c
+++ b/miscutils/nandwrite.c
@@ -123,15 +123,12 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv)
123 const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb; 123 const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb;
124 124
125 if (IS_NANDDUMP) { 125 if (IS_NANDDUMP) {
126 opt_complementary = "=1"; 126 opts = getopt32long(argv, "^" "ons:f:l:" "\0" "=1",
127#if ENABLE_LONG_OPTS 127 "bb\0" Required_argument "\xff", /* no short equivalent */
128 applet_long_options = 128 &opt_s, &opt_f, &opt_l, &opt_bb
129 "bb\0" Required_argument "\xff"; /* no short equivalent */ 129 );
130#endif
131 opts = getopt32(argv, "ons:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb);
132 } else { /* nandwrite */ 130 } else { /* nandwrite */
133 opt_complementary = "-1:?2"; 131 opts = getopt32(argv, "^" "pns:" "\0" "-1:?2", &opt_s);
134 opts = getopt32(argv, "pns:", &opt_s);
135 } 132 }
136 argv += optind; 133 argv += optind;
137 134
diff --git a/miscutils/partprobe.c b/miscutils/partprobe.c
index 2c12a7d20..d1ae27348 100644
--- a/miscutils/partprobe.c
+++ b/miscutils/partprobe.c
@@ -11,7 +11,7 @@
11//config: help 11//config: help
12//config: Ask kernel to rescan partition table. 12//config: Ask kernel to rescan partition table.
13 13
14//applet:IF_PARTPROBE(APPLET(partprobe, BB_DIR_USR_SBIN, BB_SUID_DROP)) 14//applet:IF_PARTPROBE(APPLET_NOEXEC(partprobe, partprobe, BB_DIR_USR_SBIN, BB_SUID_DROP, partprobe))
15 15
16//kbuild:lib-$(CONFIG_PARTPROBE) += partprobe.o 16//kbuild:lib-$(CONFIG_PARTPROBE) += partprobe.o
17 17
diff --git a/miscutils/raidautorun.c b/miscutils/raidautorun.c
index ecedf9ce2..caf6e0821 100644
--- a/miscutils/raidautorun.c
+++ b/miscutils/raidautorun.c
@@ -15,7 +15,7 @@
15//config: raidautorun tells the kernel md driver to 15//config: raidautorun tells the kernel md driver to
16//config: search and start RAID arrays. 16//config: search and start RAID arrays.
17 17
18//applet:IF_RAIDAUTORUN(APPLET(raidautorun, BB_DIR_SBIN, BB_SUID_DROP)) 18//applet:IF_RAIDAUTORUN(APPLET_NOEXEC(raidautorun, raidautorun, BB_DIR_SBIN, BB_SUID_DROP, raidautorun))
19 19
20//kbuild:lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o 20//kbuild:lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o
21 21
diff --git a/miscutils/runlevel.c b/miscutils/runlevel.c
index 6b4742255..0b2098564 100644
--- a/miscutils/runlevel.c
+++ b/miscutils/runlevel.c
@@ -21,7 +21,7 @@
21//config: This applet uses utmp but does not rely on busybox supporing 21//config: This applet uses utmp but does not rely on busybox supporing
22//config: utmp on purpose. It is used by e.g. emdebian via /etc/init.d/rc. 22//config: utmp on purpose. It is used by e.g. emdebian via /etc/init.d/rc.
23 23
24//applet:IF_RUNLEVEL(APPLET(runlevel, BB_DIR_SBIN, BB_SUID_DROP)) 24//applet:IF_RUNLEVEL(APPLET_NOEXEC(runlevel, runlevel, BB_DIR_SBIN, BB_SUID_DROP, runlevel))
25 25
26//kbuild:lib-$(CONFIG_RUNLEVEL) += runlevel.o 26//kbuild:lib-$(CONFIG_RUNLEVEL) += runlevel.o
27 27
diff --git a/miscutils/setserial.c b/miscutils/setserial.c
index 28a1bef18..f217c3beb 100644
--- a/miscutils/setserial.c
+++ b/miscutils/setserial.c
@@ -15,7 +15,7 @@
15//config: help 15//config: help
16//config: Retrieve or set Linux serial port. 16//config: Retrieve or set Linux serial port.
17 17
18//applet:IF_SETSERIAL(APPLET(setserial, BB_DIR_BIN, BB_SUID_DROP)) 18//applet:IF_SETSERIAL(APPLET_NOEXEC(setserial, setserial, BB_DIR_BIN, BB_SUID_DROP, setserial))
19 19
20//kbuild:lib-$(CONFIG_SETSERIAL) += setserial.o 20//kbuild:lib-$(CONFIG_SETSERIAL) += setserial.o
21 21
@@ -210,35 +210,35 @@ struct serial_struct {
210#endif 210#endif
211 211
212//usage:#define setserial_trivial_usage 212//usage:#define setserial_trivial_usage
213//usage: "[-gabGvzV] DEVICE [PARAMETER [ARG]]..." 213//usage: "[-abGvz] { DEVICE [PARAMETER [ARG]]... | -g DEVICE... }"
214//usage:#define setserial_full_usage "\n\n" 214//usage:#define setserial_full_usage "\n\n"
215//usage: "Request or set Linux serial port information\n" 215//usage: "Print or set serial port parameters"
216//usage: "\n" 216//usage: "\n"
217//usage: " -g Interpret parameters as list of devices for reporting\n" 217//usage: "\n"" -a Print all"
218//usage: " -a Print all available information\n" 218//usage: "\n"" -b Print summary"
219//usage: " -b Print summary information\n" 219//usage: "\n"" -G Print as setserial PARAMETERs"
220//usage: " -G Print in form which can be fed back\n" 220//usage: "\n"" -v Verbose"
221//usage: " to setserial as command line parameters\n" 221//usage: "\n"" -z Zero out serial flags before setting"
222//usage: " -z Zero out serial flags before setting\n" 222//usage: "\n"" -g All args are device names"
223//usage: " -v Verbose\n" 223//usage: "\n"
224//usage: "\n" 224//usage: "\n""PARAMETERs: (* = takes ARG, ^ = can be turned off by preceding ^)"
225//usage: "Parameters: (* = takes an argument, ^ = can be turned off by preceding ^)\n" 225//usage: "\n"" *port, *irq, *divisor, *uart, *baud_base, *close_delay, *closing_wait,"
226//usage: " *port, *irq, *divisor, *uart, *baud_base, *close_delay, *closing_wait,\n" 226//usage: "\n"" ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,"
227//usage: " ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,\n" 227//usage: "\n"" ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,"
228//usage: " ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,\n" 228//usage: "\n"" spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust"
229//usage: " spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust\n" 229//usage: "\n""ARG for uart:"
230//usage: "\n" 230//usage: "\n"" unknown, 8250, 16450, 16550, 16550A, Cirrus, 16650, 16650V2, 16750,"
231//usage: "UART types:\n" 231//usage: "\n"" 16950, 16954, 16654, 16850, RSA, NS16550A, XSCALE, RM9000, OCTEON, AR7,"
232//usage: " unknown, 8250, 16450, 16550, 16550A, Cirrus, 16650, 16650V2, 16750,\n" 232//usage: "\n"" U6_16550A"
233//usage: " 16950, 16954, 16654, 16850, RSA, NS16550A, XSCALE, RM9000, OCTEON, AR7,\n" 233
234//usage: " U6_16550A" 234// option string is "bGavzgq". "q" is accepted but ignored.
235
236#define OPT_PRINT_SUMMARY (1 << 0) 235#define OPT_PRINT_SUMMARY (1 << 0)
237#define OPT_PRINT_FEDBACK (1 << 1) 236#define OPT_PRINT_FEDBACK (1 << 1)
238#define OPT_PRINT_ALL (1 << 2) 237#define OPT_PRINT_ALL (1 << 2)
239#define OPT_VERBOSE (1 << 3) 238#define OPT_VERBOSE (1 << 3)
240#define OPT_ZERO (1 << 4) 239#define OPT_ZERO (1 << 4)
241#define OPT_GET (1 << 5) 240#define OPT_LIST_OF_DEVS (1 << 5)
241/*#define OPT_QUIET (1 << 6)*/
242 242
243#define OPT_MODE_MASK \ 243#define OPT_MODE_MASK \
244 (OPT_PRINT_ALL | OPT_PRINT_SUMMARY | OPT_PRINT_FEDBACK) 244 (OPT_PRINT_ALL | OPT_PRINT_SUMMARY | OPT_PRINT_FEDBACK)
@@ -362,7 +362,7 @@ static bool cmd_is_flag(int cmd)
362 return (cmd >= CMD_FLAG_FIRST && cmd <= CMD_FLAG_LAST); 362 return (cmd >= CMD_FLAG_FIRST && cmd <= CMD_FLAG_LAST);
363} 363}
364 364
365static bool cmd_need_arg(int cmd) 365static bool cmd_needs_arg(int cmd)
366{ 366{
367 return (cmd >= CMD_PORT && cmd <= CMD_WAIT); 367 return (cmd >= CMD_PORT && cmd <= CMD_WAIT);
368} 368}
@@ -652,11 +652,9 @@ static int find_cmd(const char *cmd)
652static void serial_set(char **arg, int opts) 652static void serial_set(char **arg, int opts)
653{ 653{
654 struct serial_struct serinfo; 654 struct serial_struct serinfo;
655 int cmd;
656 const char *word;
657 int fd; 655 int fd;
658 656
659 fd = serial_open(*arg++, /*quiet:*/ false); 657 fd = serial_open(*arg, /*quiet:*/ false);
660 if (fd < 0) 658 if (fd < 0)
661 exit(201); 659 exit(201);
662 660
@@ -665,17 +663,20 @@ static void serial_set(char **arg, int opts)
665 if (opts & OPT_ZERO) 663 if (opts & OPT_ZERO)
666 serinfo.flags = 0; 664 serinfo.flags = 0;
667 665
668 while (*arg) { 666 while (*++arg) {
667 const char *word;
669 int invert; 668 int invert;
669 int cmd;
670 670
671 word = *arg++; 671 word = *arg;
672 invert = (*word == '^'); 672 invert = (word[0] == '^');
673 word += invert; 673 word += invert;
674 674
675 cmd = find_cmd(word); 675 cmd = find_cmd(word);
676 676
677 if (*arg == NULL && cmd_need_arg(cmd)) 677 if (cmd_needs_arg(cmd))
678 bb_error_msg_and_die(bb_msg_requires_arg, word); 678 if (*++arg == NULL)
679 bb_error_msg_and_die(bb_msg_requires_arg, word);
679 680
680 if (invert && !cmd_is_flag(cmd)) 681 if (invert && !cmd_is_flag(cmd))
681 bb_error_msg_and_die("can't invert %s", word); 682 bb_error_msg_and_die("can't invert %s", word);
@@ -705,25 +706,25 @@ static void serial_set(char **arg, int opts)
705 serinfo.flags |= setbits[cmd]; 706 serinfo.flags |= setbits[cmd];
706 break; 707 break;
707 case CMD_PORT: 708 case CMD_PORT:
708 serinfo.port = get_numeric(*arg++); 709 serinfo.port = get_numeric(*arg);
709 break; 710 break;
710 case CMD_IRQ: 711 case CMD_IRQ:
711 serinfo.irq = get_numeric(*arg++); 712 serinfo.irq = get_numeric(*arg);
712 break; 713 break;
713 case CMD_DIVISOR: 714 case CMD_DIVISOR:
714 serinfo.custom_divisor = get_numeric(*arg++); 715 serinfo.custom_divisor = get_numeric(*arg);
715 break; 716 break;
716 case CMD_UART: 717 case CMD_UART:
717 serinfo.type = get_uart(*arg++); 718 serinfo.type = get_uart(*arg);
718 break; 719 break;
719 case CMD_BASE: 720 case CMD_BASE:
720 serinfo.baud_base = get_numeric(*arg++); 721 serinfo.baud_base = get_numeric(*arg);
721 break; 722 break;
722 case CMD_DELAY: 723 case CMD_DELAY:
723 serinfo.close_delay = get_numeric(*arg++); 724 serinfo.close_delay = get_numeric(*arg);
724 break; 725 break;
725 case CMD_WAIT: 726 case CMD_WAIT:
726 serinfo.closing_wait = get_wait(*arg++); 727 serinfo.closing_wait = get_wait(*arg);
727 break; 728 break;
728 case CMD_AUTOCONFIG: 729 case CMD_AUTOCONFIG:
729 serial_ctl(fd, CTL_SET | CTL_CONFIG | CTL_GET, &serinfo); 730 serial_ctl(fd, CTL_SET | CTL_CONFIG | CTL_GET, &serinfo);
@@ -741,22 +742,22 @@ int setserial_main(int argc UNUSED_PARAM, char **argv)
741{ 742{
742 int opts; 743 int opts;
743 744
744 opt_complementary = "-1:b-aG:G-ab:a-bG"; 745 opts = getopt32(argv, "^" "bGavzgq" "\0" "-1:b-aG:G-ab:a-bG");
745 opts = getopt32(argv, "bGavzg");
746 argv += optind; 746 argv += optind;
747 747
748 if (!argv[1]) /* one arg only? */ 748 if (!argv[1]) /* one arg only? (nothing to change?) */
749 opts |= OPT_GET; 749 opts |= OPT_LIST_OF_DEVS; /* force display */
750 750
751 if (!(opts & OPT_GET)) { 751 if (!(opts & OPT_LIST_OF_DEVS)) {
752 serial_set(argv, opts); 752 serial_set(argv, opts);
753 argv[1] = NULL; 753 argv[1] = NULL;
754 } 754 }
755 755
756 if (opts & (OPT_VERBOSE | OPT_GET)) { 756 /* -v effect: "after setting params, do not be silent, show them" */
757 if (opts & (OPT_VERBOSE | OPT_LIST_OF_DEVS)) {
757 do { 758 do {
758 serial_get(*argv++, opts & OPT_MODE_MASK); 759 serial_get(*argv, opts & OPT_MODE_MASK);
759 } while (*argv); 760 } while (*++argv);
760 } 761 }
761 762
762 return EXIT_SUCCESS; 763 return EXIT_SUCCESS;
diff --git a/miscutils/time.c b/miscutils/time.c
index 60fc11f6e..65dbcdcf3 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -127,13 +127,13 @@ static unsigned long ptok(const unsigned pagesize, const unsigned long pages)
127 127
128/* summarize: Report on the system use of a command. 128/* summarize: Report on the system use of a command.
129 129
130 Print the FMT argument except that `%' sequences 130 Print the FMT argument except that '%' sequences
131 have special meaning, and `\n' and `\t' are translated into 131 have special meaning, and '\n' and '\t' are translated into
132 newline and tab, respectively, and `\\' is translated into `\'. 132 newline and tab, respectively, and '\\' is translated into '\'.
133 133
134 The character following a `%' can be: 134 The character following a '%' can be:
135 (* means the tcsh time builtin also recognizes it) 135 (* means the tcsh time builtin also recognizes it)
136 % == a literal `%' 136 % == a literal '%'
137 C == command name and arguments 137 C == command name and arguments
138* D == average unshared data size in K (ru_idrss+ru_isrss) 138* D == average unshared data size in K (ru_idrss+ru_isrss)
139* E == elapsed real (wall clock) time in [hour:]min:sec 139* E == elapsed real (wall clock) time in [hour:]min:sec
@@ -430,9 +430,10 @@ int time_main(int argc UNUSED_PARAM, char **argv)
430 OPT_f = (1 << 4), 430 OPT_f = (1 << 4),
431 }; 431 };
432 432
433 opt_complementary = "-1"; /* at least one arg */
434 /* "+": stop on first non-option */ 433 /* "+": stop on first non-option */
435 opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); 434 opt = getopt32(argv, "^+" "vpao:f:" "\0" "-1"/*at least one arg*/,
435 &output_filename, &output_format
436 );
436 argv += optind; 437 argv += optind;
437 if (opt & OPT_v) 438 if (opt & OPT_v)
438 output_format = long_format; 439 output_format = long_format;
diff --git a/miscutils/ttysize.c b/miscutils/ttysize.c
index 7f6a84308..2c2d4ec33 100644
--- a/miscutils/ttysize.c
+++ b/miscutils/ttysize.c
@@ -18,7 +18,7 @@
18//config: error, but returns default 80x24. 18//config: error, but returns default 80x24.
19//config: Usage in shell scripts: width=`ttysize w`. 19//config: Usage in shell scripts: width=`ttysize w`.
20 20
21//applet:IF_TTYSIZE(APPLET(ttysize, BB_DIR_USR_BIN, BB_SUID_DROP)) 21//applet:IF_TTYSIZE(APPLET_NOFORK(ttysize, ttysize, BB_DIR_USR_BIN, BB_SUID_DROP, ttysize))
22 22
23//kbuild:lib-$(CONFIG_TTYSIZE) += ttysize.o 23//kbuild:lib-$(CONFIG_TTYSIZE) += ttysize.o
24 24
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c
index c6ba22adf..d142d1144 100644
--- a/miscutils/ubi_tools.c
+++ b/miscutils/ubi_tools.c
@@ -52,6 +52,7 @@
52//applet:IF_UBIRMVOL( APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol)) 52//applet:IF_UBIRMVOL( APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol))
53//applet:IF_UBIRSVOL( APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol)) 53//applet:IF_UBIRSVOL( APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol))
54//applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol)) 54//applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol))
55/* not NOEXEC: if flash operation stalls, use less memory in "hung" process */
55 56
56//kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o 57//kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o
57//kbuild:lib-$(CONFIG_UBIDETACH) += ubi_tools.o 58//kbuild:lib-$(CONFIG_UBIDETACH) += ubi_tools.o
@@ -67,23 +68,32 @@
67#endif 68#endif
68#include <mtd/ubi-user.h> 69#include <mtd/ubi-user.h>
69 70
70#define do_attach (ENABLE_UBIATTACH && applet_name[3] == 'a') 71#define UBI_APPLET_CNT (0 \
71#define do_detach (ENABLE_UBIDETACH && applet_name[3] == 'd') 72 + ENABLE_UBIATTACH \
72#define do_mkvol (ENABLE_UBIMKVOL && applet_name[3] == 'm') 73 + ENABLE_UBIDETACH \
73#define do_rmvol (ENABLE_UBIRMVOL && applet_name[4] == 'm') 74 + ENABLE_UBIMKVOL \
74#define do_rsvol (ENABLE_UBIRSVOL && applet_name[4] == 's') 75 + ENABLE_UBIRMVOL \
75#define do_update (ENABLE_UBIUPDATEVOL && applet_name[3] == 'u') 76 + ENABLE_UBIRSVOL \
76 77 + ENABLE_UBIUPDATEVOL \
77static unsigned get_num_from_file(const char *path, unsigned max, const char *errmsg) 78 )
79
80#define do_attach (ENABLE_UBIATTACH && (UBI_APPLET_CNT == 1 || applet_name[4] == 't'))
81#define do_detach (ENABLE_UBIDETACH && (UBI_APPLET_CNT == 1 || applet_name[4] == 'e'))
82#define do_mkvol (ENABLE_UBIMKVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 'k'))
83#define do_rmvol (ENABLE_UBIRMVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 'm'))
84#define do_rsvol (ENABLE_UBIRSVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 's'))
85#define do_update (ENABLE_UBIUPDATEVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 'p'))
86
87static unsigned get_num_from_file(const char *path, unsigned max)
78{ 88{
79 char buf[sizeof(long long)*3]; 89 char buf[sizeof(long long)*3];
80 unsigned long long num; 90 unsigned long long num;
81 91
82 if (open_read_close(path, buf, sizeof(buf)) < 0) 92 if (open_read_close(path, buf, sizeof(buf)) < 0)
83 bb_perror_msg_and_die(errmsg, path); 93 bb_perror_msg_and_die("can't open '%s'", path);
84 /* It can be \n terminated, xatoull won't work well */ 94 /* It can be \n terminated, xatoull won't work well */
85 if (sscanf(buf, "%llu", &num) != 1 || num > max) 95 if (sscanf(buf, "%llu", &num) != 1 || num > max)
86 bb_error_msg_and_die(errmsg, path); 96 bb_error_msg_and_die("number in '%s' is malformed or too large", path);
87 return num; 97 return num;
88} 98}
89 99
@@ -135,20 +145,17 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
135#define OPTION_a (1 << 5) 145#define OPTION_a (1 << 5)
136#define OPTION_t (1 << 6) 146#define OPTION_t (1 << 6)
137 if (do_mkvol) { 147 if (do_mkvol) {
138 opt_complementary = "-1"; 148 opts = getopt32(argv, "^" "md:+n:+N:s:a:+t:O:+" "\0" "-1",
139 opts = getopt32(argv, "md:+n:+N:s:a:+t:O:+",
140 &dev_num, &vol_id, 149 &dev_num, &vol_id,
141 &vol_name, &size_bytes_str, &alignment, &type, 150 &vol_name, &size_bytes_str, &alignment, &type,
142 &vid_hdr_offset 151 &vid_hdr_offset
143 ); 152 );
144 } else 153 } else
145 if (do_update) { 154 if (do_update) {
146 opt_complementary = "-1"; 155 opts = getopt32(argv, "^" "s:at" "\0" "-1", &size_bytes_str);
147 opts = getopt32(argv, "s:at", &size_bytes_str);
148 opts *= OPTION_s; 156 opts *= OPTION_s;
149 } else { 157 } else {
150 opt_complementary = "-1"; 158 opts = getopt32(argv, "^" "m:+d:+n:+N:s:a:+t:" "\0" "-1",
151 opts = getopt32(argv, "m:+d:+n:+N:s:a:+t:",
152 &mtd_num, &dev_num, &vol_id, 159 &mtd_num, &dev_num, &vol_id,
153 &vol_name, &size_bytes_str, &alignment, &type 160 &vol_name, &size_bytes_str, &alignment, &type
154 ); 161 );
@@ -217,10 +224,10 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
217 p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); 224 p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num);
218 225
219 strcpy(p, "avail_eraseblocks"); 226 strcpy(p, "avail_eraseblocks");
220 leb_avail = get_num_from_file(path, UINT_MAX, "Can't get available eraseblocks from '%s'"); 227 leb_avail = get_num_from_file(path, UINT_MAX);
221 228
222 strcpy(p, "eraseblock_size"); 229 strcpy(p, "eraseblock_size");
223 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get eraseblock size from '%s'"); 230 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK);
224 231
225 size_bytes = leb_avail * (unsigned long long)leb_size; 232 size_bytes = leb_avail * (unsigned long long)leb_size;
226 //if (size_bytes <= 0) 233 //if (size_bytes <= 0)
@@ -232,16 +239,19 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
232 if (!(opts & OPTION_N)) 239 if (!(opts & OPTION_N))
233 bb_error_msg_and_die("name not specified"); 240 bb_error_msg_and_die("name not specified");
234 241
242 /* the structure is memset(0) above */
235 mkvol_req.vol_id = vol_id; 243 mkvol_req.vol_id = vol_id;
236 mkvol_req.vol_type = UBI_DYNAMIC_VOLUME; 244 mkvol_req.vol_type = UBI_DYNAMIC_VOLUME;
237 if ((opts & OPTION_t) && type[0] == 's') 245 if ((opts & OPTION_t) && type[0] == 's')
238 mkvol_req.vol_type = UBI_STATIC_VOLUME; 246 mkvol_req.vol_type = UBI_STATIC_VOLUME;
239 mkvol_req.alignment = alignment; 247 mkvol_req.alignment = alignment;
240 mkvol_req.bytes = size_bytes; /* signed int64_t */ 248 mkvol_req.bytes = size_bytes; /* signed int64_t */
241 strncpy(mkvol_req.name, vol_name, UBI_MAX_VOLUME_NAME); 249 /* strnlen avoids overflow of 16-bit field (paranoia) */
242 mkvol_req.name_len = strlen(vol_name); 250 mkvol_req.name_len = strnlen(vol_name, UBI_MAX_VOLUME_NAME+1);
243 if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME) 251 if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME)
244 bb_error_msg_and_die("volume name too long: '%s'", vol_name); 252 bb_error_msg_and_die("volume name too long: '%s'", vol_name);
253 /* this is safe: .name[] is UBI_MAX_VOLUME_NAME+1 bytes */
254 strcpy(mkvol_req.name, vol_name);
245 255
246 xioctl(fd, UBI_IOCMKVOL, &mkvol_req); 256 xioctl(fd, UBI_IOCMKVOL, &mkvol_req);
247 } else 257 } else
@@ -289,7 +299,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
289 } else 299 } else
290 300
291//usage:#define ubiupdatevol_trivial_usage 301//usage:#define ubiupdatevol_trivial_usage
292//usage: "[-t | [-s SIZE] IMG_FILE] UBI_DEVICE" 302//usage: "-t UBI_DEVICE | [-s SIZE] UBI_DEVICE IMG_FILE"
293//usage:#define ubiupdatevol_full_usage "\n\n" 303//usage:#define ubiupdatevol_full_usage "\n\n"
294//usage: "Update UBI volume\n" 304//usage: "Update UBI volume\n"
295//usage: "\n -t Truncate to zero size" 305//usage: "\n -t Truncate to zero size"
@@ -304,24 +314,25 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
304 xioctl(fd, UBI_IOCVOLUP, &bytes64); 314 xioctl(fd, UBI_IOCVOLUP, &bytes64);
305 } 315 }
306 else { 316 else {
307 struct stat st;
308 unsigned ubinum, volnum; 317 unsigned ubinum, volnum;
309 unsigned leb_size; 318 unsigned leb_size;
310 ssize_t len; 319 char *buf;
311 char *input_data;
312 320
313 /* Assume that device is in normal format. */ 321 /* Assume that device is in normal format. */
314 /* Removes need for scanning sysfs tree as full libubi does. */ 322 /* Removes need for scanning sysfs tree as full libubi does. */
315 if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2) 323 if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2)
316 bb_error_msg_and_die("wrong format of UBI device name"); 324 bb_error_msg_and_die("UBI device name '%s' is not /dev/ubiN_M", ubi_ctrl);
317 325
318 sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum); 326 sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum);
319 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get usable eraseblock size from '%s'"); 327 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK);
320 328
321 if (!(opts & OPTION_s)) { 329 if (!*argv)
322 if (!*argv) 330 bb_show_usage();
323 bb_show_usage(); 331 if (NOT_LONE_DASH(*argv)) /* mtd-utils supports "-" as stdin */
324 xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO); 332 xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO);
333
334 if (!(opts & OPTION_s)) {
335 struct stat st;
325 xfstat(STDIN_FILENO, &st, *argv); 336 xfstat(STDIN_FILENO, &st, *argv);
326 size_bytes = st.st_size; 337 size_bytes = st.st_size;
327 } 338 }
@@ -330,12 +341,24 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
330 /* this ioctl expects signed int64_t* parameter */ 341 /* this ioctl expects signed int64_t* parameter */
331 xioctl(fd, UBI_IOCVOLUP, &bytes64); 342 xioctl(fd, UBI_IOCVOLUP, &bytes64);
332 343
333 input_data = xmalloc(leb_size); 344 /* can't use bb_copyfd_exact_size(): copy in blocks of exactly leb_size */
334 while ((len = full_read(STDIN_FILENO, input_data, leb_size)) > 0) { 345 buf = xmalloc(leb_size);
335 xwrite(fd, input_data, len); 346 while (size_bytes != 0) {
347 int len = full_read(STDIN_FILENO, buf, leb_size);
348 if (len <= 0) {
349 if (len < 0)
350 bb_perror_msg_and_die("read error from '%s'", *argv);
351 break;
352 }
353 if ((unsigned)len > size_bytes) {
354 /* for this case: "ubiupdatevol -s 1024000 $UBIDEV /dev/urandom" */
355 len = size_bytes;
356 }
357 xwrite(fd, buf, len);
358 size_bytes -= len;
336 } 359 }
337 if (len < 0) 360 if (ENABLE_FEATURE_CLEAN_UP)
338 bb_perror_msg_and_die("UBI volume update failed"); 361 free(buf);
339 } 362 }
340 } 363 }
341 364
diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c
index 786c4b9fa..ecc8fe137 100644
--- a/miscutils/ubirename.c
+++ b/miscutils/ubirename.c
@@ -14,6 +14,7 @@
14//config: Utility to rename UBI volumes 14//config: Utility to rename UBI volumes
15 15
16//applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP)) 16//applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP))
17/* not NOEXEC: if flash operation stalls, use less memory in "hung" process */
17 18
18//kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o 19//kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o
19 20
@@ -80,9 +81,12 @@ int ubirename_main(int argc, char **argv)
80 argv += 2; 81 argv += 2;
81 while (argv[0]) { 82 while (argv[0]) {
82 rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]); 83 rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]);
83 rnvol->ents[n].name_len = strlen(argv[1]); 84
85 /* strnlen avoids overflow of 16-bit field (paranoia) */
86 rnvol->ents[n].name_len = strnlen(argv[1], sizeof(rnvol->ents[n].name));
84 if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) 87 if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name))
85 bb_error_msg_and_die("new name '%s' is too long", argv[1]); 88 bb_error_msg_and_die("new name '%s' is too long", argv[1]);
89
86 strcpy(rnvol->ents[n].name, argv[1]); 90 strcpy(rnvol->ents[n].name, argv[1]);
87 n++; 91 n++;
88 argv += 2; 92 argv += 2;
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index ec06bcb51..392d05646 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -101,8 +101,9 @@ int watchdog_main(int argc UNUSED_PARAM, char **argv)
101 char *st_arg; 101 char *st_arg;
102 char *ht_arg; 102 char *ht_arg;
103 103
104 opt_complementary = "=1"; /* must have exactly 1 argument */ 104 opts = getopt32(argv, "^" "Ft:T:" "\0" "=1"/*must have exactly 1 arg*/,
105 opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); 105 &st_arg, &ht_arg
106 );
106 107
107 /* We need to daemonize *before* opening the watchdog as many drivers 108 /* We need to daemonize *before* opening the watchdog as many drivers
108 * will only allow one process at a time to do so. Since daemonizing 109 * will only allow one process at a time to do so. Since daemonizing