diff options
author | Ron Yorston <rmy@pobox.com> | 2017-08-22 14:56:12 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-08-22 14:56:12 +0100 |
commit | ce9af1cc5ea23f754587448cf35b5120c77bfeef (patch) | |
tree | 69e5eaba5e75ab909ed92d5045393471b8ff3c13 /util-linux | |
parent | c170026700eabb10147dd848c45c06995b43a32e (diff) | |
parent | e837a0dbbebf4229306df98fe9ee3b9bb30630c4 (diff) | |
download | busybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.tar.gz busybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.tar.bz2 busybox-w32-ce9af1cc5ea23f754587448cf35b5120c77bfeef.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
50 files changed, 419 insertions, 399 deletions
diff --git a/util-linux/acpid.c b/util-linux/acpid.c index 3c3811752..4f491fa14 100644 --- a/util-linux/acpid.c +++ b/util-linux/acpid.c | |||
@@ -264,8 +264,12 @@ int acpid_main(int argc UNUSED_PARAM, char **argv) | |||
264 | 264 | ||
265 | INIT_G(); | 265 | INIT_G(); |
266 | 266 | ||
267 | opt_complementary = "df:e--e"; | 267 | opts = getopt32(argv, "^" |
268 | opts = getopt32(argv, "c:de:fl:a:M:" IF_FEATURE_PIDFILE("p:") IF_FEATURE_ACPID_COMPAT("g:m:s:S:v"), | 268 | "c:de:fl:a:M:" |
269 | IF_FEATURE_PIDFILE("p:") | ||
270 | IF_FEATURE_ACPID_COMPAT("g:m:s:S:v") | ||
271 | "\0" | ||
272 | "df:e--e", | ||
269 | &opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map | 273 | &opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map |
270 | IF_FEATURE_PIDFILE(, &opt_pidfile) | 274 | IF_FEATURE_PIDFILE(, &opt_pidfile) |
271 | IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL) | 275 | IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL) |
diff --git a/util-linux/blkdiscard.c b/util-linux/blkdiscard.c index 8f6a4ab6c..5863f0aab 100644 --- a/util-linux/blkdiscard.c +++ b/util-linux/blkdiscard.c | |||
@@ -11,8 +11,9 @@ | |||
11 | //config: help | 11 | //config: help |
12 | //config: blkdiscard discards sectors on a given device. | 12 | //config: blkdiscard discards sectors on a given device. |
13 | 13 | ||
14 | //applet:IF_BLKDISCARD(APPLET_NOEXEC(blkdiscard, blkdiscard, BB_DIR_USR_BIN, BB_SUID_DROP, blkdiscard)) | ||
15 | |||
14 | //kbuild:lib-$(CONFIG_BLKDISCARD) += blkdiscard.o | 16 | //kbuild:lib-$(CONFIG_BLKDISCARD) += blkdiscard.o |
15 | //applet:IF_BLKDISCARD(APPLET(blkdiscard, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
16 | 17 | ||
17 | //usage:#define blkdiscard_trivial_usage | 18 | //usage:#define blkdiscard_trivial_usage |
18 | //usage: "[-o OFS] [-l LEN] [-s] DEVICE" | 19 | //usage: "[-o OFS] [-l LEN] [-s] DEVICE" |
@@ -44,7 +45,6 @@ int blkdiscard_main(int argc UNUSED_PARAM, char **argv) | |||
44 | uint64_t offset; /* Leaving these two variables out does not */ | 45 | uint64_t offset; /* Leaving these two variables out does not */ |
45 | uint64_t length; /* shrink code size and hampers readability. */ | 46 | uint64_t length; /* shrink code size and hampers readability. */ |
46 | uint64_t range[2]; | 47 | uint64_t range[2]; |
47 | // struct stat st; | ||
48 | int fd; | 48 | int fd; |
49 | 49 | ||
50 | enum { | 50 | enum { |
@@ -53,8 +53,7 @@ int blkdiscard_main(int argc UNUSED_PARAM, char **argv) | |||
53 | OPT_SECURE = (1 << 2), | 53 | OPT_SECURE = (1 << 2), |
54 | }; | 54 | }; |
55 | 55 | ||
56 | opt_complementary = "=1"; | 56 | opts = getopt32(argv, "^" "o:l:s" "\0" "=1", &offset_str, &length_str); |
57 | opts = getopt32(argv, "o:l:s", &offset_str, &length_str); | ||
58 | argv += optind; | 57 | argv += optind; |
59 | 58 | ||
60 | fd = xopen(argv[0], O_RDWR|O_EXCL); | 59 | fd = xopen(argv[0], O_RDWR|O_EXCL); |
diff --git a/util-linux/blkid.c b/util-linux/blkid.c index 0bd701aae..a56b69661 100644 --- a/util-linux/blkid.c +++ b/util-linux/blkid.c | |||
@@ -16,12 +16,12 @@ | |||
16 | //config: | 16 | //config: |
17 | //config:config FEATURE_BLKID_TYPE | 17 | //config:config FEATURE_BLKID_TYPE |
18 | //config: bool "Print filesystem type" | 18 | //config: bool "Print filesystem type" |
19 | //config: default n | 19 | //config: default y |
20 | //config: depends on BLKID | 20 | //config: depends on BLKID |
21 | //config: help | 21 | //config: help |
22 | //config: Show TYPE="filesystem type" | 22 | //config: Show TYPE="filesystem type" |
23 | 23 | ||
24 | //applet:IF_BLKID(APPLET(blkid, BB_DIR_SBIN, BB_SUID_DROP)) | 24 | //applet:IF_BLKID(APPLET_NOEXEC(blkid, blkid, BB_DIR_SBIN, BB_SUID_DROP, blkid)) |
25 | 25 | ||
26 | //kbuild:lib-$(CONFIG_BLKID) += blkid.o | 26 | //kbuild:lib-$(CONFIG_BLKID) += blkid.o |
27 | 27 | ||
diff --git a/util-linux/blockdev.c b/util-linux/blockdev.c index 9e1fef206..e53ade995 100644 --- a/util-linux/blockdev.c +++ b/util-linux/blockdev.c | |||
@@ -11,7 +11,7 @@ | |||
11 | //config: help | 11 | //config: help |
12 | //config: Performs some ioctls with block devices. | 12 | //config: Performs some ioctls with block devices. |
13 | 13 | ||
14 | //applet:IF_BLOCKDEV(APPLET(blockdev, BB_DIR_SBIN, BB_SUID_DROP)) | 14 | //applet:IF_BLOCKDEV(APPLET_NOEXEC(blockdev, blockdev, BB_DIR_SBIN, BB_SUID_DROP, blockdev)) |
15 | 15 | ||
16 | //kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o | 16 | //kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o |
17 | 17 | ||
diff --git a/util-linux/cal.c b/util-linux/cal.c index 091fdbd2b..10df0ae8b 100644 --- a/util-linux/cal.c +++ b/util-linux/cal.c | |||
@@ -376,7 +376,7 @@ static char *build_row(char *p, unsigned *dp) | |||
376 | * may be used to endorse or promote products derived from this software | 376 | * may be used to endorse or promote products derived from this software |
377 | * without specific prior written permission. | 377 | * without specific prior written permission. |
378 | * | 378 | * |
379 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 379 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND |
380 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 380 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
381 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 381 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
382 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 382 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
diff --git a/util-linux/chrt.c b/util-linux/chrt.c index 4bc8b6cfa..2712ea3e3 100644 --- a/util-linux/chrt.c +++ b/util-linux/chrt.c | |||
@@ -12,7 +12,7 @@ | |||
12 | //config: manipulate real-time attributes of a process. | 12 | //config: manipulate real-time attributes of a process. |
13 | //config: This requires sched_{g,s}etparam support in your libc. | 13 | //config: This requires sched_{g,s}etparam support in your libc. |
14 | 14 | ||
15 | //applet:IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) | 15 | //applet:IF_CHRT(APPLET_NOEXEC(chrt, chrt, BB_DIR_USR_BIN, BB_SUID_DROP, chrt)) |
16 | 16 | ||
17 | //kbuild:lib-$(CONFIG_CHRT) += chrt.o | 17 | //kbuild:lib-$(CONFIG_CHRT) += chrt.o |
18 | 18 | ||
@@ -77,8 +77,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv) | |||
77 | int policy = SCHED_RR; | 77 | int policy = SCHED_RR; |
78 | 78 | ||
79 | /* only one policy accepted */ | 79 | /* only one policy accepted */ |
80 | opt_complementary = "r--fo:f--ro:o--rf"; | 80 | opt = getopt32(argv, "^+" "mprfo" "\0" "r--fo:f--ro:o--rf"); |
81 | opt = getopt32(argv, "+mprfo"); | ||
82 | if (opt & OPT_m) { /* print min/max and exit */ | 81 | if (opt & OPT_m) { /* print min/max and exit */ |
83 | show_min_max(SCHED_FIFO); | 82 | show_min_max(SCHED_FIFO); |
84 | show_min_max(SCHED_RR); | 83 | show_min_max(SCHED_RR); |
diff --git a/util-linux/eject.c b/util-linux/eject.c index 8095cbef0..6c30facd2 100644 --- a/util-linux/eject.c +++ b/util-linux/eject.c | |||
@@ -124,8 +124,9 @@ int eject_main(int argc UNUSED_PARAM, char **argv) | |||
124 | unsigned flags; | 124 | unsigned flags; |
125 | const char *device; | 125 | const char *device; |
126 | 126 | ||
127 | opt_complementary = "?1:t--T:T--t"; | 127 | flags = getopt32(argv, "^" "tT"IF_FEATURE_EJECT_SCSI("s") |
128 | flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); | 128 | "\0" "?1:t--T:T--t" |
129 | ); | ||
129 | device = argv[optind] ? argv[optind] : "/dev/cdrom"; | 130 | device = argv[optind] ? argv[optind] : "/dev/cdrom"; |
130 | 131 | ||
131 | /* We used to do "umount <device>" here, but it was buggy | 132 | /* We used to do "umount <device>" here, but it was buggy |
diff --git a/util-linux/fallocate.c b/util-linux/fallocate.c index 70e7e178f..1a02a322f 100644 --- a/util-linux/fallocate.c +++ b/util-linux/fallocate.c | |||
@@ -82,8 +82,7 @@ int fallocate_main(int argc UNUSED_PARAM, char **argv) | |||
82 | int fd; | 82 | int fd; |
83 | 83 | ||
84 | /* exactly one non-option arg */ | 84 | /* exactly one non-option arg */ |
85 | opt_complementary = "=1"; | 85 | opts = getopt32(argv, "^" "l:o:" "\0" "=1", &str_l, &str_o); |
86 | opts = getopt32(argv, "l:o:", &str_l, &str_o); | ||
87 | if (!(opts & 1)) | 86 | if (!(opts & 1)) |
88 | bb_show_usage(); | 87 | bb_show_usage(); |
89 | 88 | ||
diff --git a/util-linux/fatattr.c b/util-linux/fatattr.c index 9fb566d5a..770b1d2f9 100644 --- a/util-linux/fatattr.c +++ b/util-linux/fatattr.c | |||
@@ -15,7 +15,7 @@ | |||
15 | //config: help | 15 | //config: help |
16 | //config: fatattr lists or changes the file attributes on a fat file system. | 16 | //config: fatattr lists or changes the file attributes on a fat file system. |
17 | 17 | ||
18 | //applet:IF_FATATTR(APPLET(fatattr, BB_DIR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_FATATTR(APPLET_NOEXEC(fatattr, fatattr, BB_DIR_BIN, BB_SUID_DROP, fatattr)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_FATATTR) += fatattr.o | 20 | //kbuild:lib-$(CONFIG_FATATTR) += fatattr.o |
21 | 21 | ||
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c index 6faaf1b10..855269c30 100644 --- a/util-linux/fdformat.c +++ b/util-linux/fdformat.c | |||
@@ -66,8 +66,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) | |||
66 | struct floppy_struct param; | 66 | struct floppy_struct param; |
67 | struct format_descr descr; | 67 | struct format_descr descr; |
68 | 68 | ||
69 | opt_complementary = "=1"; /* must have 1 param */ | 69 | verify = !getopt32(argv, "^" "n" "\0" "=1"); |
70 | verify = !getopt32(argv, "n"); | ||
71 | argv += optind; | 70 | argv += optind; |
72 | 71 | ||
73 | xstat(*argv, &st); | 72 | xstat(*argv, &st); |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index e00f85864..c4318b6c4 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -644,7 +644,7 @@ read_line(const char *prompt) | |||
644 | { | 644 | { |
645 | int sz; | 645 | int sz; |
646 | 646 | ||
647 | sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer), /*timeout*/ -1); | 647 | sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer)); |
648 | if (sz <= 0) | 648 | if (sz <= 0) |
649 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ | 649 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ |
650 | 650 | ||
@@ -2848,7 +2848,7 @@ xselect(void) | |||
2848 | if (dos_compatible_flag) { | 2848 | if (dos_compatible_flag) { |
2849 | sector_offset = g_sectors; | 2849 | sector_offset = g_sectors; |
2850 | puts("Warning: setting sector offset for DOS " | 2850 | puts("Warning: setting sector offset for DOS " |
2851 | "compatiblity"); | 2851 | "compatibility"); |
2852 | } | 2852 | } |
2853 | update_units(); | 2853 | update_units(); |
2854 | break; | 2854 | break; |
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index 89f1f323c..1141b7801 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * may be used to endorse or promote products derived from this software | 18 | * may be used to endorse or promote products derived from this software |
19 | * without specific prior written permission. | 19 | * without specific prior written permission. |
20 | * | 20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
diff --git a/util-linux/flock.c b/util-linux/flock.c index ec35af18f..dd0bfd430 100644 --- a/util-linux/flock.c +++ b/util-linux/flock.c | |||
@@ -38,17 +38,15 @@ int flock_main(int argc UNUSED_PARAM, char **argv) | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | #if ENABLE_LONG_OPTS | 40 | #if ENABLE_LONG_OPTS |
41 | static const char getopt_longopts[] ALIGN1 = | 41 | static const char flock_longopts[] ALIGN1 = |
42 | "shared\0" No_argument "s" | 42 | "shared\0" No_argument "s" |
43 | "exclusive\0" No_argument "x" | 43 | "exclusive\0" No_argument "x" |
44 | "unlock\0" No_argument "u" | 44 | "unlock\0" No_argument "u" |
45 | "nonblock\0" No_argument "n" | 45 | "nonblock\0" No_argument "n" |
46 | ; | 46 | ; |
47 | applet_long_options = getopt_longopts; | ||
48 | #endif | 47 | #endif |
49 | opt_complementary = "-1"; | ||
50 | 48 | ||
51 | opt = getopt32(argv, "+sxnu"); | 49 | opt = getopt32long(argv, "^+" "sxnu" "\0" "-1", flock_longopts); |
52 | argv += optind; | 50 | argv += optind; |
53 | 51 | ||
54 | if (argv[1]) { | 52 | if (argv[1]) { |
diff --git a/util-linux/freeramdisk.c b/util-linux/freeramdisk.c index 55187cb40..6752e49d8 100644 --- a/util-linux/freeramdisk.c +++ b/util-linux/freeramdisk.c | |||
@@ -33,9 +33,9 @@ | |||
33 | //config: ramdisk. If you have no use for freeing memory from a ramdisk, leave | 33 | //config: ramdisk. If you have no use for freeing memory from a ramdisk, leave |
34 | //config: this disabled. | 34 | //config: this disabled. |
35 | 35 | ||
36 | // APPLET_ODDNAME:name main location suid_type help | 36 | // APPLET_ODDNAME:name main location suid_type help |
37 | //applet:IF_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, BB_DIR_BIN, BB_SUID_DROP, fdflush)) | 37 | //applet:IF_FDFLUSH( APPLET_ODDNAME(fdflush, freeramdisk, BB_DIR_BIN, BB_SUID_DROP, fdflush )) |
38 | //applet:IF_FREERAMDISK(APPLET(freeramdisk, BB_DIR_SBIN, BB_SUID_DROP)) | 38 | //applet:IF_FREERAMDISK(APPLET_NOEXEC(freeramdisk, freeramdisk, BB_DIR_SBIN, BB_SUID_DROP, freeramdisk)) |
39 | 39 | ||
40 | //kbuild:lib-$(CONFIG_FDFLUSH) += freeramdisk.o | 40 | //kbuild:lib-$(CONFIG_FDFLUSH) += freeramdisk.o |
41 | //kbuild:lib-$(CONFIG_FREERAMDISK) += freeramdisk.o | 41 | //kbuild:lib-$(CONFIG_FREERAMDISK) += freeramdisk.o |
@@ -67,8 +67,12 @@ int freeramdisk_main(int argc UNUSED_PARAM, char **argv) | |||
67 | fd = xopen(single_argv(argv), O_RDWR); | 67 | fd = xopen(single_argv(argv), O_RDWR); |
68 | 68 | ||
69 | // Act like freeramdisk, fdflush, or both depending on configuration. | 69 | // Act like freeramdisk, fdflush, or both depending on configuration. |
70 | ioctl_or_perror_and_die(fd, (ENABLE_FREERAMDISK && applet_name[1] == 'r') | 70 | ioctl_or_perror_and_die(fd, |
71 | || !ENABLE_FDFLUSH ? BLKFLSBUF : FDFLUSH, NULL, "%s", argv[1]); | 71 | ((ENABLE_FREERAMDISK && applet_name[1] == 'r') || !ENABLE_FDFLUSH) |
72 | ? BLKFLSBUF | ||
73 | : FDFLUSH, | ||
74 | NULL, "%s", argv[1] | ||
75 | ); | ||
72 | 76 | ||
73 | if (ENABLE_FEATURE_CLEAN_UP) close(fd); | 77 | if (ENABLE_FEATURE_CLEAN_UP) close(fd); |
74 | 78 | ||
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index 8c2b7d8de..c4612f251 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c | |||
@@ -173,7 +173,10 @@ struct globals { | |||
173 | 173 | ||
174 | /* Bigger stuff */ | 174 | /* Bigger stuff */ |
175 | struct termios sv_termios; | 175 | struct termios sv_termios; |
176 | char superblock_buffer[BLOCK_SIZE]; | 176 | union { |
177 | char superblock_buffer[BLOCK_SIZE]; | ||
178 | struct minix_superblock Super; | ||
179 | } u; | ||
177 | char add_zone_ind_blk[BLOCK_SIZE]; | 180 | char add_zone_ind_blk[BLOCK_SIZE]; |
178 | char add_zone_dind_blk[BLOCK_SIZE]; | 181 | char add_zone_dind_blk[BLOCK_SIZE]; |
179 | IF_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];) | 182 | IF_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];) |
@@ -207,7 +210,7 @@ struct globals { | |||
207 | #define name_depth (G.name_depth ) | 210 | #define name_depth (G.name_depth ) |
208 | #define name_component (G.name_component ) | 211 | #define name_component (G.name_component ) |
209 | #define sv_termios (G.sv_termios ) | 212 | #define sv_termios (G.sv_termios ) |
210 | #define superblock_buffer (G.superblock_buffer ) | 213 | #define superblock_buffer (G.u.superblock_buffer) |
211 | #define add_zone_ind_blk (G.add_zone_ind_blk ) | 214 | #define add_zone_ind_blk (G.add_zone_ind_blk ) |
212 | #define add_zone_dind_blk (G.add_zone_dind_blk ) | 215 | #define add_zone_dind_blk (G.add_zone_dind_blk ) |
213 | #define add_zone_tind_blk (G.add_zone_tind_blk ) | 216 | #define add_zone_tind_blk (G.add_zone_tind_blk ) |
@@ -247,7 +250,7 @@ enum { | |||
247 | #define Inode1 (((struct minix1_inode *) inode_buffer)-1) | 250 | #define Inode1 (((struct minix1_inode *) inode_buffer)-1) |
248 | #define Inode2 (((struct minix2_inode *) inode_buffer)-1) | 251 | #define Inode2 (((struct minix2_inode *) inode_buffer)-1) |
249 | 252 | ||
250 | #define Super (*(struct minix_superblock *)(superblock_buffer)) | 253 | #define Super (G.u.Super) |
251 | 254 | ||
252 | #if ENABLE_FEATURE_MINIX2 | 255 | #if ENABLE_FEATURE_MINIX2 |
253 | # define ZONES ((unsigned)(version2 ? Super.s_zones : Super.s_nzones)) | 256 | # define ZONES ((unsigned)(version2 ? Super.s_zones : Super.s_nzones)) |
@@ -1232,8 +1235,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) | |||
1232 | 1235 | ||
1233 | INIT_G(); | 1236 | INIT_G(); |
1234 | 1237 | ||
1235 | opt_complementary = "=1:ar"; /* one argument; -a assumes -r */ | 1238 | getopt32(argv, "^" OPTION_STR "\0" "=1:ar" /* one arg; -a assumes -r */); |
1236 | getopt32(argv, OPTION_STR); | ||
1237 | argv += optind; | 1239 | argv += optind; |
1238 | device_name = argv[0]; | 1240 | device_name = argv[0]; |
1239 | 1241 | ||
diff --git a/util-linux/fsfreeze.c b/util-linux/fsfreeze.c index 5c10c8044..2e2257337 100644 --- a/util-linux/fsfreeze.c +++ b/util-linux/fsfreeze.c | |||
@@ -13,7 +13,7 @@ | |||
13 | //config: help | 13 | //config: help |
14 | //config: Halt new accesses and flush writes on a mounted filesystem. | 14 | //config: Halt new accesses and flush writes on a mounted filesystem. |
15 | 15 | ||
16 | //applet:IF_FSFREEZE(APPLET(fsfreeze, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 16 | //applet:IF_FSFREEZE(APPLET_NOEXEC(fsfreeze, fsfreeze, BB_DIR_USR_SBIN, BB_SUID_DROP, fsfreeze)) |
17 | 17 | ||
18 | //kbuild:lib-$(CONFIG_FSFREEZE) += fsfreeze.o | 18 | //kbuild:lib-$(CONFIG_FSFREEZE) += fsfreeze.o |
19 | 19 | ||
@@ -36,15 +36,15 @@ int fsfreeze_main(int argc UNUSED_PARAM, char **argv) | |||
36 | unsigned opts; | 36 | unsigned opts; |
37 | int fd; | 37 | int fd; |
38 | 38 | ||
39 | applet_long_options = | ||
40 | "freeze\0" No_argument "\xff" | ||
41 | "unfreeze\0" No_argument "\xfe" | ||
42 | ; | ||
43 | /* exactly one non-option arg: the mountpoint */ | 39 | /* exactly one non-option arg: the mountpoint */ |
44 | /* one of opts is required */ | 40 | /* one of opts is required */ |
45 | /* opts are mutually exclusive */ | 41 | /* opts are mutually exclusive */ |
46 | opt_complementary = "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff"; | 42 | opts = getopt32long(argv, "^" |
47 | opts = getopt32(argv, ""); | 43 | "" /* no opts */ |
44 | "\0" "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff", | ||
45 | "freeze\0" No_argument "\xff" | ||
46 | "unfreeze\0" No_argument "\xfe" | ||
47 | ); | ||
48 | 48 | ||
49 | fd = xopen(argv[optind], O_RDONLY); | 49 | fd = xopen(argv[optind], O_RDONLY); |
50 | /* Works with NULL arg on linux-4.8.0 */ | 50 | /* Works with NULL arg on linux-4.8.0 */ |
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c index 6d0d61d92..4acfa567a 100644 --- a/util-linux/fstrim.c +++ b/util-linux/fstrim.c | |||
@@ -15,7 +15,7 @@ | |||
15 | //config: help | 15 | //config: help |
16 | //config: Discard unused blocks on a mounted filesystem. | 16 | //config: Discard unused blocks on a mounted filesystem. |
17 | 17 | ||
18 | //applet:IF_FSTRIM(APPLET(fstrim, BB_DIR_SBIN, BB_SUID_DROP)) | 18 | //applet:IF_FSTRIM(APPLET_NOEXEC(fstrim, fstrim, BB_DIR_SBIN, BB_SUID_DROP, fstrim)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o | 20 | //kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o |
21 | 21 | ||
@@ -63,17 +63,17 @@ int fstrim_main(int argc UNUSED_PARAM, char **argv) | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | #if ENABLE_LONG_OPTS | 65 | #if ENABLE_LONG_OPTS |
66 | static const char getopt_longopts[] ALIGN1 = | 66 | static const char fstrim_longopts[] ALIGN1 = |
67 | "offset\0" Required_argument "o" | 67 | "offset\0" Required_argument "o" |
68 | "length\0" Required_argument "l" | 68 | "length\0" Required_argument "l" |
69 | "minimum\0" Required_argument "m" | 69 | "minimum\0" Required_argument "m" |
70 | "verbose\0" No_argument "v" | 70 | "verbose\0" No_argument "v" |
71 | ; | 71 | ; |
72 | applet_long_options = getopt_longopts; | ||
73 | #endif | 72 | #endif |
74 | 73 | ||
75 | opt_complementary = "=1"; /* exactly one non-option arg: the mountpoint */ | 74 | opts = getopt32long(argv, "^" "o:l:m:v" "\0" "=1", fstrim_longopts, |
76 | opts = getopt32(argv, "o:l:m:v", &arg_o, &arg_l, &arg_m); | 75 | &arg_o, &arg_l, &arg_m |
76 | ); | ||
77 | 77 | ||
78 | memset(&range, 0, sizeof(range)); | 78 | memset(&range, 0, sizeof(range)); |
79 | range.len = ULLONG_MAX; | 79 | range.len = ULLONG_MAX; |
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index cf1bc592f..a151b7e56 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -42,32 +42,18 @@ | |||
42 | //config: | 42 | //config: |
43 | //config:config FEATURE_GETOPT_LONG | 43 | //config:config FEATURE_GETOPT_LONG |
44 | //config: bool "Support -l LONGOPTs" | 44 | //config: bool "Support -l LONGOPTs" |
45 | //config: default y if LONG_OPTS | 45 | //config: default y |
46 | //config: depends on GETOPT | 46 | //config: depends on GETOPT && LONG_OPTS |
47 | //config: help | 47 | //config: help |
48 | //config: Enable support for long options (option -l). | 48 | //config: Enable support for long options (option -l). |
49 | 49 | ||
50 | //applet:IF_GETOPT(APPLET(getopt, BB_DIR_BIN, BB_SUID_DROP)) | 50 | //applet:IF_GETOPT(APPLET_NOEXEC(getopt, getopt, BB_DIR_BIN, BB_SUID_DROP, getopt)) |
51 | 51 | ||
52 | //kbuild:lib-$(CONFIG_GETOPT) += getopt.o | 52 | //kbuild:lib-$(CONFIG_GETOPT) += getopt.o |
53 | 53 | ||
54 | //usage:#define getopt_trivial_usage | 54 | //usage:#define getopt_trivial_usage |
55 | //usage: "[OPTIONS] [--] OPTSTRING PARAMS" | 55 | //usage: "[OPTIONS] [--] OPTSTRING PARAMS" |
56 | //usage:#define getopt_full_usage "\n\n" | 56 | //usage:#define getopt_full_usage "\n\n" |
57 | //usage: IF_LONG_OPTS( | ||
58 | //usage: IF_FEATURE_GETOPT_LONG( | ||
59 | //usage: " -a,--alternative Allow long options starting with single -\n" | ||
60 | //usage: " -l,--longoptions LOPT[,...] Long options to recognize\n" | ||
61 | //usage: ) | ||
62 | //usage: " -n,--name PROGNAME The name under which errors are reported" | ||
63 | //usage: "\n -o,--options OPTSTRING Short options to recognize" | ||
64 | //usage: "\n -q,--quiet No error messages on unrecognized options" | ||
65 | //usage: "\n -Q,--quiet-output No normal output" | ||
66 | //usage: "\n -s,--shell SHELL Set shell quoting conventions" | ||
67 | //usage: "\n -T,--test Version test (exits with 4)" | ||
68 | //usage: "\n -u,--unquoted Don't quote output" | ||
69 | //usage: ) | ||
70 | //usage: IF_NOT_LONG_OPTS( | ||
71 | //usage: IF_FEATURE_GETOPT_LONG( | 57 | //usage: IF_FEATURE_GETOPT_LONG( |
72 | //usage: " -a Allow long options starting with single -\n" | 58 | //usage: " -a Allow long options starting with single -\n" |
73 | //usage: " -l LOPT[,...] Long options to recognize\n" | 59 | //usage: " -l LOPT[,...] Long options to recognize\n" |
@@ -79,7 +65,6 @@ | |||
79 | //usage: "\n -s SHELL Set shell quoting conventions" | 65 | //usage: "\n -s SHELL Set shell quoting conventions" |
80 | //usage: "\n -T Version test (exits with 4)" | 66 | //usage: "\n -T Version test (exits with 4)" |
81 | //usage: "\n -u Don't quote output" | 67 | //usage: "\n -u Don't quote output" |
82 | //usage: ) | ||
83 | //usage: IF_FEATURE_GETOPT_LONG( /* example uses -l, needs FEATURE_GETOPT_LONG */ | 68 | //usage: IF_FEATURE_GETOPT_LONG( /* example uses -l, needs FEATURE_GETOPT_LONG */ |
84 | //usage: "\n" | 69 | //usage: "\n" |
85 | //usage: "\nExample:" | 70 | //usage: "\nExample:" |
@@ -411,8 +396,7 @@ int getopt_main(int argc, char **argv) | |||
411 | #if !ENABLE_FEATURE_GETOPT_LONG | 396 | #if !ENABLE_FEATURE_GETOPT_LONG |
412 | opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg); | 397 | opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg); |
413 | #else | 398 | #else |
414 | applet_long_options = getopt_longopts; | 399 | opt = getopt32long(argv, "+o:n:qQs:Tual:*", getopt_longopts, |
415 | opt = getopt32(argv, "+o:n:qQs:Tual:*", | ||
416 | &optstr, &name, &s_arg, &l_arg); | 400 | &optstr, &name, &s_arg, &l_arg); |
417 | /* Effectuate the read options for the applet itself */ | 401 | /* Effectuate the read options for the applet itself */ |
418 | while (l_arg) { | 402 | while (l_arg) { |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index 37e58f2d0..6cf6d0297 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
@@ -73,8 +73,9 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
73 | #define OPT_s (1 << 1) | 73 | #define OPT_s (1 << 1) |
74 | #define OPT_a (1 << 2) | 74 | #define OPT_a (1 << 2) |
75 | #define OPT_p (1 << 3) | 75 | #define OPT_p (1 << 3) |
76 | opt_complementary = "?1"; /* 1 argument max */ | 76 | opt = getopt32(argv, "^" "l:s:apg:+c:+" "\0" "?1" /* 1 argument max */, |
77 | opt = getopt32(argv, "l:s:apg:+c:+", &opt_l, &opt_s, &bytes, &cols); | 77 | &opt_l, &opt_s, &bytes, &cols |
78 | ); | ||
78 | argv += optind; | 79 | argv += optind; |
79 | 80 | ||
80 | dumper->dump_vflag = ALL; | 81 | dumper->dump_vflag = ALL; |
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 5df56de15..29f51021e 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -16,11 +16,6 @@ | |||
16 | //config: shutdown in the hardware clock, so the hardware will keep the | 16 | //config: shutdown in the hardware clock, so the hardware will keep the |
17 | //config: correct time when Linux is _not_ running. | 17 | //config: correct time when Linux is _not_ running. |
18 | //config: | 18 | //config: |
19 | //config:config FEATURE_HWCLOCK_LONG_OPTIONS | ||
20 | //config: bool "Support long options (--hctosys,...)" | ||
21 | //config: default y | ||
22 | //config: depends on HWCLOCK && LONG_OPTS | ||
23 | //config: | ||
24 | //config:config FEATURE_HWCLOCK_ADJTIME_FHS | 19 | //config:config FEATURE_HWCLOCK_ADJTIME_FHS |
25 | //config: bool "Use FHS /var/lib/hwclock/adjtime" | 20 | //config: bool "Use FHS /var/lib/hwclock/adjtime" |
26 | //config: default n # util-linux-ng in Fedora 13 still uses /etc/adjtime | 21 | //config: default n # util-linux-ng in Fedora 13 still uses /etc/adjtime |
@@ -293,12 +288,12 @@ static void set_system_clock_timezone(int utc) | |||
293 | } | 288 | } |
294 | 289 | ||
295 | //usage:#define hwclock_trivial_usage | 290 | //usage:#define hwclock_trivial_usage |
296 | //usage: IF_FEATURE_HWCLOCK_LONG_OPTIONS( | 291 | //usage: IF_LONG_OPTS( |
297 | //usage: "[-r|--show] [-s|--hctosys] [-w|--systohc] [-t|--systz]" | 292 | //usage: "[-r|--show] [-s|--hctosys] [-w|--systohc] [--systz]" |
298 | //usage: " [-l|--localtime] [-u|--utc]" | 293 | //usage: " [--localtime] [-u|--utc]" |
299 | //usage: " [-f|--rtc FILE]" | 294 | //usage: " [-f|--rtc FILE]" |
300 | //usage: ) | 295 | //usage: ) |
301 | //usage: IF_NOT_FEATURE_HWCLOCK_LONG_OPTIONS( | 296 | //usage: IF_NOT_LONG_OPTS( |
302 | //usage: "[-r] [-s] [-w] [-t] [-l] [-u] [-f FILE]" | 297 | //usage: "[-r] [-s] [-w] [-t] [-l] [-u] [-f FILE]" |
303 | //usage: ) | 298 | //usage: ) |
304 | //usage:#define hwclock_full_usage "\n\n" | 299 | //usage:#define hwclock_full_usage "\n\n" |
@@ -306,12 +301,18 @@ static void set_system_clock_timezone(int utc) | |||
306 | //usage: "\n -r Show hardware clock time" | 301 | //usage: "\n -r Show hardware clock time" |
307 | //usage: "\n -s Set system time from hardware clock" | 302 | //usage: "\n -s Set system time from hardware clock" |
308 | //usage: "\n -w Set hardware clock from system time" | 303 | //usage: "\n -w Set hardware clock from system time" |
309 | //usage: "\n -t Set in-kernel timezone, correct system time" | 304 | //usage: IF_LONG_OPTS( |
305 | //usage: "\n --systz Set in-kernel timezone, correct system time" | ||
306 | //usage: ) | ||
310 | //usage: "\n if hardware clock is in local time" | 307 | //usage: "\n if hardware clock is in local time" |
311 | //usage: "\n -u Assume hardware clock is kept in UTC" | 308 | //usage: "\n -u Assume hardware clock is kept in UTC" |
312 | //usage: "\n -l Assume hardware clock is kept in local time" | 309 | //usage: IF_LONG_OPTS( |
310 | //usage: "\n --localtime Assume hardware clock is kept in local time" | ||
311 | //usage: ) | ||
313 | //usage: "\n -f FILE Use specified device (e.g. /dev/rtc2)" | 312 | //usage: "\n -f FILE Use specified device (e.g. /dev/rtc2)" |
314 | 313 | ||
314 | //TODO: get rid of incompatible -t and -l aliases to --systz and --localtime | ||
315 | |||
315 | #define HWCLOCK_OPT_LOCALTIME 0x01 | 316 | #define HWCLOCK_OPT_LOCALTIME 0x01 |
316 | #define HWCLOCK_OPT_UTC 0x02 | 317 | #define HWCLOCK_OPT_UTC 0x02 |
317 | #define HWCLOCK_OPT_SHOW 0x04 | 318 | #define HWCLOCK_OPT_SHOW 0x04 |
@@ -327,7 +328,7 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) | |||
327 | unsigned opt; | 328 | unsigned opt; |
328 | int utc; | 329 | int utc; |
329 | 330 | ||
330 | #if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS | 331 | #if ENABLE_LONG_OPTS |
331 | static const char hwclock_longopts[] ALIGN1 = | 332 | static const char hwclock_longopts[] ALIGN1 = |
332 | "localtime\0" No_argument "l" /* short opt is non-standard */ | 333 | "localtime\0" No_argument "l" /* short opt is non-standard */ |
333 | "utc\0" No_argument "u" | 334 | "utc\0" No_argument "u" |
@@ -337,14 +338,16 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) | |||
337 | "systz\0" No_argument "t" /* short opt is non-standard */ | 338 | "systz\0" No_argument "t" /* short opt is non-standard */ |
338 | "rtc\0" Required_argument "f" | 339 | "rtc\0" Required_argument "f" |
339 | ; | 340 | ; |
340 | applet_long_options = hwclock_longopts; | ||
341 | #endif | 341 | #endif |
342 | 342 | ||
343 | /* Initialize "timezone" (libc global variable) */ | 343 | /* Initialize "timezone" (libc global variable) */ |
344 | tzset(); | 344 | tzset(); |
345 | 345 | ||
346 | opt_complementary = "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l"; | 346 | opt = getopt32long(argv, |
347 | opt = getopt32(argv, "lurswtf:", &rtcname); | 347 | "^lurswtf:" "\0" "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", |
348 | hwclock_longopts, | ||
349 | &rtcname | ||
350 | ); | ||
348 | 351 | ||
349 | /* If -u or -l wasn't given check if we are using utc */ | 352 | /* If -u or -l wasn't given check if we are using utc */ |
350 | if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) | 353 | if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) |
diff --git a/util-linux/ionice.c b/util-linux/ionice.c index c7b7f0373..5b9664d25 100644 --- a/util-linux/ionice.c +++ b/util-linux/ionice.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //config: Set/set program io scheduling class and priority | 14 | //config: Set/set program io scheduling class and priority |
15 | //config: Requires kernel >= 2.6.13 | 15 | //config: Requires kernel >= 2.6.13 |
16 | 16 | ||
17 | //applet:IF_IONICE(APPLET(ionice, BB_DIR_BIN, BB_SUID_DROP)) | 17 | //applet:IF_IONICE(APPLET_NOEXEC(ionice, ionice, BB_DIR_BIN, BB_SUID_DROP, ionice)) |
18 | 18 | ||
19 | //kbuild:lib-$(CONFIG_IONICE) += ionice.o | 19 | //kbuild:lib-$(CONFIG_IONICE) += ionice.o |
20 | 20 | ||
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index c51d33143..a93ceee11 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c | |||
@@ -15,19 +15,10 @@ | |||
15 | //config: communication (IPC) objects and the associated data structures | 15 | //config: communication (IPC) objects and the associated data structures |
16 | //config: from the system. | 16 | //config: from the system. |
17 | 17 | ||
18 | //applet:IF_IPCRM(APPLET(ipcrm, BB_DIR_USR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_IPCRM(APPLET_NOEXEC(ipcrm, ipcrm, BB_DIR_USR_BIN, BB_SUID_DROP, ipcrm)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_IPCRM) += ipcrm.o | 20 | //kbuild:lib-$(CONFIG_IPCRM) += ipcrm.o |
21 | 21 | ||
22 | //usage:#define ipcrm_trivial_usage | ||
23 | //usage: "[-MQS key] [-mqs id]" | ||
24 | //usage:#define ipcrm_full_usage "\n\n" | ||
25 | //usage: "Upper-case options MQS remove an object by shmkey value.\n" | ||
26 | //usage: "Lower-case options remove an object by shmid value.\n" | ||
27 | //usage: "\n -mM Remove memory segment after last detach" | ||
28 | //usage: "\n -qQ Remove message queue" | ||
29 | //usage: "\n -sS Remove semaphore" | ||
30 | |||
31 | #include "libbb.h" | 22 | #include "libbb.h" |
32 | 23 | ||
33 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ | 24 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ |
@@ -94,6 +85,14 @@ static int remove_ids(type_id type, char **argv) | |||
94 | } | 85 | } |
95 | #endif /* IPCRM_LEGACY */ | 86 | #endif /* IPCRM_LEGACY */ |
96 | 87 | ||
88 | //usage:#define ipcrm_trivial_usage | ||
89 | //usage: "[-MQS key] [-mqs id]" | ||
90 | //usage:#define ipcrm_full_usage "\n\n" | ||
91 | //usage: "Upper-case options MQS remove an object by shmkey value.\n" | ||
92 | //usage: "Lower-case options remove an object by shmid value.\n" | ||
93 | //usage: "\n -mM Remove memory segment after last detach" | ||
94 | //usage: "\n -qQ Remove message queue" | ||
95 | //usage: "\n -sS Remove semaphore" | ||
97 | 96 | ||
98 | int ipcrm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 97 | int ipcrm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
99 | int ipcrm_main(int argc, char **argv) | 98 | int ipcrm_main(int argc, char **argv) |
@@ -137,28 +136,20 @@ int ipcrm_main(int argc, char **argv) | |||
137 | #endif /* IPCRM_LEGACY */ | 136 | #endif /* IPCRM_LEGACY */ |
138 | 137 | ||
139 | /* process new syntax to conform with SYSV ipcrm */ | 138 | /* process new syntax to conform with SYSV ipcrm */ |
140 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { | 139 | while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) { |
141 | int result; | 140 | int result; |
142 | int id = 0; | 141 | int id; |
143 | int iskey = isupper(c); | 142 | int iskey; |
144 | |||
145 | /* needed to delete semaphores */ | 143 | /* needed to delete semaphores */ |
146 | union semun arg; | 144 | union semun arg; |
147 | 145 | ||
148 | arg.val = 0; | 146 | if (c == '?') /* option not in the string */ |
149 | |||
150 | if ((c == '?') || (c == 'h')) { | ||
151 | bb_show_usage(); | 147 | bb_show_usage(); |
152 | } | ||
153 | |||
154 | /* we don't need case information any more */ | ||
155 | c = tolower(c); | ||
156 | 148 | ||
157 | /* make sure the option is in range: allowed are q, m, s */ | 149 | id = 0; |
158 | if (c != 'q' && c != 'm' && c != 's') { | 150 | arg.val = 0; |
159 | bb_show_usage(); | ||
160 | } | ||
161 | 151 | ||
152 | iskey = !(c & 0x20); /* uppercase? */ | ||
162 | if (iskey) { | 153 | if (iskey) { |
163 | /* keys are in hex or decimal */ | 154 | /* keys are in hex or decimal */ |
164 | key_t key = xstrtoul(optarg, 0); | 155 | key_t key = xstrtoul(optarg, 0); |
@@ -169,6 +160,7 @@ int ipcrm_main(int argc, char **argv) | |||
169 | continue; | 160 | continue; |
170 | } | 161 | } |
171 | 162 | ||
163 | c |= 0x20; /* lowercase. c is 'q', 'm' or 's' now */ | ||
172 | /* convert key to id */ | 164 | /* convert key to id */ |
173 | id = ((c == 'q') ? msgget(key, 0) : | 165 | id = ((c == 'q') ? msgget(key, 0) : |
174 | (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); | 166 | (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); |
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c index 1404930d4..7092ecd92 100644 --- a/util-linux/ipcs.c +++ b/util-linux/ipcs.c | |||
@@ -15,26 +15,10 @@ | |||
15 | //config: The ipcs utility is used to provide information on the currently | 15 | //config: The ipcs utility is used to provide information on the currently |
16 | //config: allocated System V interprocess (IPC) objects in the system. | 16 | //config: allocated System V interprocess (IPC) objects in the system. |
17 | 17 | ||
18 | //applet:IF_IPCS(APPLET(ipcs, BB_DIR_USR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_IPCS(APPLET_NOEXEC(ipcs, ipcs, BB_DIR_USR_BIN, BB_SUID_DROP, ipcs)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_IPCS) += ipcs.o | 20 | //kbuild:lib-$(CONFIG_IPCS) += ipcs.o |
21 | 21 | ||
22 | //usage:#define ipcs_trivial_usage | ||
23 | //usage: "[[-smq] -i shmid] | [[-asmq] [-tcplu]]" | ||
24 | //usage:#define ipcs_full_usage "\n\n" | ||
25 | //usage: " -i Show specific resource" | ||
26 | //usage: "\nResource specification:" | ||
27 | //usage: "\n -m Shared memory segments" | ||
28 | //usage: "\n -q Message queues" | ||
29 | //usage: "\n -s Semaphore arrays" | ||
30 | //usage: "\n -a All (default)" | ||
31 | //usage: "\nOutput format:" | ||
32 | //usage: "\n -t Time" | ||
33 | //usage: "\n -c Creator" | ||
34 | //usage: "\n -p Pid" | ||
35 | //usage: "\n -l Limits" | ||
36 | //usage: "\n -u Summary" | ||
37 | |||
38 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ | 22 | /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */ |
39 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ | 23 | /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */ |
40 | /* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */ | 24 | /* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */ |
@@ -585,6 +569,22 @@ static void print_sem(int semid) | |||
585 | bb_putchar('\n'); | 569 | bb_putchar('\n'); |
586 | } | 570 | } |
587 | 571 | ||
572 | //usage:#define ipcs_trivial_usage | ||
573 | //usage: "[[-smq] -i shmid] | [[-asmq] [-tcplu]]" | ||
574 | //usage:#define ipcs_full_usage "\n\n" | ||
575 | //usage: " -i Show specific resource" | ||
576 | //usage: "\nResource specification:" | ||
577 | //usage: "\n -m Shared memory segments" | ||
578 | //usage: "\n -q Message queues" | ||
579 | //usage: "\n -s Semaphore arrays" | ||
580 | //usage: "\n -a All (default)" | ||
581 | //usage: "\nOutput format:" | ||
582 | //usage: "\n -t Time" | ||
583 | //usage: "\n -c Creator" | ||
584 | //usage: "\n -p Pid" | ||
585 | //usage: "\n -l Limits" | ||
586 | //usage: "\n -u Summary" | ||
587 | |||
588 | int ipcs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 588 | int ipcs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
589 | int ipcs_main(int argc UNUSED_PARAM, char **argv) | 589 | int ipcs_main(int argc UNUSED_PARAM, char **argv) |
590 | { | 590 | { |
@@ -632,6 +632,10 @@ int ipcs_main(int argc UNUSED_PARAM, char **argv) | |||
632 | flags |= flag_msg | flag_shm | flag_sem; | 632 | flags |= flag_msg | flag_shm | flag_sem; |
633 | bb_putchar('\n'); | 633 | bb_putchar('\n'); |
634 | 634 | ||
635 | if (flags & flag_msg) { | ||
636 | do_msg(); | ||
637 | bb_putchar('\n'); | ||
638 | } | ||
635 | if (flags & flag_shm) { | 639 | if (flags & flag_shm) { |
636 | do_shm(); | 640 | do_shm(); |
637 | bb_putchar('\n'); | 641 | bb_putchar('\n'); |
@@ -640,9 +644,5 @@ int ipcs_main(int argc UNUSED_PARAM, char **argv) | |||
640 | do_sem(); | 644 | do_sem(); |
641 | bb_putchar('\n'); | 645 | bb_putchar('\n'); |
642 | } | 646 | } |
643 | if (flags & flag_msg) { | ||
644 | do_msg(); | ||
645 | bb_putchar('\n'); | ||
646 | } | ||
647 | fflush_stdout_and_exit(EXIT_SUCCESS); | 647 | fflush_stdout_and_exit(EXIT_SUCCESS); |
648 | } | 648 | } |
diff --git a/util-linux/losetup.c b/util-linux/losetup.c index c608de6cc..6b171d710 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c | |||
@@ -15,9 +15,9 @@ | |||
15 | //config: file or block device, and to query the status of a loop device. This | 15 | //config: file or block device, and to query the status of a loop device. This |
16 | //config: version does not currently support enabling data encryption. | 16 | //config: version does not currently support enabling data encryption. |
17 | 17 | ||
18 | //kbuild:lib-$(CONFIG_LOSETUP) += losetup.o | 18 | //applet:IF_LOSETUP(APPLET_NOEXEC(losetup, losetup, BB_DIR_SBIN, BB_SUID_DROP, losetup)) |
19 | 19 | ||
20 | //applet:IF_LOSETUP(APPLET(losetup, BB_DIR_SBIN, BB_SUID_DROP)) | 20 | //kbuild:lib-$(CONFIG_LOSETUP) += losetup.o |
21 | 21 | ||
22 | //usage:#define losetup_trivial_usage | 22 | //usage:#define losetup_trivial_usage |
23 | //usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE - associate loop devices\n" | 23 | //usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE - associate loop devices\n" |
@@ -57,8 +57,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
57 | OPT_r = (1 << 4), /* must be last */ | 57 | OPT_r = (1 << 4), /* must be last */ |
58 | }; | 58 | }; |
59 | 59 | ||
60 | opt_complementary = "?2:d--ofar:a--ofr"; | 60 | opt = getopt32(argv, "^" "do:far" "\0" "?2:d--ofar:a--ofr", &opt_o); |
61 | opt = getopt32(argv, "do:far", &opt_o); | ||
62 | argv += optind; | 61 | argv += optind; |
63 | 62 | ||
64 | /* LOOPDEV */ | 63 | /* LOOPDEV */ |
diff --git a/util-linux/lspci.c b/util-linux/lspci.c index 3877deb67..0000fbfda 100644 --- a/util-linux/lspci.c +++ b/util-linux/lspci.c | |||
@@ -16,7 +16,7 @@ | |||
16 | //config: | 16 | //config: |
17 | //config: This version uses sysfs (/sys/bus/pci/devices) only. | 17 | //config: This version uses sysfs (/sys/bus/pci/devices) only. |
18 | 18 | ||
19 | //applet:IF_LSPCI(APPLET(lspci, BB_DIR_USR_BIN, BB_SUID_DROP)) | 19 | //applet:IF_LSPCI(APPLET_NOEXEC(lspci, lspci, BB_DIR_USR_BIN, BB_SUID_DROP, lspci)) |
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_LSPCI) += lspci.o | 21 | //kbuild:lib-$(CONFIG_LSPCI) += lspci.o |
22 | 22 | ||
diff --git a/util-linux/lsusb.c b/util-linux/lsusb.c index cabf047cf..33639413a 100644 --- a/util-linux/lsusb.c +++ b/util-linux/lsusb.c | |||
@@ -16,7 +16,7 @@ | |||
16 | //config: | 16 | //config: |
17 | //config: This version uses sysfs (/sys/bus/usb/devices) only. | 17 | //config: This version uses sysfs (/sys/bus/usb/devices) only. |
18 | 18 | ||
19 | //applet:IF_LSUSB(APPLET(lsusb, BB_DIR_USR_BIN, BB_SUID_DROP)) | 19 | //applet:IF_LSUSB(APPLET_NOEXEC(lsusb, lsusb, BB_DIR_USR_BIN, BB_SUID_DROP, lsusb)) |
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_LSUSB) += lsusb.o | 21 | //kbuild:lib-$(CONFIG_LSUSB) += lsusb.o |
22 | 22 | ||
diff --git a/util-linux/mesg.c b/util-linux/mesg.c index c4371eb24..91c05317e 100644 --- a/util-linux/mesg.c +++ b/util-linux/mesg.c | |||
@@ -26,7 +26,7 @@ | |||
26 | //config: If you set this option to N, "mesg y" will enable writing | 26 | //config: If you set this option to N, "mesg y" will enable writing |
27 | //config: by anybody at all. This is not recommended. | 27 | //config: by anybody at all. This is not recommended. |
28 | 28 | ||
29 | //applet:IF_MESG(APPLET(mesg, BB_DIR_USR_BIN, BB_SUID_DROP)) | 29 | //applet:IF_MESG(APPLET_NOFORK(mesg, mesg, BB_DIR_USR_BIN, BB_SUID_DROP, mesg)) |
30 | 30 | ||
31 | //kbuild:lib-$(CONFIG_MESG) += mesg.o | 31 | //kbuild:lib-$(CONFIG_MESG) += mesg.o |
32 | 32 | ||
@@ -60,10 +60,15 @@ int mesg_main(int argc UNUSED_PARAM, char **argv) | |||
60 | bb_show_usage(); | 60 | bb_show_usage(); |
61 | } | 61 | } |
62 | 62 | ||
63 | /* We are a NOFORK applet. | ||
64 | * (Not that it's very useful, but code is trivially NOFORK-safe). | ||
65 | * Play nice. Do not leak anything. | ||
66 | */ | ||
67 | |||
63 | if (!isatty(STDIN_FILENO)) | 68 | if (!isatty(STDIN_FILENO)) |
64 | bb_error_msg_and_die("not a tty"); | 69 | bb_error_msg_and_die("not a tty"); |
65 | 70 | ||
66 | xfstat(STDIN_FILENO, &sb, "stderr"); | 71 | xfstat(STDIN_FILENO, &sb, "stdin"); |
67 | if (c == 0) { | 72 | if (c == 0) { |
68 | puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); | 73 | puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n"); |
69 | return EXIT_SUCCESS; | 74 | return EXIT_SUCCESS; |
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c index 88647e9d8..69dfcd123 100644 --- a/util-linux/mkfs_minix.c +++ b/util-linux/mkfs_minix.c | |||
@@ -142,7 +142,10 @@ struct globals { | |||
142 | unsigned currently_testing; | 142 | unsigned currently_testing; |
143 | 143 | ||
144 | char root_block[BLOCK_SIZE]; | 144 | char root_block[BLOCK_SIZE]; |
145 | char superblock_buffer[BLOCK_SIZE]; | 145 | union { |
146 | char superblock_buffer[BLOCK_SIZE]; | ||
147 | struct minix_superblock SB; | ||
148 | } u; | ||
146 | char boot_block_buffer[512]; | 149 | char boot_block_buffer[512]; |
147 | unsigned short good_blocks_table[MAX_GOOD_BLOCKS]; | 150 | unsigned short good_blocks_table[MAX_GOOD_BLOCKS]; |
148 | /* check_blocks(): buffer[] was the biggest static in entire bbox */ | 151 | /* check_blocks(): buffer[] was the biggest static in entire bbox */ |
@@ -166,7 +169,7 @@ static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n) | |||
166 | #define INODE_BUF1 (((struct minix1_inode*)G.inode_buffer) - 1) | 169 | #define INODE_BUF1 (((struct minix1_inode*)G.inode_buffer) - 1) |
167 | #define INODE_BUF2 (((struct minix2_inode*)G.inode_buffer) - 1) | 170 | #define INODE_BUF2 (((struct minix2_inode*)G.inode_buffer) - 1) |
168 | 171 | ||
169 | #define SB (*(struct minix_superblock*)G.superblock_buffer) | 172 | #define SB (G.u.SB) |
170 | 173 | ||
171 | #define SB_INODES (SB.s_ninodes) | 174 | #define SB_INODES (SB.s_ninodes) |
172 | #define SB_IMAPS (SB.s_imap_blocks) | 175 | #define SB_IMAPS (SB.s_imap_blocks) |
@@ -234,7 +237,7 @@ static void write_tables(void) | |||
234 | xlseek(dev_fd, BLOCK_SIZE, SEEK_SET); | 237 | xlseek(dev_fd, BLOCK_SIZE, SEEK_SET); |
235 | 238 | ||
236 | msg_eol = "can't write superblock"; | 239 | msg_eol = "can't write superblock"; |
237 | xwrite(dev_fd, G.superblock_buffer, BLOCK_SIZE); | 240 | xwrite(dev_fd, G.u.superblock_buffer, BLOCK_SIZE); |
238 | 241 | ||
239 | msg_eol = "can't write inode map"; | 242 | msg_eol = "can't write inode map"; |
240 | xwrite(dev_fd, G.inode_map, SB_IMAPS * BLOCK_SIZE); | 243 | xwrite(dev_fd, G.inode_map, SB_IMAPS * BLOCK_SIZE); |
@@ -541,7 +544,7 @@ static void setup_tables(void) | |||
541 | unsigned sb_zmaps; | 544 | unsigned sb_zmaps; |
542 | unsigned i; | 545 | unsigned i; |
543 | 546 | ||
544 | /* memset(G.superblock_buffer, 0, BLOCK_SIZE); */ | 547 | /* memset(G.u.superblock_buffer, 0, BLOCK_SIZE); */ |
545 | /* memset(G.boot_block_buffer, 0, 512); */ | 548 | /* memset(G.boot_block_buffer, 0, 512); */ |
546 | SB_MAGIC = G.magic; | 549 | SB_MAGIC = G.magic; |
547 | SB_ZONE_SIZE = 0; | 550 | SB_ZONE_SIZE = 0; |
diff --git a/util-linux/mkfs_reiser.c b/util-linux/mkfs_reiser.c index c7d99b018..390aef86c 100644 --- a/util-linux/mkfs_reiser.c +++ b/util-linux/mkfs_reiser.c | |||
@@ -180,8 +180,7 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv) | |||
180 | 180 | ||
181 | // using global "option_mask32" instead of local "opts": | 181 | // using global "option_mask32" instead of local "opts": |
182 | // we are register starved here | 182 | // we are register starved here |
183 | opt_complementary = "-1"; | 183 | /*opts =*/ getopt32(argv, "^" "b:+j:s:o:t:B:h:u:l:fqd" "\0" "-1", |
184 | /*opts =*/ getopt32(argv, "b:+j:s:o:t:B:h:u:l:fqd", | ||
185 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label); | 184 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &label); |
186 | argv += optind; // argv[0] -- device | 185 | argv += optind; // argv[0] -- device |
187 | 186 | ||
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index f9768ed56..426854b1e 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c | |||
@@ -269,8 +269,9 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
269 | OPT_v = 1 << 16, // verbose | 269 | OPT_v = 1 << 16, // verbose |
270 | }; | 270 | }; |
271 | 271 | ||
272 | opt_complementary = "-1";//:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c"; | 272 | opts = getopt32(argv, "^" |
273 | opts = getopt32(argv, "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v", | 273 | "Ab:cCf:F:h:Ii:l:m:n:r:R:s:S:v" |
274 | "\0" "-1", //:b+:f+:F+:h+:r+:R+:s+:S+:vv:c--l:l--c | ||
274 | NULL, NULL, NULL, NULL, NULL, | 275 | NULL, NULL, NULL, NULL, NULL, |
275 | NULL, NULL, &volume_label, NULL, NULL, NULL, NULL); | 276 | NULL, NULL, &volume_label, NULL, NULL, NULL, NULL); |
276 | argv += optind; | 277 | argv += optind; |
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c index e44e13c0d..71449882d 100644 --- a/util-linux/mkswap.c +++ b/util-linux/mkswap.c | |||
@@ -119,9 +119,8 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv) | |||
119 | 119 | ||
120 | INIT_G(); | 120 | INIT_G(); |
121 | 121 | ||
122 | opt_complementary = "-1"; /* at least one param */ | ||
123 | /* TODO: -p PAGESZ, -U UUID */ | 122 | /* TODO: -p PAGESZ, -U UUID */ |
124 | getopt32(argv, "L:", &label); | 123 | getopt32(argv, "^" "L:" "\0" "-1"/*at least one arg*/, &label); |
125 | argv += optind; | 124 | argv += optind; |
126 | 125 | ||
127 | fd = xopen(argv[0], O_WRONLY); | 126 | fd = xopen(argv[0], O_WRONLY); |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 4d5c2243a..4eade0869 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -69,7 +69,6 @@ | |||
69 | //config: bool "Support mounting NFS file systems on Linux < 2.6.23" | 69 | //config: bool "Support mounting NFS file systems on Linux < 2.6.23" |
70 | //config: default n | 70 | //config: default n |
71 | //config: depends on MOUNT | 71 | //config: depends on MOUNT |
72 | //config: select FEATURE_HAVE_RPC | ||
73 | //config: select FEATURE_SYSLOG | 72 | //config: select FEATURE_SYSLOG |
74 | //config: help | 73 | //config: help |
75 | //config: Enable mounting of NFS file systems on Linux kernels prior | 74 | //config: Enable mounting of NFS file systems on Linux kernels prior |
@@ -2205,10 +2204,14 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2205 | 2204 | ||
2206 | // Parse remaining options | 2205 | // Parse remaining options |
2207 | // Max 2 params; -o is a list, -v is a counter | 2206 | // Max 2 params; -o is a list, -v is a counter |
2208 | opt_complementary = "?2" IF_FEATURE_MOUNT_VERBOSE("vv"); | 2207 | opt = getopt32(argv, "^" |
2209 | opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch | 2208 | OPTION_STR |
2210 | IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) | 2209 | "\0" "?2"IF_FEATURE_MOUNT_VERBOSE("vv"), |
2211 | IF_FEATURE_MOUNT_VERBOSE(, &verbose)); | 2210 | &lst_o, &fstype, &O_optmatch |
2211 | IF_FEATURE_MOUNT_OTHERTAB(, &fstabname) | ||
2212 | IF_FEATURE_MOUNT_VERBOSE(, &verbose) | ||
2213 | ); | ||
2214 | |||
2212 | while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o | 2215 | while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o |
2213 | if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r | 2216 | if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r |
2214 | if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w | 2217 | if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w |
diff --git a/util-linux/mountpoint.c b/util-linux/mountpoint.c index b7f048196..6b21a5fb3 100644 --- a/util-linux/mountpoint.c +++ b/util-linux/mountpoint.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //config: help | 14 | //config: help |
15 | //config: mountpoint checks if the directory is a mountpoint. | 15 | //config: mountpoint checks if the directory is a mountpoint. |
16 | 16 | ||
17 | //applet:IF_MOUNTPOINT(APPLET(mountpoint, BB_DIR_BIN, BB_SUID_DROP)) | 17 | //applet:IF_MOUNTPOINT(APPLET_NOEXEC(mountpoint, mountpoint, BB_DIR_BIN, BB_SUID_DROP, mountpoint)) |
18 | 18 | ||
19 | //kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o | 19 | //kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o |
20 | 20 | ||
@@ -43,8 +43,7 @@ int mountpoint_main(int argc UNUSED_PARAM, char **argv) | |||
43 | char *arg; | 43 | char *arg; |
44 | int rc, opt; | 44 | int rc, opt; |
45 | 45 | ||
46 | opt_complementary = "=1"; /* must have one argument */ | 46 | opt = getopt32(argv, "^" "qdxn" "\0" "=1"); |
47 | opt = getopt32(argv, "qdxn"); | ||
48 | #define OPT_q (1) | 47 | #define OPT_q (1) |
49 | #define OPT_d (2) | 48 | #define OPT_d (2) |
50 | #define OPT_x (4) | 49 | #define OPT_x (4) |
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index 12c86b0ed..d91b0b509 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c | |||
@@ -13,14 +13,6 @@ | |||
13 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
14 | //config: help | 14 | //config: help |
15 | //config: Run program with namespaces of other processes. | 15 | //config: Run program with namespaces of other processes. |
16 | //config: | ||
17 | //config:config FEATURE_NSENTER_LONG_OPTS | ||
18 | //config: bool "Enable long options" | ||
19 | //config: default y | ||
20 | //config: depends on NSENTER && LONG_OPTS | ||
21 | //config: help | ||
22 | //config: Support long options for the nsenter applet. This makes | ||
23 | //config: the busybox implementation more compatible with upstream. | ||
24 | 16 | ||
25 | //applet:IF_NSENTER(APPLET(nsenter, BB_DIR_USR_BIN, BB_SUID_DROP)) | 17 | //applet:IF_NSENTER(APPLET(nsenter, BB_DIR_USR_BIN, BB_SUID_DROP)) |
26 | 18 | ||
@@ -28,22 +20,6 @@ | |||
28 | 20 | ||
29 | //usage:#define nsenter_trivial_usage | 21 | //usage:#define nsenter_trivial_usage |
30 | //usage: "[OPTIONS] [PROG [ARGS]]" | 22 | //usage: "[OPTIONS] [PROG [ARGS]]" |
31 | //usage:#if ENABLE_FEATURE_NSENTER_LONG_OPTS | ||
32 | //usage:#define nsenter_full_usage "\n" | ||
33 | //usage: "\n -t,--target PID Target process to get namespaces from" | ||
34 | //usage: "\n -m,--mount[=FILE] Enter mount namespace" | ||
35 | //usage: "\n -u,--uts[=FILE] Enter UTS namespace (hostname etc)" | ||
36 | //usage: "\n -i,--ipc[=FILE] Enter System V IPC namespace" | ||
37 | //usage: "\n -n,--net[=FILE] Enter network namespace" | ||
38 | //usage: "\n -p,--pid[=FILE] Enter pid namespace" | ||
39 | //usage: "\n -U,--user[=FILE] Enter user namespace" | ||
40 | //usage: "\n -S,--setuid UID Set uid in entered namespace" | ||
41 | //usage: "\n -G,--setgid GID Set gid in entered namespace" | ||
42 | //usage: "\n --preserve-credentials Don't touch uids or gids" | ||
43 | //usage: "\n -r,--root[=DIR] Set root directory" | ||
44 | //usage: "\n -w,--wd[=DIR] Set working directory" | ||
45 | //usage: "\n -F,--no-fork Don't fork before exec'ing PROG" | ||
46 | //usage:#else | ||
47 | //usage:#define nsenter_full_usage "\n" | 23 | //usage:#define nsenter_full_usage "\n" |
48 | //usage: "\n -t PID Target process to get namespaces from" | 24 | //usage: "\n -t PID Target process to get namespaces from" |
49 | //usage: "\n -m[FILE] Enter mount namespace" | 25 | //usage: "\n -m[FILE] Enter mount namespace" |
@@ -54,10 +30,12 @@ | |||
54 | //usage: "\n -U[FILE] Enter user namespace" | 30 | //usage: "\n -U[FILE] Enter user namespace" |
55 | //usage: "\n -S UID Set uid in entered namespace" | 31 | //usage: "\n -S UID Set uid in entered namespace" |
56 | //usage: "\n -G GID Set gid in entered namespace" | 32 | //usage: "\n -G GID Set gid in entered namespace" |
33 | //usage: IF_LONG_OPTS( | ||
34 | //usage: "\n --preserve-credentials Don't touch uids or gids" | ||
35 | //usage: ) | ||
57 | //usage: "\n -r[DIR] Set root directory" | 36 | //usage: "\n -r[DIR] Set root directory" |
58 | //usage: "\n -w[DIR] Set working directory" | 37 | //usage: "\n -w[DIR] Set working directory" |
59 | //usage: "\n -F Don't fork before exec'ing PROG" | 38 | //usage: "\n -F Don't fork before exec'ing PROG" |
60 | //usage:#endif | ||
61 | 39 | ||
62 | #include <sched.h> | 40 | #include <sched.h> |
63 | #ifndef CLONE_NEWUTS | 41 | #ifndef CLONE_NEWUTS |
@@ -101,7 +79,7 @@ enum { | |||
101 | OPT_root = 1 << 9, | 79 | OPT_root = 1 << 9, |
102 | OPT_wd = 1 << 10, | 80 | OPT_wd = 1 << 10, |
103 | OPT_nofork = 1 << 11, | 81 | OPT_nofork = 1 << 11, |
104 | OPT_prescred = (1 << 12) * ENABLE_FEATURE_NSENTER_LONG_OPTS, | 82 | OPT_prescred = (1 << 12) * ENABLE_LONG_OPTS, |
105 | }; | 83 | }; |
106 | enum { | 84 | enum { |
107 | NS_USR_POS = 0, | 85 | NS_USR_POS = 0, |
@@ -130,7 +108,7 @@ static const struct namespace_descr ns_list[] = { | |||
130 | */ | 108 | */ |
131 | static const char opt_str[] ALIGN1 = "U::i::u::n::p::m::""t+S+G+r::w::F"; | 109 | static const char opt_str[] ALIGN1 = "U::i::u::n::p::m::""t+S+G+r::w::F"; |
132 | 110 | ||
133 | #if ENABLE_FEATURE_NSENTER_LONG_OPTS | 111 | #if ENABLE_LONG_OPTS |
134 | static const char nsenter_longopts[] ALIGN1 = | 112 | static const char nsenter_longopts[] ALIGN1 = |
135 | "user\0" Optional_argument "U" | 113 | "user\0" Optional_argument "U" |
136 | "ipc\0" Optional_argument "i" | 114 | "ipc\0" Optional_argument "i" |
@@ -190,8 +168,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) | |||
190 | 168 | ||
191 | memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); | 169 | memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); |
192 | 170 | ||
193 | IF_FEATURE_NSENTER_LONG_OPTS(applet_long_options = nsenter_longopts); | 171 | opts = getopt32long(argv, opt_str, nsenter_longopts, |
194 | opts = getopt32(argv, opt_str, | ||
195 | &ns_ctx_list[NS_USR_POS].path, | 172 | &ns_ctx_list[NS_USR_POS].path, |
196 | &ns_ctx_list[NS_IPC_POS].path, | 173 | &ns_ctx_list[NS_IPC_POS].path, |
197 | &ns_ctx_list[NS_UTS_POS].path, | 174 | &ns_ctx_list[NS_UTS_POS].path, |
diff --git a/util-linux/pivot_root.c b/util-linux/pivot_root.c index 331038057..d6a26b912 100644 --- a/util-linux/pivot_root.c +++ b/util-linux/pivot_root.c | |||
@@ -21,7 +21,7 @@ | |||
21 | //config: Note: This is for initrd in linux 2.4. Under initramfs (introduced | 21 | //config: Note: This is for initrd in linux 2.4. Under initramfs (introduced |
22 | //config: in linux 2.6) use switch_root instead. | 22 | //config: in linux 2.6) use switch_root instead. |
23 | 23 | ||
24 | //applet:IF_PIVOT_ROOT(APPLET(pivot_root, BB_DIR_SBIN, BB_SUID_DROP)) | 24 | //applet:IF_PIVOT_ROOT(APPLET_NOFORK(pivot_root, pivot_root, BB_DIR_SBIN, BB_SUID_DROP, pivot_root)) |
25 | 25 | ||
26 | //kbuild:lib-$(CONFIG_PIVOT_ROOT) += pivot_root.o | 26 | //kbuild:lib-$(CONFIG_PIVOT_ROOT) += pivot_root.o |
27 | 27 | ||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #include "libbb.h" | 34 | #include "libbb.h" |
35 | 35 | ||
36 | extern int pivot_root(const char * new_root,const char * put_old); | 36 | extern int pivot_root(const char *new_root, const char *put_old); |
37 | 37 | ||
38 | int pivot_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 38 | int pivot_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
39 | int pivot_root_main(int argc, char **argv) | 39 | int pivot_root_main(int argc, char **argv) |
@@ -41,6 +41,8 @@ int pivot_root_main(int argc, char **argv) | |||
41 | if (argc != 3) | 41 | if (argc != 3) |
42 | bb_show_usage(); | 42 | bb_show_usage(); |
43 | 43 | ||
44 | /* NOFORK applet. Hardly matters wrt performance, but code is trivial */ | ||
45 | |||
44 | if (pivot_root(argv[1], argv[2]) < 0) { | 46 | if (pivot_root(argv[1], argv[2]) < 0) { |
45 | /* prints "pivot_root: <strerror text>" */ | 47 | /* prints "pivot_root: <strerror text>" */ |
46 | bb_perror_nomsg_and_die(); | 48 | bb_perror_nomsg_and_die(); |
diff --git a/util-linux/rdate.c b/util-linux/rdate.c index 14ce591e9..f27294e25 100644 --- a/util-linux/rdate.c +++ b/util-linux/rdate.c | |||
@@ -81,8 +81,7 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) | |||
81 | time_t remote_time; | 81 | time_t remote_time; |
82 | unsigned flags; | 82 | unsigned flags; |
83 | 83 | ||
84 | opt_complementary = "-1"; | 84 | flags = getopt32(argv, "^" "sp" "\0" "-1"); |
85 | flags = getopt32(argv, "sp"); | ||
86 | 85 | ||
87 | remote_time = askremotedate(argv[optind]); | 86 | remote_time = askremotedate(argv[optind]); |
88 | 87 | ||
diff --git a/util-linux/rdev.c b/util-linux/rdev.c index 2ffe07688..7eb7413a8 100644 --- a/util-linux/rdev.c +++ b/util-linux/rdev.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //config: help | 14 | //config: help |
15 | //config: Print the device node associated with the filesystem mounted at '/'. | 15 | //config: Print the device node associated with the filesystem mounted at '/'. |
16 | 16 | ||
17 | //applet:IF_RDEV(APPLET(rdev, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 17 | //applet:IF_RDEV(APPLET_NOEXEC(rdev, rdev, BB_DIR_USR_SBIN, BB_SUID_DROP, rdev)) |
18 | 18 | ||
19 | //kbuild:lib-$(CONFIG_RDEV) += rdev.o | 19 | //kbuild:lib-$(CONFIG_RDEV) += rdev.o |
20 | 20 | ||
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c index b045657d8..394ece1dd 100644 --- a/util-linux/readprofile.c +++ b/util-linux/readprofile.c | |||
@@ -266,8 +266,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) | |||
266 | printf("%6u %-40s %8.4f\n", | 266 | printf("%6u %-40s %8.4f\n", |
267 | total, "total", total/(double)(fn_add-add0)); | 267 | total, "total", total/(double)(fn_add-add0)); |
268 | 268 | ||
269 | fclose(map); | 269 | if (ENABLE_FEATURE_CLEAN_UP) { |
270 | free(buf); | 270 | fclose(map); |
271 | free(buf); | ||
272 | } | ||
271 | 273 | ||
272 | return EXIT_SUCCESS; | 274 | return EXIT_SUCCESS; |
273 | } | 275 | } |
diff --git a/util-linux/renice.c b/util-linux/renice.c index 23cbca88d..70c494b3d 100644 --- a/util-linux/renice.c +++ b/util-linux/renice.c | |||
@@ -25,7 +25,7 @@ | |||
25 | //config: Renice alters the scheduling priority of one or more running | 25 | //config: Renice alters the scheduling priority of one or more running |
26 | //config: processes. | 26 | //config: processes. |
27 | 27 | ||
28 | //applet:IF_RENICE(APPLET(renice, BB_DIR_USR_BIN, BB_SUID_DROP)) | 28 | //applet:IF_RENICE(APPLET_NOEXEC(renice, renice, BB_DIR_USR_BIN, BB_SUID_DROP, renice)) |
29 | 29 | ||
30 | //kbuild:lib-$(CONFIG_RENICE) += renice.o | 30 | //kbuild:lib-$(CONFIG_RENICE) += renice.o |
31 | 31 | ||
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c index 4c47c5369..8ffa4f3a6 100644 --- a/util-linux/rtcwake.c +++ b/util-linux/rtcwake.c | |||
@@ -154,11 +154,11 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv) | |||
154 | "seconds\0" Required_argument "s" | 154 | "seconds\0" Required_argument "s" |
155 | "time\0" Required_argument "t" | 155 | "time\0" Required_argument "t" |
156 | ; | 156 | ; |
157 | applet_long_options = rtcwake_longopts; | ||
158 | #endif | 157 | #endif |
159 | /* Must have -s or -t, exclusive */ | 158 | opt = getopt32long(argv, |
160 | opt_complementary = "s:t:s--t:t--s"; | 159 | /* Must have -s or -t, exclusive */ |
161 | opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time); | 160 | "^alud:m:s:t:" "\0" "s:t:s--t:t--s", rtcwake_longopts, |
161 | &rtcname, &suspend, &opt_seconds, &opt_time); | ||
162 | 162 | ||
163 | /* this is the default | 163 | /* this is the default |
164 | if (opt & RTCWAKE_OPT_AUTO) | 164 | if (opt & RTCWAKE_OPT_AUTO) |
diff --git a/util-linux/script.c b/util-linux/script.c index 9eebb51a4..aac77c3ba 100644 --- a/util-linux/script.c +++ b/util-linux/script.c | |||
@@ -21,15 +21,25 @@ | |||
21 | //kbuild:lib-$(CONFIG_SCRIPT) += script.o | 21 | //kbuild:lib-$(CONFIG_SCRIPT) += script.o |
22 | 22 | ||
23 | //usage:#define script_trivial_usage | 23 | //usage:#define script_trivial_usage |
24 | //usage: "[-afq" IF_SCRIPTREPLAY("t") "] [-c PROG] [OUTFILE]" | 24 | //usage: "[-afq] [-t[FILE]] [-c PROG] [OUTFILE]" |
25 | //usage:#define script_full_usage "\n\n" | 25 | //usage:#define script_full_usage "\n\n" |
26 | //usage: " -a Append output" | 26 | //usage: "Default OUTFILE is 'typescript'" |
27 | //usage: "\n" | ||
28 | //usage: "\n -a Append output" | ||
27 | //usage: "\n -c PROG Run PROG, not shell" | 29 | //usage: "\n -c PROG Run PROG, not shell" |
28 | //usage: "\n -f Flush output after each write" | 30 | /* Accepted but has no effect (we never buffer output) */ |
31 | /*//usage: "\n -f Flush output after each write"*/ | ||
29 | //usage: "\n -q Quiet" | 32 | //usage: "\n -q Quiet" |
30 | //usage: IF_SCRIPTREPLAY( | 33 | //usage: "\n -t[FILE] Send timing to stderr or FILE" |
31 | //usage: "\n -t Send timing to stderr" | 34 | |
32 | //usage: ) | 35 | //util-linux-2.28: |
36 | //-e: return exit code of the child | ||
37 | |||
38 | //FYI (reported as bbox bug #2749): | ||
39 | // > script -q -c 'echo -e -n "1\n2\n3\n"' /dev/null </dev/null >123.txt | ||
40 | // > The output file on full-blown ubuntu system contains 6 bytes. | ||
41 | // > Output on Busybox system (arm-linux) contains extra '\r' byte in each line. | ||
42 | //however, in my test, "script" from util-linux-2.28 seems to also add '\r' bytes. | ||
33 | 43 | ||
34 | #include "libbb.h" | 44 | #include "libbb.h" |
35 | #include "common_bufsiz.h" | 45 | #include "common_bufsiz.h" |
@@ -46,6 +56,8 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
46 | char pty_line[GETPTY_BUFSIZE]; | 56 | char pty_line[GETPTY_BUFSIZE]; |
47 | struct termios tt, rtt; | 57 | struct termios tt, rtt; |
48 | struct winsize win; | 58 | struct winsize win; |
59 | FILE *timing_fp; | ||
60 | const char *str_t = NULL; | ||
49 | const char *fname = "typescript"; | 61 | const char *fname = "typescript"; |
50 | const char *shell; | 62 | const char *shell; |
51 | char shell_opt[] = "-i"; | 63 | char shell_opt[] = "-i"; |
@@ -59,19 +71,19 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
59 | }; | 71 | }; |
60 | 72 | ||
61 | #if ENABLE_LONG_OPTS | 73 | #if ENABLE_LONG_OPTS |
62 | static const char getopt_longopts[] ALIGN1 = | 74 | static const char script_longopts[] ALIGN1 = |
63 | "append\0" No_argument "a" | 75 | "append\0" No_argument "a" |
64 | "command\0" Required_argument "c" | 76 | "command\0" Required_argument "c" |
65 | "flush\0" No_argument "f" | 77 | "flush\0" No_argument "f" |
66 | "quiet\0" No_argument "q" | 78 | "quiet\0" No_argument "q" |
67 | IF_SCRIPTREPLAY("timing\0" No_argument "t") | 79 | "timing\0" Optional_argument "t" |
68 | ; | 80 | ; |
69 | |||
70 | applet_long_options = getopt_longopts; | ||
71 | #endif | 81 | #endif |
72 | 82 | ||
73 | opt_complementary = "?1"; /* max one arg */ | 83 | opt = getopt32long(argv, "^" "ac:fqt::" "\0" "?1"/* max one arg */, |
74 | opt = getopt32(argv, "ac:fq" IF_SCRIPTREPLAY("t") , &shell_arg); | 84 | script_longopts, |
85 | &shell_arg, &str_t | ||
86 | ); | ||
75 | //argc -= optind; | 87 | //argc -= optind; |
76 | argv += optind; | 88 | argv += optind; |
77 | if (argv[0]) { | 89 | if (argv[0]) { |
@@ -87,6 +99,10 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
87 | if (!(opt & OPT_q)) { | 99 | if (!(opt & OPT_q)) { |
88 | printf("Script started, file is %s\n", fname); | 100 | printf("Script started, file is %s\n", fname); |
89 | } | 101 | } |
102 | timing_fp = stderr; | ||
103 | if (str_t) { | ||
104 | timing_fp = xfopen_for_write(str_t); | ||
105 | } | ||
90 | 106 | ||
91 | shell = get_shell_name(); | 107 | shell = get_shell_name(); |
92 | 108 | ||
@@ -120,8 +136,9 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
120 | /* parent */ | 136 | /* parent */ |
121 | struct pollfd pfd[2]; | 137 | struct pollfd pfd[2]; |
122 | int outfd, count, loop; | 138 | int outfd, count, loop; |
123 | double oldtime = ENABLE_SCRIPTREPLAY ? time(NULL) : 0; | 139 | double oldtime = time(NULL); |
124 | smallint fd_count = 2; | 140 | smallint fd_count = 2; |
141 | |||
125 | #define buf bb_common_bufsiz1 | 142 | #define buf bb_common_bufsiz1 |
126 | setup_common_bufsiz(); | 143 | setup_common_bufsiz(); |
127 | 144 | ||
@@ -151,20 +168,21 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
151 | goto restore; | 168 | goto restore; |
152 | } | 169 | } |
153 | if (count > 0) { | 170 | if (count > 0) { |
154 | if (ENABLE_SCRIPTREPLAY && (opt & OPT_t)) { | 171 | if (opt & OPT_t) { |
155 | struct timeval tv; | 172 | struct timeval tv; |
156 | double newtime; | 173 | double newtime; |
157 | 174 | ||
158 | gettimeofday(&tv, NULL); | 175 | gettimeofday(&tv, NULL); |
159 | newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; | 176 | newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; |
160 | fprintf(stderr, "%f %u\n", newtime - oldtime, count); | 177 | fprintf(timing_fp, "%f %u\n", newtime - oldtime, count); |
161 | oldtime = newtime; | 178 | oldtime = newtime; |
162 | } | 179 | } |
163 | full_write(STDOUT_FILENO, buf, count); | 180 | full_write(STDOUT_FILENO, buf, count); |
164 | full_write(outfd, buf, count); | 181 | full_write(outfd, buf, count); |
165 | if (opt & OPT_f) { | 182 | // If we'd be using (buffered) FILE i/o, we'd need this: |
166 | fsync(outfd); | 183 | //if (opt & OPT_f) { |
167 | } | 184 | // fflush(outfd); |
185 | //} | ||
168 | } | 186 | } |
169 | } | 187 | } |
170 | if (pfd[1].revents) { | 188 | if (pfd[1].revents) { |
diff --git a/util-linux/scriptreplay.c b/util-linux/scriptreplay.c index 7e9850103..e3083ab93 100644 --- a/util-linux/scriptreplay.c +++ b/util-linux/scriptreplay.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * pascal.bellard@ads-lu.com | 5 | * pascal.bellard@ads-lu.com |
6 | * | 6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | * | ||
9 | */ | 8 | */ |
10 | //config:config SCRIPTREPLAY | 9 | //config:config SCRIPTREPLAY |
11 | //config: bool "scriptreplay (2.6 kb)" | 10 | //config: bool "scriptreplay (2.6 kb)" |
@@ -19,7 +18,7 @@ | |||
19 | //kbuild:lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o | 18 | //kbuild:lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o |
20 | 19 | ||
21 | //usage:#define scriptreplay_trivial_usage | 20 | //usage:#define scriptreplay_trivial_usage |
22 | //usage: "timingfile [typescript [divisor]]" | 21 | //usage: "TIMINGFILE [TYPESCRIPT [DIVISOR]]" |
23 | //usage:#define scriptreplay_full_usage "\n\n" | 22 | //usage:#define scriptreplay_full_usage "\n\n" |
24 | //usage: "Play back typescripts, using timing information" | 23 | //usage: "Play back typescripts, using timing information" |
25 | 24 | ||
diff --git a/util-linux/setarch.c b/util-linux/setarch.c index d4b568832..520865318 100644 --- a/util-linux/setarch.c +++ b/util-linux/setarch.c | |||
@@ -30,10 +30,10 @@ | |||
30 | //config: help | 30 | //config: help |
31 | //config: Alias to "setarch linux64". | 31 | //config: Alias to "setarch linux64". |
32 | 32 | ||
33 | //applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) | 33 | //applet:IF_SETARCH(APPLET_NOEXEC(setarch, setarch, BB_DIR_BIN, BB_SUID_DROP, setarch)) |
34 | // APPLET_ODDNAME:name main location suid_type help | 34 | // APPLET_NOEXEC:name main location suid_type help |
35 | //applet:IF_LINUX32(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) | 35 | //applet:IF_LINUX32(APPLET_NOEXEC(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) |
36 | //applet:IF_LINUX64(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) | 36 | //applet:IF_LINUX64(APPLET_NOEXEC(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) |
37 | 37 | ||
38 | //kbuild:lib-$(CONFIG_SETARCH) += setarch.o | 38 | //kbuild:lib-$(CONFIG_SETARCH) += setarch.o |
39 | //kbuild:lib-$(CONFIG_LINUX32) += setarch.o | 39 | //kbuild:lib-$(CONFIG_LINUX32) += setarch.o |
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c index 0f85428ab..12ab1bd66 100644 --- a/util-linux/setpriv.c +++ b/util-linux/setpriv.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * Copyright (C) 2017 by <assafgordon@gmail.com> | 5 | * Copyright (C) 2017 by <assafgordon@gmail.com> |
6 | * | 6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | * | ||
9 | */ | 8 | */ |
10 | //config:config SETPRIV | 9 | //config:config SETPRIV |
11 | //config: bool "setpriv (3.4 kb)" | 10 | //config: bool "setpriv (3.4 kb)" |
@@ -125,96 +124,10 @@ enum { | |||
125 | }; | 124 | }; |
126 | 125 | ||
127 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | 126 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES |
128 | struct caps { | 127 | DEFINE_STRUCT_CAPS; |
129 | struct __user_cap_header_struct header; | ||
130 | cap_user_data_t data; | ||
131 | int u32s; | ||
132 | }; | ||
133 | |||
134 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
135 | static const char *const capabilities[] = { | ||
136 | "chown", | ||
137 | "dac_override", | ||
138 | "dac_read_search", | ||
139 | "fowner", | ||
140 | "fsetid", | ||
141 | "kill", | ||
142 | "setgid", | ||
143 | "setuid", | ||
144 | "setpcap", | ||
145 | "linux_immutable", | ||
146 | "net_bind_service", | ||
147 | "net_broadcast", | ||
148 | "net_admin", | ||
149 | "net_raw", | ||
150 | "ipc_lock", | ||
151 | "ipc_owner", | ||
152 | "sys_module", | ||
153 | "sys_rawio", | ||
154 | "sys_chroot", | ||
155 | "sys_ptrace", | ||
156 | "sys_pacct", | ||
157 | "sys_admin", | ||
158 | "sys_boot", | ||
159 | "sys_nice", | ||
160 | "sys_resource", | ||
161 | "sys_time", | ||
162 | "sys_tty_config", | ||
163 | "mknod", | ||
164 | "lease", | ||
165 | "audit_write", | ||
166 | "audit_control", | ||
167 | "setfcap", | ||
168 | "mac_override", | ||
169 | "mac_admin", | ||
170 | "syslog", | ||
171 | "wake_alarm", | ||
172 | "block_suspend", | ||
173 | "audit_read", | ||
174 | }; | ||
175 | # endif /* FEATURE_SETPRIV_CAPABILITY_NAMES */ | ||
176 | 128 | ||
177 | static void getcaps(struct caps *caps) | 129 | static unsigned parse_cap(const char *cap) |
178 | { | 130 | { |
179 | static const uint8_t versions[] = { | ||
180 | _LINUX_CAPABILITY_U32S_3, /* = 2 (fits into byte) */ | ||
181 | _LINUX_CAPABILITY_U32S_2, /* = 2 */ | ||
182 | _LINUX_CAPABILITY_U32S_1, /* = 1 */ | ||
183 | }; | ||
184 | int i; | ||
185 | |||
186 | caps->header.pid = 0; | ||
187 | for (i = 0; i < ARRAY_SIZE(versions); i++) { | ||
188 | caps->header.version = versions[i]; | ||
189 | if (capget(&caps->header, NULL) == 0) | ||
190 | goto got_it; | ||
191 | } | ||
192 | bb_simple_perror_msg_and_die("capget"); | ||
193 | got_it: | ||
194 | |||
195 | switch (caps->header.version) { | ||
196 | case _LINUX_CAPABILITY_VERSION_1: | ||
197 | caps->u32s = _LINUX_CAPABILITY_U32S_1; | ||
198 | break; | ||
199 | case _LINUX_CAPABILITY_VERSION_2: | ||
200 | caps->u32s = _LINUX_CAPABILITY_U32S_2; | ||
201 | break; | ||
202 | case _LINUX_CAPABILITY_VERSION_3: | ||
203 | caps->u32s = _LINUX_CAPABILITY_U32S_3; | ||
204 | break; | ||
205 | default: | ||
206 | bb_error_msg_and_die("unsupported capability version"); | ||
207 | } | ||
208 | |||
209 | caps->data = xmalloc(sizeof(caps->data[0]) * caps->u32s); | ||
210 | if (capget(&caps->header, caps->data) < 0) | ||
211 | bb_simple_perror_msg_and_die("capget"); | ||
212 | } | ||
213 | |||
214 | static void parse_cap(unsigned long *index, const char *cap) | ||
215 | { | ||
216 | unsigned long i; | ||
217 | |||
218 | switch (cap[0]) { | 131 | switch (cap[0]) { |
219 | case '-': | 132 | case '-': |
220 | break; | 133 | break; |
@@ -226,26 +139,7 @@ static void parse_cap(unsigned long *index, const char *cap) | |||
226 | } | 139 | } |
227 | 140 | ||
228 | cap++; | 141 | cap++; |
229 | if ((sscanf(cap, "cap_%lu", &i)) == 1) { | 142 | return cap_name_to_number(cap); |
230 | if (!cap_valid(i)) | ||
231 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
232 | *index = i; | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
237 | for (i = 0; i < ARRAY_SIZE(capabilities); i++) { | ||
238 | if (strcmp(capabilities[i], cap) != 0) | ||
239 | continue; | ||
240 | |||
241 | if (!cap_valid(i)) | ||
242 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
243 | *index = i; | ||
244 | return; | ||
245 | } | ||
246 | # endif | ||
247 | |||
248 | bb_error_msg_and_die("unknown capability '%s'", cap); | ||
249 | } | 143 | } |
250 | 144 | ||
251 | static void set_inh_caps(char *capstring) | 145 | static void set_inh_caps(char *capstring) |
@@ -256,11 +150,11 @@ static void set_inh_caps(char *capstring) | |||
256 | 150 | ||
257 | capstring = strtok(capstring, ","); | 151 | capstring = strtok(capstring, ","); |
258 | while (capstring) { | 152 | while (capstring) { |
259 | unsigned long cap; | 153 | unsigned cap; |
260 | 154 | ||
261 | parse_cap(&cap, capstring); | 155 | cap = parse_cap(capstring); |
262 | if (CAP_TO_INDEX(cap) >= caps.u32s) | 156 | if (CAP_TO_INDEX(cap) >= caps.u32s) |
263 | bb_error_msg_and_die("invalid capability cap"); | 157 | bb_error_msg_and_die("invalid capability '%s'", capstring); |
264 | 158 | ||
265 | if (capstring[0] == '+') | 159 | if (capstring[0] == '+') |
266 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | 160 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); |
@@ -269,11 +163,8 @@ static void set_inh_caps(char *capstring) | |||
269 | capstring = strtok(NULL, ","); | 163 | capstring = strtok(NULL, ","); |
270 | } | 164 | } |
271 | 165 | ||
272 | if ((capset(&caps.header, caps.data)) < 0) | 166 | if (capset(&caps.header, caps.data) != 0) |
273 | bb_perror_msg_and_die("capset"); | 167 | bb_perror_msg_and_die("capset"); |
274 | |||
275 | if (ENABLE_FEATURE_CLEAN_UP) | ||
276 | free(caps.data); | ||
277 | } | 168 | } |
278 | 169 | ||
279 | static void set_ambient_caps(char *string) | 170 | static void set_ambient_caps(char *string) |
@@ -282,9 +173,9 @@ static void set_ambient_caps(char *string) | |||
282 | 173 | ||
283 | cap = strtok(string, ","); | 174 | cap = strtok(string, ","); |
284 | while (cap) { | 175 | while (cap) { |
285 | unsigned long index; | 176 | unsigned index; |
286 | 177 | ||
287 | parse_cap(&index, cap); | 178 | index = parse_cap(cap); |
288 | if (cap[0] == '+') { | 179 | if (cap[0] == '+') { |
289 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) | 180 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) |
290 | bb_perror_msg("cap_ambient_raise"); | 181 | bb_perror_msg("cap_ambient_raise"); |
@@ -298,16 +189,7 @@ static void set_ambient_caps(char *string) | |||
298 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | 189 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ |
299 | 190 | ||
300 | #if ENABLE_FEATURE_SETPRIV_DUMP | 191 | #if ENABLE_FEATURE_SETPRIV_DUMP |
301 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | 192 | # if !ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES |
302 | static void printf_cap(const char *pfx, unsigned cap_no) | ||
303 | { | ||
304 | if (cap_no < ARRAY_SIZE(capabilities)) { | ||
305 | printf("%s%s", pfx, capabilities[cap_no]); | ||
306 | return; | ||
307 | } | ||
308 | printf("%scap_%u", pfx, cap_no); | ||
309 | } | ||
310 | # else | ||
311 | # define printf_cap(pfx, cap_no) printf("%scap_%u", (pfx), (cap_no)) | 193 | # define printf_cap(pfx, cap_no) printf("%scap_%u", (pfx), (cap_no)) |
312 | # endif | 194 | # endif |
313 | 195 | ||
@@ -396,10 +278,9 @@ static int dump(void) | |||
396 | bb_putchar('\n'); | 278 | bb_putchar('\n'); |
397 | # endif | 279 | # endif |
398 | 280 | ||
399 | if (ENABLE_FEATURE_CLEAN_UP) { | 281 | if (ENABLE_FEATURE_CLEAN_UP) |
400 | IF_FEATURE_SETPRIV_CAPABILITIES(free(caps.data);) | ||
401 | free(gids); | 282 | free(gids); |
402 | } | 283 | |
403 | return EXIT_SUCCESS; | 284 | return EXIT_SUCCESS; |
404 | } | 285 | } |
405 | #endif /* FEATURE_SETPRIV_DUMP */ | 286 | #endif /* FEATURE_SETPRIV_DUMP */ |
@@ -421,9 +302,12 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv) | |||
421 | int opts; | 302 | int opts; |
422 | IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;) | 303 | IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;) |
423 | 304 | ||
424 | applet_long_options = setpriv_longopts; | 305 | opts = getopt32long(argv, "+" |
425 | opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d") | 306 | IF_FEATURE_SETPRIV_DUMP("d") |
426 | IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:", &inh_caps, &ambient_caps)); | 307 | IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:"), |
308 | setpriv_longopts | ||
309 | IF_FEATURE_SETPRIV_CAPABILITIES(, &inh_caps, &ambient_caps) | ||
310 | ); | ||
427 | argv += optind; | 311 | argv += optind; |
428 | 312 | ||
429 | #if ENABLE_FEATURE_SETPRIV_DUMP | 313 | #if ENABLE_FEATURE_SETPRIV_DUMP |
diff --git a/util-linux/setsid.c b/util-linux/setsid.c index 60cab2fcf..8385a9115 100644 --- a/util-linux/setsid.c +++ b/util-linux/setsid.c | |||
@@ -37,8 +37,8 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) | |||
37 | { | 37 | { |
38 | unsigned opt; | 38 | unsigned opt; |
39 | 39 | ||
40 | opt_complementary = "-1"; /* at least one arg */ | 40 | /* +: stop on first non-opt */ |
41 | opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ | 41 | opt = getopt32(argv, "^+" "c" "\0" "-1"/* at least one arg */); |
42 | argv += optind; | 42 | argv += optind; |
43 | 43 | ||
44 | /* setsid() is allowed only when we are not a process group leader. | 44 | /* setsid() is allowed only when we are not a process group leader. |
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index 32708934e..080b05e45 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c | |||
@@ -24,22 +24,33 @@ | |||
24 | //config: * Because the Linux kernel uses rootfs internally as the starting | 24 | //config: * Because the Linux kernel uses rootfs internally as the starting |
25 | //config: and ending point for searching through the kernel's doubly linked | 25 | //config: and ending point for searching through the kernel's doubly linked |
26 | //config: list of active mount points. That's why. | 26 | //config: list of active mount points. That's why. |
27 | //config: | ||
28 | // RUN_INIT config item is in klibc-utils | ||
27 | 29 | ||
28 | //applet:IF_SWITCH_ROOT(APPLET(switch_root, BB_DIR_SBIN, BB_SUID_DROP)) | 30 | //applet:IF_SWITCH_ROOT(APPLET(switch_root, BB_DIR_SBIN, BB_SUID_DROP)) |
31 | // APPLET_ODDNAME:name main location suid_type help | ||
32 | //applet:IF_RUN_INIT( APPLET_ODDNAME(run-init, switch_root, BB_DIR_SBIN, BB_SUID_DROP, run_init)) | ||
29 | 33 | ||
30 | //kbuild:lib-$(CONFIG_SWITCH_ROOT) += switch_root.o | 34 | //kbuild:lib-$(CONFIG_SWITCH_ROOT) += switch_root.o |
31 | 35 | //kbuild:lib-$(CONFIG_RUN_INIT) += switch_root.o | |
32 | //usage:#define switch_root_trivial_usage | ||
33 | //usage: "[-c /dev/console] NEW_ROOT NEW_INIT [ARGS]" | ||
34 | //usage:#define switch_root_full_usage "\n\n" | ||
35 | //usage: "Free initramfs and switch to another root fs:\n" | ||
36 | //usage: "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n" | ||
37 | //usage: "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n" | ||
38 | //usage: "\n -c DEV Reopen stdio to DEV after switch" | ||
39 | 36 | ||
40 | #include <sys/vfs.h> | 37 | #include <sys/vfs.h> |
41 | #include <sys/mount.h> | 38 | #include <sys/mount.h> |
39 | #if ENABLE_RUN_INIT | ||
40 | # include <sys/prctl.h> | ||
41 | # include <linux/capability.h> | ||
42 | // #include <sys/capability.h> | ||
43 | // This header is in libcap, but the functions are in libc. | ||
44 | // Comment in the header says this above capset/capget: | ||
45 | /* system calls - look to libc for function to system call mapping */ | ||
46 | extern int capset(cap_user_header_t header, cap_user_data_t data); | ||
47 | extern int capget(cap_user_header_t header, const cap_user_data_t data); | ||
48 | // so for bbox, let's just repeat the declarations. | ||
49 | // This way, libcap needs not be installed in build environment. | ||
50 | #endif | ||
51 | |||
42 | #include "libbb.h" | 52 | #include "libbb.h" |
53 | |||
43 | // Make up for header deficiencies | 54 | // Make up for header deficiencies |
44 | #ifndef RAMFS_MAGIC | 55 | #ifndef RAMFS_MAGIC |
45 | # define RAMFS_MAGIC ((unsigned)0x858458f6) | 56 | # define RAMFS_MAGIC ((unsigned)0x858458f6) |
@@ -89,17 +100,125 @@ static void delete_contents(const char *directory, dev_t rootdev) | |||
89 | } | 100 | } |
90 | } | 101 | } |
91 | 102 | ||
103 | #if ENABLE_RUN_INIT | ||
104 | DEFINE_STRUCT_CAPS; | ||
105 | |||
106 | static void drop_capset(int cap_idx) | ||
107 | { | ||
108 | struct caps caps; | ||
109 | |||
110 | getcaps(&caps); | ||
111 | caps.data[CAP_TO_INDEX(cap_idx)].inheritable &= ~CAP_TO_MASK(cap_idx); | ||
112 | if (capset(&caps.header, caps.data) != 0) | ||
113 | bb_perror_msg_and_die("capset"); | ||
114 | } | ||
115 | |||
116 | static void drop_bounding_set(int cap_idx) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = prctl(PR_CAPBSET_READ, cap_idx, 0, 0, 0); | ||
121 | if (ret < 0) | ||
122 | bb_perror_msg_and_die("prctl: %s", "PR_CAPBSET_READ"); | ||
123 | |||
124 | if (ret == 1) { | ||
125 | ret = prctl(PR_CAPBSET_DROP, cap_idx, 0, 0, 0); | ||
126 | if (ret != 0) | ||
127 | bb_perror_msg_and_die("prctl: %s", "PR_CAPBSET_DROP"); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void drop_usermodehelper(const char *filename, int cap_idx) | ||
132 | { | ||
133 | unsigned lo, hi; | ||
134 | char buf[sizeof(int)*3 * 2 + 8]; | ||
135 | int fd; | ||
136 | int ret; | ||
137 | |||
138 | ret = open_read_close(filename, buf, sizeof(buf) - 1); | ||
139 | if (ret < 0) | ||
140 | return; /* assuming files do not exist */ | ||
141 | |||
142 | buf[ret] = '\0'; | ||
143 | ret = sscanf(buf, "%u %u", &lo, &hi); | ||
144 | if (ret != 2) | ||
145 | bb_perror_msg_and_die("can't parse file '%s'", filename); | ||
146 | |||
147 | if (cap_idx < 32) | ||
148 | lo &= ~(1 << cap_idx); | ||
149 | else | ||
150 | hi &= ~(1 << (cap_idx - 32)); | ||
151 | |||
152 | fd = xopen(filename, O_WRONLY); | ||
153 | fdprintf(fd, "%u %u", lo, hi); | ||
154 | close(fd); | ||
155 | } | ||
156 | |||
157 | static void drop_capabilities(char *string) | ||
158 | { | ||
159 | char *cap; | ||
160 | |||
161 | cap = strtok(string, ","); | ||
162 | while (cap) { | ||
163 | unsigned cap_idx; | ||
164 | |||
165 | cap_idx = cap_name_to_number(cap); | ||
166 | drop_usermodehelper("/proc/sys/kernel/usermodehelper/bset", cap_idx); | ||
167 | drop_usermodehelper("/proc/sys/kernel/usermodehelper/inheritable", cap_idx); | ||
168 | drop_bounding_set(cap_idx); | ||
169 | drop_capset(cap_idx); | ||
170 | bb_error_msg("dropped capability: %s", cap); | ||
171 | cap = strtok(NULL, ","); | ||
172 | } | ||
173 | } | ||
174 | #endif | ||
175 | |||
92 | int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 176 | int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
93 | int switch_root_main(int argc UNUSED_PARAM, char **argv) | 177 | int switch_root_main(int argc UNUSED_PARAM, char **argv) |
94 | { | 178 | { |
95 | char *newroot, *console = NULL; | 179 | char *newroot, *console = NULL; |
96 | struct stat st; | 180 | struct stat st; |
97 | struct statfs stfs; | 181 | struct statfs stfs; |
182 | unsigned dry_run = 0; | ||
98 | dev_t rootdev; | 183 | dev_t rootdev; |
99 | 184 | ||
100 | // Parse args (-c console) | 185 | // Parse args. '+': stop at first non-option |
101 | opt_complementary = "-2"; // minimum 2 params | 186 | if (ENABLE_SWITCH_ROOT && (!ENABLE_RUN_INIT || applet_name[0] == 's')) { |
102 | getopt32(argv, "+c:", &console); // '+': stop at first non-option | 187 | //usage:#define switch_root_trivial_usage |
188 | //usage: "[-c CONSOLE_DEV] NEW_ROOT NEW_INIT [ARGS]" | ||
189 | //usage:#define switch_root_full_usage "\n\n" | ||
190 | //usage: "Free initramfs and switch to another root fs:\n" | ||
191 | //usage: "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n" | ||
192 | //usage: "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n" | ||
193 | //usage: "\n -c DEV Reopen stdio to DEV after switch" | ||
194 | getopt32(argv, "^+" | ||
195 | "c:" | ||
196 | "\0" "-2" /* minimum 2 args */, | ||
197 | &console | ||
198 | ); | ||
199 | } else { | ||
200 | #if ENABLE_RUN_INIT | ||
201 | //usage:#define run_init_trivial_usage | ||
202 | //usage: "[-d CAP,CAP...] [-n] [-c CONSOLE_DEV] NEW_ROOT NEW_INIT [ARGS]" | ||
203 | //usage:#define run_init_full_usage "\n\n" | ||
204 | //usage: "Free initramfs and switch to another root fs:\n" | ||
205 | //usage: "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n" | ||
206 | //usage: "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n" | ||
207 | //usage: "\n -c DEV Reopen stdio to DEV after switch" | ||
208 | //usage: "\n -d CAPS Drop capabilities" | ||
209 | //usage: "\n -n Dry run" | ||
210 | char *cap_list = NULL; | ||
211 | dry_run = getopt32(argv, "^+" | ||
212 | "c:d:n" | ||
213 | "\0" "-2" /* minimum 2 args */, | ||
214 | &console, | ||
215 | &cap_list | ||
216 | ); | ||
217 | dry_run >>= 2; // -n | ||
218 | if (cap_list) | ||
219 | drop_capabilities(cap_list); | ||
220 | #endif | ||
221 | } | ||
103 | argv += optind; | 222 | argv += optind; |
104 | newroot = *argv++; | 223 | newroot = *argv++; |
105 | 224 | ||
@@ -108,9 +227,12 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |||
108 | xstat("/", &st); | 227 | xstat("/", &st); |
109 | rootdev = st.st_dev; | 228 | rootdev = st.st_dev; |
110 | xstat(".", &st); | 229 | xstat(".", &st); |
111 | if (st.st_dev == rootdev || getpid() != 1) { | 230 | if (st.st_dev == rootdev) { |
112 | // Show usage, it says new root must be a mountpoint | 231 | // Show usage, it says new root must be a mountpoint |
113 | // and we must be PID 1 | 232 | bb_show_usage(); |
233 | } | ||
234 | if (!dry_run && getpid() != 1) { | ||
235 | // Show usage, it says we must be PID 1 | ||
114 | bb_show_usage(); | 236 | bb_show_usage(); |
115 | } | 237 | } |
116 | 238 | ||
@@ -118,7 +240,7 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |||
118 | // we mean it. I could make this a CONFIG option, but I would get email | 240 | // we mean it. I could make this a CONFIG option, but I would get email |
119 | // from all the people who WILL destroy their filesystems. | 241 | // from all the people who WILL destroy their filesystems. |
120 | if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { | 242 | if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { |
121 | bb_error_msg_and_die("/init is not a regular file"); | 243 | bb_error_msg_and_die("'%s' is not a regular file", "/init"); |
122 | } | 244 | } |
123 | statfs("/", &stfs); // this never fails | 245 | statfs("/", &stfs); // this never fails |
124 | if ((unsigned)stfs.f_type != RAMFS_MAGIC | 246 | if ((unsigned)stfs.f_type != RAMFS_MAGIC |
@@ -127,13 +249,15 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |||
127 | bb_error_msg_and_die("root filesystem is not ramfs/tmpfs"); | 249 | bb_error_msg_and_die("root filesystem is not ramfs/tmpfs"); |
128 | } | 250 | } |
129 | 251 | ||
130 | // Zap everything out of rootdev | 252 | if (!dry_run) { |
131 | delete_contents("/", rootdev); | 253 | // Zap everything out of rootdev |
254 | delete_contents("/", rootdev); | ||
132 | 255 | ||
133 | // Overmount / with newdir and chroot into it | 256 | // Overmount / with newdir and chroot into it |
134 | if (mount(".", "/", NULL, MS_MOVE, NULL)) { | 257 | if (mount(".", "/", NULL, MS_MOVE, NULL)) { |
135 | // For example, fails when newroot is not a mountpoint | 258 | // For example, fails when newroot is not a mountpoint |
136 | bb_perror_msg_and_die("error moving root"); | 259 | bb_perror_msg_and_die("error moving root"); |
260 | } | ||
137 | } | 261 | } |
138 | xchroot("."); | 262 | xchroot("."); |
139 | // The chdir is needed to recalculate "." and ".." links | 263 | // The chdir is needed to recalculate "." and ".." links |
@@ -149,8 +273,17 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |||
149 | } | 273 | } |
150 | } | 274 | } |
151 | 275 | ||
152 | // Exec real init | 276 | if (dry_run) { |
153 | execv(argv[0], argv); | 277 | // Does NEW_INIT look like it can be executed? |
278 | //xstat(argv[0], &st); | ||
279 | //if (!S_ISREG(st.st_mode)) | ||
280 | // bb_perror_msg_and_die("'%s' is not a regular file", argv[0]); | ||
281 | if (access(argv[0], X_OK) == 0) | ||
282 | return 0; | ||
283 | } else { | ||
284 | // Exec NEW_INIT | ||
285 | execv(argv[0], argv); | ||
286 | } | ||
154 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | 287 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
155 | } | 288 | } |
156 | 289 | ||
diff --git a/util-linux/taskset.c b/util-linux/taskset.c index 9957b1a71..401a1bcb7 100644 --- a/util-linux/taskset.c +++ b/util-linux/taskset.c | |||
@@ -22,7 +22,7 @@ | |||
22 | //config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long | 22 | //config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long |
23 | //config: in this case. Otherwise, it is limited to sizeof(long). | 23 | //config: in this case. Otherwise, it is limited to sizeof(long). |
24 | 24 | ||
25 | //applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) | 25 | //applet:IF_TASKSET(APPLET_NOEXEC(taskset, taskset, BB_DIR_USR_BIN, BB_SUID_DROP, taskset)) |
26 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o | 26 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o |
27 | 27 | ||
28 | //usage:#define taskset_trivial_usage | 28 | //usage:#define taskset_trivial_usage |
@@ -123,8 +123,7 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
123 | * Indeed, util-linux-2.13-pre7 uses: | 123 | * Indeed, util-linux-2.13-pre7 uses: |
124 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ | 124 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ |
125 | 125 | ||
126 | opt_complementary = "-1"; /* at least 1 arg */ | 126 | opt_p = getopt32(argv, "^+" "p" "\0" "-1" /* at least 1 arg */); |
127 | opt_p = getopt32(argv, "+p"); | ||
128 | argv += optind; | 127 | argv += optind; |
129 | 128 | ||
130 | aff = *argv++; | 129 | aff = *argv++; |
diff --git a/util-linux/uevent.c b/util-linux/uevent.c index 252e8fb64..7ff866cec 100644 --- a/util-linux/uevent.c +++ b/util-linux/uevent.c | |||
@@ -32,7 +32,10 @@ | |||
32 | #define env ((char **)bb_common_bufsiz1) | 32 | #define env ((char **)bb_common_bufsiz1) |
33 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 33 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
34 | enum { | 34 | enum { |
35 | MAX_ENV = COMMON_BUFSIZE / sizeof(env[0]) - 1, | 35 | MAX_ENV = COMMON_BUFSIZE / sizeof(char*) - 1, |
36 | /* sizeof(env[0]) instead of sizeof(char*) | ||
37 | * makes gcc-6.3.0 emit "strict-aliasing" warning. | ||
38 | */ | ||
36 | }; | 39 | }; |
37 | 40 | ||
38 | #ifndef SO_RCVBUFFORCE | 41 | #ifndef SO_RCVBUFFORCE |
diff --git a/util-linux/umount.c b/util-linux/umount.c index 122c0f579..a6405dfcc 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -24,7 +24,20 @@ | |||
24 | //config: help | 24 | //config: help |
25 | //config: Support -a option to unmount all currently mounted filesystems. | 25 | //config: Support -a option to unmount all currently mounted filesystems. |
26 | 26 | ||
27 | //applet:IF_UMOUNT(APPLET(umount, BB_DIR_BIN, BB_SUID_DROP)) | 27 | //applet:IF_UMOUNT(APPLET_NOEXEC(umount, umount, BB_DIR_BIN, BB_SUID_DROP, umount)) |
28 | /* | ||
29 | * On one hand, in some weird situations you'd want umount | ||
30 | * to not do anything surprising, to behave as a usual fork+execed executable. | ||
31 | * | ||
32 | * OTOH, there can be situations where execing would not succeed, or even hang | ||
33 | * (say, if executable is on a filesystem which is in trouble and accesses to it | ||
34 | * block in kernel). | ||
35 | * In this case, you might be actually happy if your standalone bbox shell | ||
36 | * does not fork+exec, but only forks and calls umount_main() which it already has! | ||
37 | * Let's go with NOEXEC. | ||
38 | * | ||
39 | * bb_common_bufsiz1 usage here is safe wrt NOEXEC: not expecting it to be zeroed. | ||
40 | */ | ||
28 | 41 | ||
29 | //kbuild:lib-$(CONFIG_UMOUNT) += umount.o | 42 | //kbuild:lib-$(CONFIG_UMOUNT) += umount.o |
30 | 43 | ||
diff --git a/util-linux/unshare.c b/util-linux/unshare.c index e7b95c72b..6a3da9f91 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c | |||
@@ -137,7 +137,7 @@ static const struct namespace_descr ns_list[] = { | |||
137 | * we are forced to use "fake" letters for them. | 137 | * we are forced to use "fake" letters for them. |
138 | * '+': stop at first non-option. | 138 | * '+': stop at first non-option. |
139 | */ | 139 | */ |
140 | static const char opt_str[] ALIGN1 = "+muinpU""fr""\xfd::""\xfe:""\xff:"; | 140 | #define OPT_STR "+muinpU""fr""\xfd::""\xfe:""\xff:" |
141 | static const char unshare_longopts[] ALIGN1 = | 141 | static const char unshare_longopts[] ALIGN1 = |
142 | "mount\0" Optional_argument "\xf0" | 142 | "mount\0" Optional_argument "\xf0" |
143 | "uts\0" Optional_argument "\xf1" | 143 | "uts\0" Optional_argument "\xf1" |
@@ -210,7 +210,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) | |||
210 | prop_str = PRIVATE_STR; | 210 | prop_str = PRIVATE_STR; |
211 | setgrp_str = NULL; | 211 | setgrp_str = NULL; |
212 | 212 | ||
213 | opt_complementary = | 213 | opts = getopt32long(argv, "^" OPT_STR "\0" |
214 | "\xf0""m" /* long opts (via their "fake chars") imply short opts */ | 214 | "\xf0""m" /* long opts (via their "fake chars") imply short opts */ |
215 | ":\xf1""u" | 215 | ":\xf1""u" |
216 | ":\xf2""i" | 216 | ":\xf2""i" |
@@ -219,16 +219,14 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) | |||
219 | ":\xf5""U" | 219 | ":\xf5""U" |
220 | ":ru" /* --map-root-user or -r implies -u */ | 220 | ":ru" /* --map-root-user or -r implies -u */ |
221 | ":\xfd""m" /* --mount-proc implies -m */ | 221 | ":\xfd""m" /* --mount-proc implies -m */ |
222 | ; | 222 | , unshare_longopts, |
223 | applet_long_options = unshare_longopts; | 223 | &proc_mnt_target, &prop_str, &setgrp_str, |
224 | opts = getopt32(argv, opt_str, | 224 | &ns_ctx_list[NS_MNT_POS].path, |
225 | &proc_mnt_target, &prop_str, &setgrp_str, | 225 | &ns_ctx_list[NS_UTS_POS].path, |
226 | &ns_ctx_list[NS_MNT_POS].path, | 226 | &ns_ctx_list[NS_IPC_POS].path, |
227 | &ns_ctx_list[NS_UTS_POS].path, | 227 | &ns_ctx_list[NS_NET_POS].path, |
228 | &ns_ctx_list[NS_IPC_POS].path, | 228 | &ns_ctx_list[NS_PID_POS].path, |
229 | &ns_ctx_list[NS_NET_POS].path, | 229 | &ns_ctx_list[NS_USR_POS].path |
230 | &ns_ctx_list[NS_PID_POS].path, | ||
231 | &ns_ctx_list[NS_USR_POS].path | ||
232 | ); | 230 | ); |
233 | argv += optind; | 231 | argv += optind; |
234 | //bb_error_msg("opts:0x%x", opts); | 232 | //bb_error_msg("opts:0x%x", opts); |