diff options
101 files changed, 1041 insertions, 549 deletions
diff --git a/archival/Config.src b/archival/Config.src index 76635ba78..a9afaea5b 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -31,7 +31,7 @@ config FEATURE_SEAMLESS_GZ | |||
31 | 31 | ||
32 | config FEATURE_SEAMLESS_Z | 32 | config FEATURE_SEAMLESS_Z |
33 | bool "tar, rpm, modprobe etc understand .Z data" | 33 | bool "tar, rpm, modprobe etc understand .Z data" |
34 | default n | 34 | default n # it is ancient |
35 | help | 35 | help |
36 | Make tar, rpm, modprobe etc understand .Z data. | 36 | Make tar, rpm, modprobe etc understand .Z data. |
37 | 37 | ||
diff --git a/archival/ar.c b/archival/ar.c index 89e6a1207..a850868f6 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -22,23 +22,13 @@ | |||
22 | //config: default n # needs to be improved to be able to replace binutils ar | 22 | //config: default n # needs to be improved to be able to replace binutils ar |
23 | //config: help | 23 | //config: help |
24 | //config: ar is an archival utility program used to create, modify, and | 24 | //config: ar is an archival utility program used to create, modify, and |
25 | //config: extract contents from archives. An archive is a single file holding | 25 | //config: extract contents from archives. In practice, it is used exclusively |
26 | //config: a collection of other files in a structure that makes it possible to | 26 | //config: for object module archives used by compilers. |
27 | //config: retrieve the original individual files (called archive members). | ||
28 | //config: The original files' contents, mode (permissions), timestamp, owner, | ||
29 | //config: and group are preserved in the archive, and can be restored on | ||
30 | //config: extraction. | ||
31 | //config: | 27 | //config: |
32 | //config: The stored filename is limited to 15 characters. (for more information | ||
33 | //config: see long filename support). | ||
34 | //config: ar has 60 bytes of overheads for every stored file. | ||
35 | //config: | ||
36 | //config: This implementation of ar can extract archives, it cannot create or | ||
37 | //config: modify them. | ||
38 | //config: On an x86 system, the ar applet adds about 1K. | 28 | //config: On an x86 system, the ar applet adds about 1K. |
39 | //config: | 29 | //config: |
40 | //config: Unless you have a specific application which requires ar, you should | 30 | //config: Unless you have a specific application which requires ar, you should |
41 | //config: probably say N here. | 31 | //config: probably say N here: most compilers come with their own ar utility. |
42 | //config: | 32 | //config: |
43 | //config:config FEATURE_AR_LONG_FILENAMES | 33 | //config:config FEATURE_AR_LONG_FILENAMES |
44 | //config: bool "Support for long filenames (not needed for debs)" | 34 | //config: bool "Support for long filenames (not needed for debs)" |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index a859ef201..aaaf67e03 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -222,7 +222,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
222 | 222 | ||
223 | //config:config UNCOMPRESS | 223 | //config:config UNCOMPRESS |
224 | //config: bool "uncompress" | 224 | //config: bool "uncompress" |
225 | //config: default n | 225 | //config: default n # ancient |
226 | //config: help | 226 | //config: help |
227 | //config: uncompress is used to decompress archives created by compress. | 227 | //config: uncompress is used to decompress archives created by compress. |
228 | //config: Not much used anymore, replaced by gzip/gunzip. | 228 | //config: Not much used anymore, replaced by gzip/gunzip. |
@@ -292,6 +292,13 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
292 | //config: gunzip is used to decompress archives created by gzip. | 292 | //config: gunzip is used to decompress archives created by gzip. |
293 | //config: You can use the `-t' option to test the integrity of | 293 | //config: You can use the `-t' option to test the integrity of |
294 | //config: an archive, without decompressing it. | 294 | //config: an archive, without decompressing it. |
295 | //config: | ||
296 | //config:config FEATURE_GUNZIP_LONG_OPTIONS | ||
297 | //config: bool "Enable long options" | ||
298 | //config: default y | ||
299 | //config: depends on GUNZIP && LONG_OPTS | ||
300 | //config: help | ||
301 | //config: Enable use of long options. | ||
295 | 302 | ||
296 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) | 303 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) |
297 | //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) | 304 | //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) |
@@ -323,6 +330,17 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
323 | } | 330 | } |
324 | return filename; | 331 | return filename; |
325 | } | 332 | } |
333 | |||
334 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS | ||
335 | static const char gunzip_longopts[] ALIGN1 = | ||
336 | "stdout\0" No_argument "c" | ||
337 | "to-stdout\0" No_argument "c" | ||
338 | "force\0" No_argument "f" | ||
339 | "test\0" No_argument "t" | ||
340 | "no-name\0" No_argument "n" | ||
341 | ; | ||
342 | #endif | ||
343 | |||
326 | /* | 344 | /* |
327 | * Linux kernel build uses gzip -d -n. We accept and ignore it. | 345 | * Linux kernel build uses gzip -d -n. We accept and ignore it. |
328 | * Man page says: | 346 | * Man page says: |
@@ -339,6 +357,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
339 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 357 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
340 | int gunzip_main(int argc UNUSED_PARAM, char **argv) | 358 | int gunzip_main(int argc UNUSED_PARAM, char **argv) |
341 | { | 359 | { |
360 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS | ||
361 | applet_long_options = gunzip_longopts; | ||
362 | #endif | ||
342 | getopt32(argv, "cfvqdtn"); | 363 | getopt32(argv, "cfvqdtn"); |
343 | argv += optind; | 364 | argv += optind; |
344 | 365 | ||
diff --git a/archival/gzip.c b/archival/gzip.c index c9171304a..f9bb3c742 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -2160,6 +2160,7 @@ static const char gzip_longopts[] ALIGN1 = | |||
2160 | "quiet\0" No_argument "q" | 2160 | "quiet\0" No_argument "q" |
2161 | "fast\0" No_argument "1" | 2161 | "fast\0" No_argument "1" |
2162 | "best\0" No_argument "9" | 2162 | "best\0" No_argument "9" |
2163 | "no-name\0" No_argument "n" | ||
2163 | ; | 2164 | ; |
2164 | #endif | 2165 | #endif |
2165 | 2166 | ||
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 45776dcbe..bd034afdc 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -11,6 +11,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
11 | file_header_t *file_header = archive_handle->file_header; | 11 | file_header_t *file_header = archive_handle->file_header; |
12 | int dst_fd; | 12 | int dst_fd; |
13 | int res; | 13 | int res; |
14 | char *hard_link; | ||
15 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
16 | char *dst_name; | ||
17 | #else | ||
18 | # define dst_name (file_header->name) | ||
19 | #endif | ||
14 | 20 | ||
15 | #if ENABLE_FEATURE_TAR_SELINUX | 21 | #if ENABLE_FEATURE_TAR_SELINUX |
16 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; | 22 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; |
@@ -23,11 +29,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
23 | } | 29 | } |
24 | #endif | 30 | #endif |
25 | 31 | ||
32 | /* Hard links are encoded as regular files of size 0 | ||
33 | * with a nonempty link field */ | ||
34 | hard_link = NULL; | ||
35 | if (S_ISREG(file_header->mode) && file_header->size == 0) | ||
36 | hard_link = file_header->link_target; | ||
37 | |||
38 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
39 | dst_name = file_header->name; | ||
40 | if (archive_handle->tar__strip_components) { | ||
41 | unsigned n = archive_handle->tar__strip_components; | ||
42 | do { | ||
43 | dst_name = strchr(dst_name, '/'); | ||
44 | if (!dst_name || dst_name[1] == '\0') { | ||
45 | data_skip(archive_handle); | ||
46 | goto ret; | ||
47 | } | ||
48 | dst_name++; | ||
49 | /* | ||
50 | * Link target is shortened only for hardlinks: | ||
51 | * softlinks restored unchanged. | ||
52 | */ | ||
53 | if (hard_link) { | ||
54 | // GNU tar 1.26 does not check that we reached end of link name: | ||
55 | // if "dir/hardlink" is hardlinked to "file", | ||
56 | // tar xvf a.tar --strip-components=1 says: | ||
57 | // tar: hardlink: Cannot hard link to '': No such file or directory | ||
58 | // and continues processing. We silently skip such entries. | ||
59 | hard_link = strchr(hard_link, '/'); | ||
60 | if (!hard_link || hard_link[1] == '\0') { | ||
61 | data_skip(archive_handle); | ||
62 | goto ret; | ||
63 | } | ||
64 | hard_link++; | ||
65 | } | ||
66 | } while (--n != 0); | ||
67 | } | ||
68 | #endif | ||
69 | |||
26 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | 70 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { |
27 | char *slash = strrchr(file_header->name, '/'); | 71 | char *slash = strrchr(dst_name, '/'); |
28 | if (slash) { | 72 | if (slash) { |
29 | *slash = '\0'; | 73 | *slash = '\0'; |
30 | bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); | 74 | bb_make_directory(dst_name, -1, FILEUTILS_RECUR); |
31 | *slash = '/'; | 75 | *slash = '/'; |
32 | } | 76 | } |
33 | } | 77 | } |
@@ -35,12 +79,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
35 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { | 79 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { |
36 | /* Remove the entry if it exists */ | 80 | /* Remove the entry if it exists */ |
37 | if (!S_ISDIR(file_header->mode)) { | 81 | if (!S_ISDIR(file_header->mode)) { |
38 | /* Is it hardlink? | 82 | if (hard_link) { |
39 | * We encode hard links as regular files of size 0 with a symlink */ | ||
40 | if (S_ISREG(file_header->mode) | ||
41 | && file_header->link_target | ||
42 | && file_header->size == 0 | ||
43 | ) { | ||
44 | /* Ugly special case: | 83 | /* Ugly special case: |
45 | * tar cf t.tar hardlink1 hardlink2 hardlink1 | 84 | * tar cf t.tar hardlink1 hardlink2 hardlink1 |
46 | * results in this tarball structure: | 85 | * results in this tarball structure: |
@@ -48,22 +87,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
48 | * hardlink2 -> hardlink1 | 87 | * hardlink2 -> hardlink1 |
49 | * hardlink1 -> hardlink1 <== !!! | 88 | * hardlink1 -> hardlink1 <== !!! |
50 | */ | 89 | */ |
51 | if (strcmp(file_header->link_target, file_header->name) == 0) | 90 | if (strcmp(hard_link, dst_name) == 0) |
52 | goto ret; | 91 | goto ret; |
53 | } | 92 | } |
54 | /* Proceed with deleting */ | 93 | /* Proceed with deleting */ |
55 | if (unlink(file_header->name) == -1 | 94 | if (unlink(dst_name) == -1 |
56 | && errno != ENOENT | 95 | && errno != ENOENT |
57 | ) { | 96 | ) { |
58 | bb_perror_msg_and_die("can't remove old file %s", | 97 | bb_perror_msg_and_die("can't remove old file %s", |
59 | file_header->name); | 98 | dst_name); |
60 | } | 99 | } |
61 | } | 100 | } |
62 | } | 101 | } |
63 | else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { | 102 | else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { |
64 | /* Remove the existing entry if its older than the extracted entry */ | 103 | /* Remove the existing entry if its older than the extracted entry */ |
65 | struct stat existing_sb; | 104 | struct stat existing_sb; |
66 | if (lstat(file_header->name, &existing_sb) == -1) { | 105 | if (lstat(dst_name, &existing_sb) == -1) { |
67 | if (errno != ENOENT) { | 106 | if (errno != ENOENT) { |
68 | bb_perror_msg_and_die("can't stat old file"); | 107 | bb_perror_msg_and_die("can't stat old file"); |
69 | } | 108 | } |
@@ -73,30 +112,25 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
73 | && !S_ISDIR(file_header->mode) | 112 | && !S_ISDIR(file_header->mode) |
74 | ) { | 113 | ) { |
75 | bb_error_msg("%s not created: newer or " | 114 | bb_error_msg("%s not created: newer or " |
76 | "same age file exists", file_header->name); | 115 | "same age file exists", dst_name); |
77 | } | 116 | } |
78 | data_skip(archive_handle); | 117 | data_skip(archive_handle); |
79 | goto ret; | 118 | goto ret; |
80 | } | 119 | } |
81 | else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { | 120 | else if ((unlink(dst_name) == -1) && (errno != EISDIR)) { |
82 | bb_perror_msg_and_die("can't remove old file %s", | 121 | bb_perror_msg_and_die("can't remove old file %s", |
83 | file_header->name); | 122 | dst_name); |
84 | } | 123 | } |
85 | } | 124 | } |
86 | 125 | ||
87 | /* Handle hard links separately | 126 | /* Handle hard links separately */ |
88 | * We encode hard links as regular files of size 0 with a symlink */ | 127 | if (hard_link) { |
89 | if (S_ISREG(file_header->mode) | 128 | res = link(hard_link, dst_name); |
90 | && file_header->link_target | 129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { |
91 | && file_header->size == 0 | ||
92 | ) { | ||
93 | /* hard link */ | ||
94 | res = link(file_header->link_target, file_header->name); | ||
95 | if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | ||
96 | bb_perror_msg("can't create %slink " | 130 | bb_perror_msg("can't create %slink " |
97 | "from %s to %s", "hard", | 131 | "from %s to %s", "hard", |
98 | file_header->name, | 132 | dst_name, |
99 | file_header->link_target); | 133 | hard_link); |
100 | } | 134 | } |
101 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ | 135 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ |
102 | goto ret; | 136 | goto ret; |
@@ -106,17 +140,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
106 | switch (file_header->mode & S_IFMT) { | 140 | switch (file_header->mode & S_IFMT) { |
107 | case S_IFREG: { | 141 | case S_IFREG: { |
108 | /* Regular file */ | 142 | /* Regular file */ |
109 | char *dst_name; | 143 | char *dst_nameN; |
110 | int flags = O_WRONLY | O_CREAT | O_EXCL; | 144 | int flags = O_WRONLY | O_CREAT | O_EXCL; |
111 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | 145 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) |
112 | flags = O_WRONLY | O_CREAT | O_TRUNC; | 146 | flags = O_WRONLY | O_CREAT | O_TRUNC; |
113 | dst_name = file_header->name; | 147 | dst_nameN = dst_name; |
114 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | 148 | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
115 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) | 149 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) |
116 | /* rpm-style temp file name */ | 150 | /* rpm-style temp file name */ |
117 | dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); | 151 | dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid()); |
118 | #endif | 152 | #endif |
119 | dst_fd = xopen3(dst_name, | 153 | dst_fd = xopen3(dst_nameN, |
120 | flags, | 154 | flags, |
121 | file_header->mode | 155 | file_header->mode |
122 | ); | 156 | ); |
@@ -124,32 +158,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
124 | close(dst_fd); | 158 | close(dst_fd); |
125 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | 159 | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
126 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { | 160 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { |
127 | xrename(dst_name, file_header->name); | 161 | xrename(dst_nameN, dst_name); |
128 | free(dst_name); | 162 | free(dst_nameN); |
129 | } | 163 | } |
130 | #endif | 164 | #endif |
131 | break; | 165 | break; |
132 | } | 166 | } |
133 | case S_IFDIR: | 167 | case S_IFDIR: |
134 | res = mkdir(file_header->name, file_header->mode); | 168 | res = mkdir(dst_name, file_header->mode); |
135 | if ((res == -1) | 169 | if ((res == -1) |
136 | && (errno != EISDIR) /* btw, Linux doesn't return this */ | 170 | && (errno != EISDIR) /* btw, Linux doesn't return this */ |
137 | && (errno != EEXIST) | 171 | && (errno != EEXIST) |
138 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 172 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
139 | ) { | 173 | ) { |
140 | bb_perror_msg("can't make dir %s", file_header->name); | 174 | bb_perror_msg("can't make dir %s", dst_name); |
141 | } | 175 | } |
142 | break; | 176 | break; |
143 | case S_IFLNK: | 177 | case S_IFLNK: |
144 | /* Symlink */ | 178 | /* Symlink */ |
145 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) | 179 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) |
146 | res = symlink(file_header->link_target, file_header->name); | 180 | res = symlink(file_header->link_target, dst_name); |
147 | if ((res == -1) | 181 | if (res != 0 |
148 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 182 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
149 | ) { | 183 | ) { |
150 | bb_perror_msg("can't create %slink " | 184 | bb_perror_msg("can't create %slink " |
151 | "from %s to %s", "sym", | 185 | "from %s to %s", "sym", |
152 | file_header->name, | 186 | dst_name, |
153 | file_header->link_target); | 187 | file_header->link_target); |
154 | } | 188 | } |
155 | break; | 189 | break; |
@@ -157,11 +191,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
157 | case S_IFBLK: | 191 | case S_IFBLK: |
158 | case S_IFCHR: | 192 | case S_IFCHR: |
159 | case S_IFIFO: | 193 | case S_IFIFO: |
160 | res = mknod(file_header->name, file_header->mode, file_header->device); | 194 | res = mknod(dst_name, file_header->mode, file_header->device); |
161 | if ((res == -1) | 195 | if ((res == -1) |
162 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 196 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
163 | ) { | 197 | ) { |
164 | bb_perror_msg("can't create node %s", file_header->name); | 198 | bb_perror_msg("can't create node %s", dst_name); |
165 | } | 199 | } |
166 | break; | 200 | break; |
167 | default: | 201 | default: |
@@ -186,20 +220,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
186 | } | 220 | } |
187 | #endif | 221 | #endif |
188 | /* GNU tar 1.15.1 uses chown, not lchown */ | 222 | /* GNU tar 1.15.1 uses chown, not lchown */ |
189 | chown(file_header->name, uid, gid); | 223 | chown(dst_name, uid, gid); |
190 | } | 224 | } |
191 | /* uclibc has no lchmod, glibc is even stranger - | 225 | /* uclibc has no lchmod, glibc is even stranger - |
192 | * it has lchmod which seems to do nothing! | 226 | * it has lchmod which seems to do nothing! |
193 | * so we use chmod... */ | 227 | * so we use chmod... */ |
194 | if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { | 228 | if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { |
195 | chmod(file_header->name, file_header->mode); | 229 | chmod(dst_name, file_header->mode); |
196 | } | 230 | } |
197 | if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { | 231 | if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { |
198 | struct timeval t[2]; | 232 | struct timeval t[2]; |
199 | 233 | ||
200 | t[1].tv_sec = t[0].tv_sec = file_header->mtime; | 234 | t[1].tv_sec = t[0].tv_sec = file_header->mtime; |
201 | t[1].tv_usec = t[0].tv_usec = 0; | 235 | t[1].tv_usec = t[0].tv_usec = 0; |
202 | utimes(file_header->name, t); | 236 | utimes(dst_name, t); |
203 | } | 237 | } |
204 | } | 238 | } |
205 | 239 | ||
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index b6ae7f738..eb64645ae 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -308,11 +308,11 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
308 | unsigned i; /* counter, current code */ | 308 | unsigned i; /* counter, current code */ |
309 | unsigned j; /* counter */ | 309 | unsigned j; /* counter */ |
310 | int k; /* number of bits in current code */ | 310 | int k; /* number of bits in current code */ |
311 | unsigned *p; /* pointer into c[], b[], or v[] */ | 311 | const unsigned *p; /* pointer into c[], b[], or v[] */ |
312 | huft_t *q; /* points to current table */ | 312 | huft_t *q; /* points to current table */ |
313 | huft_t r; /* table entry for structure assignment */ | 313 | huft_t r; /* table entry for structure assignment */ |
314 | huft_t *u[BMAX]; /* table stack */ | 314 | huft_t *u[BMAX]; /* table stack */ |
315 | unsigned v[N_MAX]; /* values in order of bit length */ | 315 | unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */ |
316 | int ws[BMAX + 1]; /* bits decoded stack */ | 316 | int ws[BMAX + 1]; /* bits decoded stack */ |
317 | int w; /* bits decoded */ | 317 | int w; /* bits decoded */ |
318 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ | 318 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ |
@@ -327,7 +327,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
327 | 327 | ||
328 | /* Generate counts for each bit length */ | 328 | /* Generate counts for each bit length */ |
329 | memset(c, 0, sizeof(c)); | 329 | memset(c, 0, sizeof(c)); |
330 | p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ | 330 | p = b; |
331 | i = n; | 331 | i = n; |
332 | do { | 332 | do { |
333 | c[*p]++; /* assume all entries <= BMAX */ | 333 | c[*p]++; /* assume all entries <= BMAX */ |
@@ -367,8 +367,12 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
367 | *xp++ = j; | 367 | *xp++ = j; |
368 | } | 368 | } |
369 | 369 | ||
370 | /* Make a table of values in order of bit lengths */ | 370 | /* Make a table of values in order of bit lengths. |
371 | p = (unsigned *) b; | 371 | * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX. |
372 | * In particular, last v[i] is never filled and must not be accessed. | ||
373 | */ | ||
374 | memset(v, 0xff, sizeof(v)); | ||
375 | p = b; | ||
372 | i = 0; | 376 | i = 0; |
373 | do { | 377 | do { |
374 | j = *p++; | 378 | j = *p++; |
@@ -435,7 +439,9 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
435 | 439 | ||
436 | /* set up table entry in r */ | 440 | /* set up table entry in r */ |
437 | r.b = (unsigned char) (k - w); | 441 | r.b = (unsigned char) (k - w); |
438 | if (p >= v + n) { | 442 | if (/*p >= v + n || -- redundant, caught by the second check: */ |
443 | *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/ | ||
444 | ) { | ||
439 | r.e = 99; /* out of values--invalid code */ | 445 | r.e = 99; /* out of values--invalid code */ |
440 | } else if (*p < s) { | 446 | } else if (*p < s) { |
441 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ | 447 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ |
@@ -520,8 +526,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
520 | e = t->e; | 526 | e = t->e; |
521 | if (e > 16) | 527 | if (e > 16) |
522 | do { | 528 | do { |
523 | if (e == 99) | 529 | if (e == 99) { |
524 | abort_unzip(PASS_STATE_ONLY);; | 530 | abort_unzip(PASS_STATE_ONLY); |
531 | } | ||
525 | bb >>= t->b; | 532 | bb >>= t->b; |
526 | k -= t->b; | 533 | k -= t->b; |
527 | e -= 16; | 534 | e -= 16; |
@@ -557,8 +564,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
557 | e = t->e; | 564 | e = t->e; |
558 | if (e > 16) | 565 | if (e > 16) |
559 | do { | 566 | do { |
560 | if (e == 99) | 567 | if (e == 99) { |
561 | abort_unzip(PASS_STATE_ONLY); | 568 | abort_unzip(PASS_STATE_ONLY); |
569 | } | ||
562 | bb >>= t->b; | 570 | bb >>= t->b; |
563 | k -= t->b; | 571 | k -= t->b; |
564 | e -= 16; | 572 | e -= 16; |
@@ -824,8 +832,9 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
824 | 832 | ||
825 | b_dynamic >>= 4; | 833 | b_dynamic >>= 4; |
826 | k_dynamic -= 4; | 834 | k_dynamic -= 4; |
827 | if (nl > 286 || nd > 30) | 835 | if (nl > 286 || nd > 30) { |
828 | abort_unzip(PASS_STATE_ONLY); /* bad lengths */ | 836 | abort_unzip(PASS_STATE_ONLY); /* bad lengths */ |
837 | } | ||
829 | 838 | ||
830 | /* read in bit-length-code lengths */ | 839 | /* read in bit-length-code lengths */ |
831 | for (j = 0; j < nb; j++) { | 840 | for (j = 0; j < nb; j++) { |
@@ -906,12 +915,14 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
906 | bl = lbits; | 915 | bl = lbits; |
907 | 916 | ||
908 | i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); | 917 | i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); |
909 | if (i != 0) | 918 | if (i != 0) { |
910 | abort_unzip(PASS_STATE_ONLY); | 919 | abort_unzip(PASS_STATE_ONLY); |
920 | } | ||
911 | bd = dbits; | 921 | bd = dbits; |
912 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); | 922 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); |
913 | if (i != 0) | 923 | if (i != 0) { |
914 | abort_unzip(PASS_STATE_ONLY); | 924 | abort_unzip(PASS_STATE_ONLY); |
925 | } | ||
915 | 926 | ||
916 | /* set up data for inflate_codes() */ | 927 | /* set up data for inflate_codes() */ |
917 | inflate_codes_setup(PASS_STATE bl, bd); | 928 | inflate_codes_setup(PASS_STATE bl, bd); |
@@ -999,6 +1010,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) | |||
999 | error_msg = "corrupted data"; | 1010 | error_msg = "corrupted data"; |
1000 | if (setjmp(error_jmp)) { | 1011 | if (setjmp(error_jmp)) { |
1001 | /* Error from deep inside zip machinery */ | 1012 | /* Error from deep inside zip machinery */ |
1013 | bb_error_msg(error_msg); | ||
1002 | n = -1; | 1014 | n = -1; |
1003 | goto ret; | 1015 | goto ret; |
1004 | } | 1016 | } |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index fb68673b9..ac2be726f 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -418,6 +418,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
418 | 418 | ||
419 | /* Everything up to and including last ".." component is stripped */ | 419 | /* Everything up to and including last ".." component is stripped */ |
420 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); | 420 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); |
421 | //TODO: do the same for file_header->link_target? | ||
421 | 422 | ||
422 | /* Strip trailing '/' in directories */ | 423 | /* Strip trailing '/' in directories */ |
423 | /* Must be done after mode is set as '/' is used to check if it's a directory */ | 424 | /* Must be done after mode is set as '/' is used to check if it's a directory */ |
diff --git a/archival/lzop.c b/archival/lzop.c index 73d11a705..a5fc01941 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -640,7 +640,7 @@ static int lzo_get_method(header_t *h) | |||
640 | /**********************************************************************/ | 640 | /**********************************************************************/ |
641 | // compress a file | 641 | // compress a file |
642 | /**********************************************************************/ | 642 | /**********************************************************************/ |
643 | static NOINLINE smallint lzo_compress(const header_t *h) | 643 | static NOINLINE int lzo_compress(const header_t *h) |
644 | { | 644 | { |
645 | unsigned block_size = LZO_BLOCK_SIZE; | 645 | unsigned block_size = LZO_BLOCK_SIZE; |
646 | int r = 0; /* LZO_E_OK */ | 646 | int r = 0; /* LZO_E_OK */ |
@@ -650,7 +650,6 @@ static NOINLINE smallint lzo_compress(const header_t *h) | |||
650 | uint32_t d_adler32 = ADLER32_INIT_VALUE; | 650 | uint32_t d_adler32 = ADLER32_INIT_VALUE; |
651 | uint32_t d_crc32 = CRC32_INIT_VALUE; | 651 | uint32_t d_crc32 = CRC32_INIT_VALUE; |
652 | int l; | 652 | int l; |
653 | smallint ok = 1; | ||
654 | uint8_t *wrk_mem = NULL; | 653 | uint8_t *wrk_mem = NULL; |
655 | 654 | ||
656 | if (h->method == M_LZO1X_1) | 655 | if (h->method == M_LZO1X_1) |
@@ -732,7 +731,7 @@ static NOINLINE smallint lzo_compress(const header_t *h) | |||
732 | free(wrk_mem); | 731 | free(wrk_mem); |
733 | free(b1); | 732 | free(b1); |
734 | free(b2); | 733 | free(b2); |
735 | return ok; | 734 | return 1; |
736 | } | 735 | } |
737 | 736 | ||
738 | static FAST_FUNC void lzo_check( | 737 | static FAST_FUNC void lzo_check( |
@@ -753,7 +752,7 @@ static FAST_FUNC void lzo_check( | |||
753 | /**********************************************************************/ | 752 | /**********************************************************************/ |
754 | // decompress a file | 753 | // decompress a file |
755 | /**********************************************************************/ | 754 | /**********************************************************************/ |
756 | static NOINLINE smallint lzo_decompress(const header_t *h) | 755 | static NOINLINE int lzo_decompress(const header_t *h) |
757 | { | 756 | { |
758 | unsigned block_size = LZO_BLOCK_SIZE; | 757 | unsigned block_size = LZO_BLOCK_SIZE; |
759 | int r; | 758 | int r; |
@@ -761,7 +760,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h) | |||
761 | uint32_t c_adler32 = ADLER32_INIT_VALUE; | 760 | uint32_t c_adler32 = ADLER32_INIT_VALUE; |
762 | uint32_t d_adler32 = ADLER32_INIT_VALUE; | 761 | uint32_t d_adler32 = ADLER32_INIT_VALUE; |
763 | uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; | 762 | uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; |
764 | smallint ok = 1; | ||
765 | uint8_t *b1; | 763 | uint8_t *b1; |
766 | uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); | 764 | uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); |
767 | uint8_t *b2 = NULL; | 765 | uint8_t *b2 = NULL; |
@@ -865,7 +863,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h) | |||
865 | } | 863 | } |
866 | 864 | ||
867 | free(b2); | 865 | free(b2); |
868 | return ok; | 866 | return 1; |
869 | } | 867 | } |
870 | 868 | ||
871 | /**********************************************************************/ | 869 | /**********************************************************************/ |
@@ -1050,7 +1048,7 @@ static void lzo_set_method(header_t *h) | |||
1050 | h->level = level; | 1048 | h->level = level; |
1051 | } | 1049 | } |
1052 | 1050 | ||
1053 | static smallint do_lzo_compress(void) | 1051 | static int do_lzo_compress(void) |
1054 | { | 1052 | { |
1055 | header_t header; | 1053 | header_t header; |
1056 | 1054 | ||
@@ -1078,7 +1076,7 @@ static smallint do_lzo_compress(void) | |||
1078 | /**********************************************************************/ | 1076 | /**********************************************************************/ |
1079 | // decompress | 1077 | // decompress |
1080 | /**********************************************************************/ | 1078 | /**********************************************************************/ |
1081 | static smallint do_lzo_decompress(void) | 1079 | static int do_lzo_decompress(void) |
1082 | { | 1080 | { |
1083 | header_t header; | 1081 | header_t header; |
1084 | 1082 | ||
diff --git a/archival/tar.c b/archival/tar.c index 0dd675f64..adb0b934f 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -152,9 +152,12 @@ | |||
152 | # define FNM_LEADING_DIR 0 | 152 | # define FNM_LEADING_DIR 0 |
153 | #endif | 153 | #endif |
154 | 154 | ||
155 | 155 | #if 0 | |
156 | //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) | 156 | # define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) |
157 | #define DBG(...) ((void)0) | 157 | #else |
158 | # define DBG(...) ((void)0) | ||
159 | #endif | ||
160 | #define DBG_OPTION_PARSING 0 | ||
158 | 161 | ||
159 | 162 | ||
160 | #define block_buf bb_common_bufsiz1 | 163 | #define block_buf bb_common_bufsiz1 |
@@ -884,6 +887,7 @@ enum { | |||
884 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) | 887 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) |
885 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) | 888 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
886 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 889 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
890 | OPTBIT_STRIP_COMPONENTS, | ||
887 | OPTBIT_NORECURSION, | 891 | OPTBIT_NORECURSION, |
888 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) | 892 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) |
889 | OPTBIT_NUMERIC_OWNER, | 893 | OPTBIT_NUMERIC_OWNER, |
@@ -908,12 +912,13 @@ enum { | |||
908 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z | 912 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
909 | OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J | 913 | OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J |
910 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z | 914 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
911 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m | 915 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
912 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion | 916 | OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components |
913 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command | 917 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion |
914 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 918 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command |
915 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 919 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
916 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | 920 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
921 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | ||
917 | 922 | ||
918 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), | 923 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), |
919 | }; | 924 | }; |
@@ -957,6 +962,7 @@ static const char tar_longopts[] ALIGN1 = | |||
957 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME | 962 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
958 | "touch\0" No_argument "m" | 963 | "touch\0" No_argument "m" |
959 | # endif | 964 | # endif |
965 | "strip-components\0" Required_argument "\xf9" | ||
960 | "no-recursion\0" No_argument "\xfa" | 966 | "no-recursion\0" No_argument "\xfa" |
961 | # if ENABLE_FEATURE_TAR_TO_COMMAND | 967 | # if ENABLE_FEATURE_TAR_TO_COMMAND |
962 | "to-command\0" Required_argument "\xfb" | 968 | "to-command\0" Required_argument "\xfb" |
@@ -1002,15 +1008,28 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1002 | "tt:vv:" // count -t,-v | 1008 | "tt:vv:" // count -t,-v |
1003 | IF_FEATURE_TAR_FROM("X::T::") // cumulative lists | 1009 | IF_FEATURE_TAR_FROM("X::T::") // cumulative lists |
1004 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 1010 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
1005 | "\xff::" // cumulative lists for --exclude | 1011 | "\xff::" // --exclude=PATTERN is a list |
1006 | #endif | 1012 | #endif |
1007 | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd | 1013 | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd |
1008 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive | 1014 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive |
1009 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive | 1015 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive |
1016 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
1017 | ":\xf9+" // --strip-components=NUM | ||
1018 | #endif | ||
1019 | ; | ||
1010 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 1020 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
1011 | applet_long_options = tar_longopts; | 1021 | applet_long_options = tar_longopts; |
1012 | #endif | 1022 | #endif |
1013 | #if ENABLE_DESKTOP | 1023 | #if ENABLE_DESKTOP |
1024 | /* Lie to buildroot when it starts asking stupid questions. */ | ||
1025 | if (argv[1] && strcmp(argv[1], "--version") == 0) { | ||
1026 | // Output of 'tar --version' examples: | ||
1027 | // tar (GNU tar) 1.15.1 | ||
1028 | // tar (GNU tar) 1.25 | ||
1029 | // bsdtar 2.8.3 - libarchive 2.8.3 | ||
1030 | puts("tar (busybox) " BB_VER); | ||
1031 | return 0; | ||
1032 | } | ||
1014 | if (argv[1] && argv[1][0] != '-') { | 1033 | if (argv[1] && argv[1][0] != '-') { |
1015 | /* Compat: | 1034 | /* Compat: |
1016 | * 1st argument without dash handles options with parameters | 1035 | * 1st argument without dash handles options with parameters |
@@ -1047,10 +1066,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1047 | IF_FEATURE_SEAMLESS_XZ( "J" ) | 1066 | IF_FEATURE_SEAMLESS_XZ( "J" ) |
1048 | IF_FEATURE_SEAMLESS_Z( "Z" ) | 1067 | IF_FEATURE_SEAMLESS_Z( "Z" ) |
1049 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") | 1068 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") |
1069 | IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components | ||
1050 | , &base_dir // -C dir | 1070 | , &base_dir // -C dir |
1051 | , &tar_filename // -f filename | 1071 | , &tar_filename // -f filename |
1052 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T | 1072 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T |
1053 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X | 1073 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X |
1074 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
1075 | , &tar_handle->tar__strip_components // --strip-components | ||
1076 | #endif | ||
1054 | IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command | 1077 | IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command |
1055 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 1078 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
1056 | , &excludes // --exclude | 1079 | , &excludes // --exclude |
@@ -1058,11 +1081,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1058 | , &verboseFlag // combined count for -t and -v | 1081 | , &verboseFlag // combined count for -t and -v |
1059 | , &verboseFlag // combined count for -t and -v | 1082 | , &verboseFlag // combined count for -t and -v |
1060 | ); | 1083 | ); |
1061 | //bb_error_msg("opt:%08x", opt); | 1084 | #if DBG_OPTION_PARSING |
1085 | bb_error_msg("opt: 0x%08x", opt); | ||
1086 | # define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); | ||
1087 | showopt(OPT_TEST ); | ||
1088 | showopt(OPT_EXTRACT ); | ||
1089 | showopt(OPT_BASEDIR ); | ||
1090 | showopt(OPT_TARNAME ); | ||
1091 | showopt(OPT_2STDOUT ); | ||
1092 | showopt(OPT_NOPRESERVE_OWNER); | ||
1093 | showopt(OPT_P ); | ||
1094 | showopt(OPT_VERBOSE ); | ||
1095 | showopt(OPT_KEEP_OLD ); | ||
1096 | showopt(OPT_CREATE ); | ||
1097 | showopt(OPT_DEREFERENCE ); | ||
1098 | showopt(OPT_BZIP2 ); | ||
1099 | showopt(OPT_LZMA ); | ||
1100 | showopt(OPT_INCLUDE_FROM ); | ||
1101 | showopt(OPT_EXCLUDE_FROM ); | ||
1102 | showopt(OPT_GZIP ); | ||
1103 | showopt(OPT_XZ ); | ||
1104 | showopt(OPT_COMPRESS ); | ||
1105 | showopt(OPT_NOPRESERVE_TIME ); | ||
1106 | showopt(OPT_STRIP_COMPONENTS); | ||
1107 | showopt(OPT_NORECURSION ); | ||
1108 | showopt(OPT_2COMMAND ); | ||
1109 | showopt(OPT_NUMERIC_OWNER ); | ||
1110 | showopt(OPT_NOPRESERVE_PERM ); | ||
1111 | showopt(OPT_OVERWRITE ); | ||
1112 | showopt(OPT_ANY_COMPRESS ); | ||
1113 | bb_error_msg("base_dir:'%s'", base_dir); | ||
1114 | bb_error_msg("tar_filename:'%s'", tar_filename); | ||
1115 | bb_error_msg("verboseFlag:%d", verboseFlag); | ||
1116 | bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command); | ||
1117 | bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components); | ||
1118 | return 0; | ||
1119 | # undef showopt | ||
1120 | #endif | ||
1062 | argv += optind; | 1121 | argv += optind; |
1063 | 1122 | ||
1064 | if (verboseFlag) tar_handle->action_header = header_verbose_list; | 1123 | if (verboseFlag) |
1065 | if (verboseFlag == 1) tar_handle->action_header = header_list; | 1124 | tar_handle->action_header = header_verbose_list; |
1125 | if (verboseFlag == 1) | ||
1126 | tar_handle->action_header = header_list; | ||
1066 | 1127 | ||
1067 | if (opt & OPT_EXTRACT) | 1128 | if (opt & OPT_EXTRACT) |
1068 | tar_handle->action_data = data_extract_all; | 1129 | tar_handle->action_data = data_extract_all; |
diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 4dfbdb526..1095094fe 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig | |||
@@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" | |||
89 | # | 89 | # |
90 | # Busybox Library Tuning | 90 | # Busybox Library Tuning |
91 | # | 91 | # |
92 | # CONFIG_FEATURE_SYSTEMD is not set | ||
93 | # CONFIG_FEATURE_RTMINMAX is not set | 92 | # CONFIG_FEATURE_RTMINMAX is not set |
94 | CONFIG_PASSWORD_MINLEN=6 | 93 | CONFIG_PASSWORD_MINLEN=6 |
95 | CONFIG_MD5_SMALL=1 | 94 | CONFIG_MD5_SMALL=1 |
diff --git a/configs/android_defconfig b/configs/android_defconfig index e35830e7f..082994b6c 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig | |||
@@ -107,7 +107,6 @@ CONFIG_PREFIX="./_install" | |||
107 | # | 107 | # |
108 | # Busybox Library Tuning | 108 | # Busybox Library Tuning |
109 | # | 109 | # |
110 | # CONFIG_FEATURE_SYSTEMD is not set | ||
111 | # CONFIG_FEATURE_RTMINMAX is not set | 110 | # CONFIG_FEATURE_RTMINMAX is not set |
112 | CONFIG_PASSWORD_MINLEN=6 | 111 | CONFIG_PASSWORD_MINLEN=6 |
113 | CONFIG_MD5_SMALL=1 | 112 | CONFIG_MD5_SMALL=1 |
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 66c85268f..63fafb468 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig | |||
@@ -96,7 +96,6 @@ CONFIG_PREFIX="./_install" | |||
96 | # | 96 | # |
97 | # Busybox Library Tuning | 97 | # Busybox Library Tuning |
98 | # | 98 | # |
99 | # CONFIG_FEATURE_SYSTEMD is not set | ||
100 | # CONFIG_FEATURE_RTMINMAX is not set | 99 | # CONFIG_FEATURE_RTMINMAX is not set |
101 | CONFIG_PASSWORD_MINLEN=6 | 100 | CONFIG_PASSWORD_MINLEN=6 |
102 | CONFIG_MD5_SMALL=1 | 101 | CONFIG_MD5_SMALL=1 |
diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index aa346e34c..2c02be743 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig | |||
@@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" | |||
89 | # | 89 | # |
90 | # Busybox Library Tuning | 90 | # Busybox Library Tuning |
91 | # | 91 | # |
92 | # CONFIG_FEATURE_SYSTEMD is not set | ||
93 | CONFIG_FEATURE_RTMINMAX=y | 92 | CONFIG_FEATURE_RTMINMAX=y |
94 | CONFIG_PASSWORD_MINLEN=6 | 93 | CONFIG_PASSWORD_MINLEN=6 |
95 | CONFIG_MD5_SMALL=1 | 94 | CONFIG_MD5_SMALL=1 |
diff --git a/coreutils/Config.src b/coreutils/Config.src index 21b97d382..619c2efe8 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -543,21 +543,6 @@ config FEATURE_SPLIT_FANCY | |||
543 | Supports additional suffixes 'b' for 512 bytes, | 543 | Supports additional suffixes 'b' for 512 bytes, |
544 | 'g' for 1GiB for the -b option. | 544 | 'g' for 1GiB for the -b option. |
545 | 545 | ||
546 | config STAT | ||
547 | bool "stat" | ||
548 | default y | ||
549 | help | ||
550 | display file or filesystem status. | ||
551 | |||
552 | config FEATURE_STAT_FORMAT | ||
553 | bool "Enable custom formats (-c)" | ||
554 | default y | ||
555 | depends on STAT | ||
556 | help | ||
557 | Without this, stat will not support the '-c format' option where | ||
558 | users can pass a custom format string for output. This adds about | ||
559 | 7k to a nonstatic build on amd64. | ||
560 | |||
561 | config STTY | 546 | config STTY |
562 | bool "stty" | 547 | bool "stty" |
563 | default y | 548 | default y |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 14c8beaff..c48498858 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -1105,7 +1105,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1105 | 1105 | ||
1106 | #if ENABLE_FEATURE_AUTOWIDTH | 1106 | #if ENABLE_FEATURE_AUTOWIDTH |
1107 | /* obtain the terminal width */ | 1107 | /* obtain the terminal width */ |
1108 | get_terminal_width_height(STDIN_FILENO, &G_terminal_width, NULL); | 1108 | G_terminal_width = get_terminal_width(STDIN_FILENO); |
1109 | /* go one less... */ | 1109 | /* go one less... */ |
1110 | G_terminal_width--; | 1110 | G_terminal_width--; |
1111 | #endif | 1111 | #endif |
diff --git a/coreutils/sort.c b/coreutils/sort.c index 36f02543b..07d903388 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -106,7 +106,9 @@ static struct sort_key { | |||
106 | 106 | ||
107 | static char *get_key(char *str, struct sort_key *key, int flags) | 107 | static char *get_key(char *str, struct sort_key *key, int flags) |
108 | { | 108 | { |
109 | int start = 0, end = 0, len, j; | 109 | int start = start; /* for compiler */ |
110 | int end; | ||
111 | int len, j; | ||
110 | unsigned i; | 112 | unsigned i; |
111 | 113 | ||
112 | /* Special case whole string, so we don't have to make a copy */ | 114 | /* Special case whole string, so we don't have to make a copy */ |
@@ -123,12 +125,15 @@ static char *get_key(char *str, struct sort_key *key, int flags) | |||
123 | end = len; | 125 | end = len; |
124 | /* Loop through fields */ | 126 | /* Loop through fields */ |
125 | else { | 127 | else { |
128 | unsigned char ch = 0; | ||
129 | |||
126 | end = 0; | 130 | end = 0; |
127 | for (i = 1; i < key->range[2*j] + j; i++) { | 131 | for (i = 1; i < key->range[2*j] + j; i++) { |
128 | if (key_separator) { | 132 | if (key_separator) { |
129 | /* Skip body of key and separator */ | 133 | /* Skip body of key and separator */ |
130 | while (str[end]) { | 134 | while ((ch = str[end]) != '\0') { |
131 | if (str[end++] == key_separator) | 135 | end++; |
136 | if (ch == key_separator) | ||
132 | break; | 137 | break; |
133 | } | 138 | } |
134 | } else { | 139 | } else { |
@@ -136,7 +141,7 @@ static char *get_key(char *str, struct sort_key *key, int flags) | |||
136 | while (isspace(str[end])) | 141 | while (isspace(str[end])) |
137 | end++; | 142 | end++; |
138 | /* Skip body of key */ | 143 | /* Skip body of key */ |
139 | while (str[end]) { | 144 | while (str[end] != '\0') { |
140 | if (isspace(str[end])) | 145 | if (isspace(str[end])) |
141 | break; | 146 | break; |
142 | end++; | 147 | end++; |
@@ -144,23 +149,29 @@ static char *get_key(char *str, struct sort_key *key, int flags) | |||
144 | } | 149 | } |
145 | } | 150 | } |
146 | /* Remove last delim: "abc:def:" => "abc:def" */ | 151 | /* Remove last delim: "abc:def:" => "abc:def" */ |
147 | if (key_separator && j && end != 0) | 152 | if (j && ch) { |
153 | //if (str[end-1] != key_separator) | ||
154 | // bb_error_msg(_and_die("BUG! " | ||
155 | // "str[start:%d,end:%d]:'%.*s'", | ||
156 | // start, end, (int)(end-start), &str[start]); | ||
148 | end--; | 157 | end--; |
158 | } | ||
149 | } | 159 | } |
150 | if (!j) start = end; | 160 | if (!j) start = end; |
151 | } | 161 | } |
152 | /* Strip leading whitespace if necessary */ | 162 | /* Strip leading whitespace if necessary */ |
153 | //XXX: skip_whitespace() | ||
154 | if (flags & FLAG_b) | 163 | if (flags & FLAG_b) |
164 | /* not using skip_whitespace() for speed */ | ||
155 | while (isspace(str[start])) start++; | 165 | while (isspace(str[start])) start++; |
156 | /* Strip trailing whitespace if necessary */ | 166 | /* Strip trailing whitespace if necessary */ |
157 | if (flags & FLAG_bb) | 167 | if (flags & FLAG_bb) |
158 | while (end > start && isspace(str[end-1])) end--; | 168 | while (end > start && isspace(str[end-1])) end--; |
159 | /* Handle offsets on start and end */ | 169 | /* -kSTART,N.ENDCHAR: honor ENDCHAR (1-based) */ |
160 | if (key->range[3]) { | 170 | if (key->range[3]) { |
161 | end += key->range[3] - 1; | 171 | end = key->range[3]; |
162 | if (end > len) end = len; | 172 | if (end > len) end = len; |
163 | } | 173 | } |
174 | /* -kN.STARTCHAR[,...]: honor STARTCHAR (1-based) */ | ||
164 | if (key->range[1]) { | 175 | if (key->range[1]) { |
165 | start += key->range[1] - 1; | 176 | start += key->range[1] - 1; |
166 | if (start > len) start = len; | 177 | if (start > len) start = len; |
@@ -281,7 +292,7 @@ static int compare_keys(const void *xarg, const void *yarg) | |||
281 | else if (!yy) | 292 | else if (!yy) |
282 | retval = 1; | 293 | retval = 1; |
283 | else | 294 | else |
284 | retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon; | 295 | retval = dx - thyme.tm_mon; |
285 | break; | 296 | break; |
286 | } | 297 | } |
287 | /* Full floating point version of -n */ | 298 | /* Full floating point version of -n */ |
@@ -307,8 +318,8 @@ static int compare_keys(const void *xarg, const void *yarg) | |||
307 | 318 | ||
308 | /* Perform fallback sort if necessary */ | 319 | /* Perform fallback sort if necessary */ |
309 | if (!retval && !(option_mask32 & FLAG_s)) { | 320 | if (!retval && !(option_mask32 & FLAG_s)) { |
310 | retval = strcmp(*(char **)xarg, *(char **)yarg); | ||
311 | flags = option_mask32; | 321 | flags = option_mask32; |
322 | retval = strcmp(*(char **)xarg, *(char **)yarg); | ||
312 | } | 323 | } |
313 | 324 | ||
314 | if (flags & FLAG_r) | 325 | if (flags & FLAG_r) |
@@ -336,7 +347,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
336 | char *line, **lines; | 347 | char *line, **lines; |
337 | char *str_ignored, *str_o, *str_t; | 348 | char *str_ignored, *str_o, *str_t; |
338 | llist_t *lst_k = NULL; | 349 | llist_t *lst_k = NULL; |
339 | int i, flag; | 350 | int i; |
340 | int linecount; | 351 | int linecount; |
341 | unsigned opts; | 352 | unsigned opts; |
342 | 353 | ||
@@ -359,7 +370,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
359 | /* note: below this point we use option_mask32, not opts, | 370 | /* note: below this point we use option_mask32, not opts, |
360 | * since that reduces register pressure and makes code smaller */ | 371 | * since that reduces register pressure and makes code smaller */ |
361 | 372 | ||
362 | /* parse sort key */ | 373 | /* Parse sort key */ |
363 | while (lst_k) { | 374 | while (lst_k) { |
364 | enum { | 375 | enum { |
365 | FLAG_allowed_for_k = | 376 | FLAG_allowed_for_k = |
@@ -386,17 +397,18 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
386 | key->range[2*i+1] = str2u(&str_k); | 397 | key->range[2*i+1] = str2u(&str_k); |
387 | } | 398 | } |
388 | while (*str_k) { | 399 | while (*str_k) { |
389 | const char *temp2; | 400 | int flag; |
401 | const char *idx; | ||
390 | 402 | ||
391 | if (*str_k == ',' && !i++) { | 403 | if (*str_k == ',' && !i++) { |
392 | str_k++; | 404 | str_k++; |
393 | break; | 405 | break; |
394 | } /* no else needed: fall through to syntax error | 406 | } /* no else needed: fall through to syntax error |
395 | because comma isn't in OPT_STR */ | 407 | because comma isn't in OPT_STR */ |
396 | temp2 = strchr(OPT_STR, *str_k); | 408 | idx = strchr(OPT_STR, *str_k); |
397 | if (!temp2) | 409 | if (!idx) |
398 | bb_error_msg_and_die("unknown key option"); | 410 | bb_error_msg_and_die("unknown key option"); |
399 | flag = 1 << (temp2 - OPT_STR); | 411 | flag = 1 << (idx - OPT_STR); |
400 | if (flag & ~FLAG_allowed_for_k) | 412 | if (flag & ~FLAG_allowed_for_k) |
401 | bb_error_msg_and_die("unknown sort type"); | 413 | bb_error_msg_and_die("unknown sort type"); |
402 | /* b after ',' means strip _trailing_ space */ | 414 | /* b after ',' means strip _trailing_ space */ |
@@ -430,10 +442,10 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
430 | } while (*++argv); | 442 | } while (*++argv); |
431 | 443 | ||
432 | #if ENABLE_FEATURE_SORT_BIG | 444 | #if ENABLE_FEATURE_SORT_BIG |
433 | /* if no key, perform alphabetic sort */ | 445 | /* If no key, perform alphabetic sort */ |
434 | if (!key_list) | 446 | if (!key_list) |
435 | add_key()->range[0] = 1; | 447 | add_key()->range[0] = 1; |
436 | /* handle -c */ | 448 | /* Handle -c */ |
437 | if (option_mask32 & FLAG_c) { | 449 | if (option_mask32 & FLAG_c) { |
438 | int j = (option_mask32 & FLAG_u) ? -1 : 0; | 450 | int j = (option_mask32 & FLAG_u) ? -1 : 0; |
439 | for (i = 1; i < linecount; i++) { | 451 | for (i = 1; i < linecount; i++) { |
@@ -447,20 +459,21 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
447 | #endif | 459 | #endif |
448 | /* Perform the actual sort */ | 460 | /* Perform the actual sort */ |
449 | qsort(lines, linecount, sizeof(lines[0]), compare_keys); | 461 | qsort(lines, linecount, sizeof(lines[0]), compare_keys); |
450 | /* handle -u */ | 462 | |
463 | /* Handle -u */ | ||
451 | if (option_mask32 & FLAG_u) { | 464 | if (option_mask32 & FLAG_u) { |
452 | flag = 0; | 465 | int j = 0; |
453 | /* coreutils 6.3 drop lines for which only key is the same */ | 466 | /* coreutils 6.3 drop lines for which only key is the same */ |
454 | /* -- disabling last-resort compare... */ | 467 | /* -- disabling last-resort compare... */ |
455 | option_mask32 |= FLAG_s; | 468 | option_mask32 |= FLAG_s; |
456 | for (i = 1; i < linecount; i++) { | 469 | for (i = 1; i < linecount; i++) { |
457 | if (compare_keys(&lines[flag], &lines[i]) == 0) | 470 | if (compare_keys(&lines[j], &lines[i]) == 0) |
458 | free(lines[i]); | 471 | free(lines[i]); |
459 | else | 472 | else |
460 | lines[++flag] = lines[i]; | 473 | lines[++j] = lines[i]; |
461 | } | 474 | } |
462 | if (linecount) | 475 | if (linecount) |
463 | linecount = flag+1; | 476 | linecount = j+1; |
464 | } | 477 | } |
465 | 478 | ||
466 | /* Print it */ | 479 | /* Print it */ |
@@ -469,9 +482,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
469 | if (option_mask32 & FLAG_o) | 482 | if (option_mask32 & FLAG_o) |
470 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); | 483 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); |
471 | #endif | 484 | #endif |
472 | flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; | 485 | { |
473 | for (i = 0; i < linecount; i++) | 486 | int ch = (option_mask32 & FLAG_z) ? '\0' : '\n'; |
474 | printf("%s%c", lines[i], flag); | 487 | for (i = 0; i < linecount; i++) |
488 | printf("%s%c", lines[i], ch); | ||
489 | } | ||
475 | 490 | ||
476 | fflush_stdout_and_exit(EXIT_SUCCESS); | 491 | fflush_stdout_and_exit(EXIT_SUCCESS); |
477 | } | 492 | } |
diff --git a/coreutils/stat.c b/coreutils/stat.c index f7fd227bb..1a490fef7 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
@@ -12,54 +12,83 @@ | |||
12 | * | 12 | * |
13 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 13 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
14 | */ | 14 | */ |
15 | //config:config STAT | ||
16 | //config: bool "stat" | ||
17 | //config: default y | ||
18 | //config: help | ||
19 | //config: display file or filesystem status. | ||
20 | //config: | ||
21 | //config:config FEATURE_STAT_FORMAT | ||
22 | //config: bool "Enable custom formats (-c)" | ||
23 | //config: default y | ||
24 | //config: depends on STAT | ||
25 | //config: help | ||
26 | //config: Without this, stat will not support the '-c format' option where | ||
27 | //config: users can pass a custom format string for output. This adds about | ||
28 | //config: 7k to a nonstatic build on amd64. | ||
29 | //config: | ||
30 | //config:config FEATURE_STAT_FILESYSTEM | ||
31 | //config: bool "Enable display of filesystem status (-f)" | ||
32 | //config: default y | ||
33 | //config: depends on STAT | ||
34 | //config: select PLATFORM_LINUX # statfs() | ||
35 | //config: help | ||
36 | //config: Without this, stat will not support the '-f' option to display | ||
37 | //config: information about filesystem status. | ||
38 | |||
15 | 39 | ||
16 | //usage:#define stat_trivial_usage | 40 | //usage:#define stat_trivial_usage |
17 | //usage: "[OPTIONS] FILE..." | 41 | //usage: "[OPTIONS] FILE..." |
18 | //usage:#define stat_full_usage "\n\n" | 42 | //usage:#define stat_full_usage "\n\n" |
19 | //usage: "Display file (default) or filesystem status\n" | 43 | //usage: "Display file" |
44 | //usage: IF_FEATURE_STAT_FILESYSTEM(" (default) or filesystem") | ||
45 | //usage: " status\n" | ||
20 | //usage: IF_FEATURE_STAT_FORMAT( | 46 | //usage: IF_FEATURE_STAT_FORMAT( |
21 | //usage: "\n -c fmt Use the specified format" | 47 | //usage: "\n -c FMT Use the specified format" |
22 | //usage: ) | 48 | //usage: ) |
49 | //usage: IF_FEATURE_STAT_FILESYSTEM( | ||
23 | //usage: "\n -f Display filesystem status" | 50 | //usage: "\n -f Display filesystem status" |
51 | //usage: ) | ||
24 | //usage: "\n -L Follow links" | 52 | //usage: "\n -L Follow links" |
25 | //usage: "\n -t Display info in terse form" | 53 | //usage: "\n -t Terse display" |
26 | //usage: IF_SELINUX( | 54 | //usage: IF_SELINUX( |
27 | //usage: "\n -Z Print security context" | 55 | //usage: "\n -Z Print security context" |
28 | //usage: ) | 56 | //usage: ) |
29 | //usage: IF_FEATURE_STAT_FORMAT( | 57 | //usage: IF_FEATURE_STAT_FORMAT( |
30 | //usage: "\n\nValid format sequences for files:\n" | 58 | //usage: "\n\nFMT sequences"IF_FEATURE_STAT_FILESYSTEM(" for files")":\n" |
31 | //usage: " %a Access rights in octal\n" | 59 | //usage: " %a Access rights in octal\n" |
32 | //usage: " %A Access rights in human readable form\n" | 60 | //usage: " %A Access rights in human readable form\n" |
33 | //usage: " %b Number of blocks allocated (see %B)\n" | 61 | //usage: " %b Number of blocks allocated (see %B)\n" |
34 | //usage: " %B The size in bytes of each block reported by %b\n" | 62 | //usage: " %B Size in bytes of each block reported by %b\n" |
35 | //usage: " %d Device number in decimal\n" | 63 | //usage: " %d Device number in decimal\n" |
36 | //usage: " %D Device number in hex\n" | 64 | //usage: " %D Device number in hex\n" |
37 | //usage: " %f Raw mode in hex\n" | 65 | //usage: " %f Raw mode in hex\n" |
38 | //usage: " %F File type\n" | 66 | //usage: " %F File type\n" |
39 | //usage: " %g Group ID of owner\n" | 67 | //usage: " %g Group ID\n" |
40 | //usage: " %G Group name of owner\n" | 68 | //usage: " %G Group name\n" |
41 | //usage: " %h Number of hard links\n" | 69 | //usage: " %h Number of hard links\n" |
42 | //usage: " %i Inode number\n" | 70 | //usage: " %i Inode number\n" |
43 | //usage: " %n File name\n" | 71 | //usage: " %n File name\n" |
44 | //usage: " %N File name, with -> TARGET if symlink\n" | 72 | //usage: " %N File name, with -> TARGET if symlink\n" |
45 | //usage: " %o I/O block size\n" | 73 | //usage: " %o I/O block size\n" |
46 | //usage: " %s Total size, in bytes\n" | 74 | //usage: " %s Total size in bytes\n" |
47 | //usage: " %t Major device type in hex\n" | 75 | //usage: " %t Major device type in hex\n" |
48 | //usage: " %T Minor device type in hex\n" | 76 | //usage: " %T Minor device type in hex\n" |
49 | //usage: " %u User ID of owner\n" | 77 | //usage: " %u User ID\n" |
50 | //usage: " %U User name of owner\n" | 78 | //usage: " %U User name\n" |
51 | //usage: " %x Time of last access\n" | 79 | //usage: " %x Time of last access\n" |
52 | //usage: " %X Time of last access as seconds since Epoch\n" | 80 | //usage: " %X Time of last access as seconds since Epoch\n" |
53 | //usage: " %y Time of last modification\n" | 81 | //usage: " %y Time of last modification\n" |
54 | //usage: " %Y Time of last modification as seconds since Epoch\n" | 82 | //usage: " %Y Time of last modification as seconds since Epoch\n" |
55 | //usage: " %z Time of last change\n" | 83 | //usage: " %z Time of last change\n" |
56 | //usage: " %Z Time of last change as seconds since Epoch\n" | 84 | //usage: " %Z Time of last change as seconds since Epoch\n" |
57 | //usage: "\nValid format sequences for file systems:\n" | 85 | //usage: IF_FEATURE_STAT_FILESYSTEM( |
86 | //usage: "\nFMT sequences for file systems:\n" | ||
58 | //usage: " %a Free blocks available to non-superuser\n" | 87 | //usage: " %a Free blocks available to non-superuser\n" |
59 | //usage: " %b Total data blocks in file system\n" | 88 | //usage: " %b Total data blocks\n" |
60 | //usage: " %c Total file nodes in file system\n" | 89 | //usage: " %c Total file nodes\n" |
61 | //usage: " %d Free file nodes in file system\n" | 90 | //usage: " %d Free file nodes\n" |
62 | //usage: " %f Free blocks in file system\n" | 91 | //usage: " %f Free blocks\n" |
63 | //usage: IF_SELINUX( | 92 | //usage: IF_SELINUX( |
64 | //usage: " %C Security context in selinux\n" | 93 | //usage: " %C Security context in selinux\n" |
65 | //usage: ) | 94 | //usage: ) |
@@ -71,13 +100,16 @@ | |||
71 | //usage: " %t Type in hex\n" | 100 | //usage: " %t Type in hex\n" |
72 | //usage: " %T Type in human readable form" | 101 | //usage: " %T Type in human readable form" |
73 | //usage: ) | 102 | //usage: ) |
103 | //usage: ) | ||
74 | 104 | ||
75 | #include "libbb.h" | 105 | #include "libbb.h" |
76 | 106 | ||
77 | #define OPT_FILESYS (1 << 0) | 107 | enum { |
78 | #define OPT_TERSE (1 << 1) | 108 | OPT_TERSE = (1 << 0), |
79 | #define OPT_DEREFERENCE (1 << 2) | 109 | OPT_DEREFERENCE = (1 << 1), |
80 | #define OPT_SELINUX (1 << 3) | 110 | OPT_FILESYS = (1 << 2) * ENABLE_FEATURE_STAT_FILESYSTEM, |
111 | OPT_SELINUX = (1 << (2+ENABLE_FEATURE_STAT_FILESYSTEM)) * ENABLE_SELINUX, | ||
112 | }; | ||
81 | 113 | ||
82 | #if ENABLE_FEATURE_STAT_FORMAT | 114 | #if ENABLE_FEATURE_STAT_FORMAT |
83 | typedef bool (*statfunc_ptr)(const char *, const char *); | 115 | typedef bool (*statfunc_ptr)(const char *, const char *); |
@@ -132,6 +164,7 @@ static const char *human_time(time_t t) | |||
132 | #undef buf | 164 | #undef buf |
133 | } | 165 | } |
134 | 166 | ||
167 | #if ENABLE_FEATURE_STAT_FILESYSTEM | ||
135 | /* Return the type of the specified file system. | 168 | /* Return the type of the specified file system. |
136 | * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris) | 169 | * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris) |
137 | * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2) | 170 | * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2) |
@@ -202,6 +235,7 @@ static unsigned long long get_f_fsid(const struct statfs *statfsbuf) | |||
202 | while (--sz > 0); | 235 | while (--sz > 0); |
203 | return r; | 236 | return r; |
204 | } | 237 | } |
238 | #endif /* FEATURE_STAT_FILESYSTEM */ | ||
205 | 239 | ||
206 | #if ENABLE_FEATURE_STAT_FORMAT | 240 | #if ENABLE_FEATURE_STAT_FORMAT |
207 | static void strcatc(char *str, char c) | 241 | static void strcatc(char *str, char c) |
@@ -217,6 +251,7 @@ static void printfs(char *pformat, const char *msg) | |||
217 | printf(pformat, msg); | 251 | printf(pformat, msg); |
218 | } | 252 | } |
219 | 253 | ||
254 | #if ENABLE_FEATURE_STAT_FILESYSTEM | ||
220 | /* print statfs info */ | 255 | /* print statfs info */ |
221 | static void FAST_FUNC print_statfs(char *pformat, const char m, | 256 | static void FAST_FUNC print_statfs(char *pformat, const char m, |
222 | const char *const filename, const void *data | 257 | const char *const filename, const void *data |
@@ -263,6 +298,7 @@ static void FAST_FUNC print_statfs(char *pformat, const char m, | |||
263 | printf(pformat, m); | 298 | printf(pformat, m); |
264 | } | 299 | } |
265 | } | 300 | } |
301 | #endif | ||
266 | 302 | ||
267 | /* print stat info */ | 303 | /* print stat info */ |
268 | static void FAST_FUNC print_stat(char *pformat, const char m, | 304 | static void FAST_FUNC print_stat(char *pformat, const char m, |
@@ -423,6 +459,7 @@ static void print_it(const char *masterformat, | |||
423 | } | 459 | } |
424 | #endif /* FEATURE_STAT_FORMAT */ | 460 | #endif /* FEATURE_STAT_FORMAT */ |
425 | 461 | ||
462 | #if ENABLE_FEATURE_STAT_FILESYSTEM | ||
426 | /* Stat the file system and print what we find. */ | 463 | /* Stat the file system and print what we find. */ |
427 | #if !ENABLE_FEATURE_STAT_FORMAT | 464 | #if !ENABLE_FEATURE_STAT_FORMAT |
428 | #define do_statfs(filename, format) do_statfs(filename) | 465 | #define do_statfs(filename, format) do_statfs(filename) |
@@ -538,6 +575,7 @@ static bool do_statfs(const char *filename, const char *format) | |||
538 | #endif /* FEATURE_STAT_FORMAT */ | 575 | #endif /* FEATURE_STAT_FORMAT */ |
539 | return 1; | 576 | return 1; |
540 | } | 577 | } |
578 | #endif /* FEATURE_STAT_FILESYSTEM */ | ||
541 | 579 | ||
542 | /* stat the file and print what we find */ | 580 | /* stat the file and print what we find */ |
543 | #if !ENABLE_FEATURE_STAT_FORMAT | 581 | #if !ENABLE_FEATURE_STAT_FORMAT |
@@ -721,12 +759,15 @@ int stat_main(int argc UNUSED_PARAM, char **argv) | |||
721 | statfunc_ptr statfunc = do_stat; | 759 | statfunc_ptr statfunc = do_stat; |
722 | 760 | ||
723 | opt_complementary = "-1"; /* min one arg */ | 761 | opt_complementary = "-1"; /* min one arg */ |
724 | opts = getopt32(argv, "ftL" | 762 | opts = getopt32(argv, "tL" |
763 | IF_FEATURE_STAT_FILESYSTEM("f") | ||
725 | IF_SELINUX("Z") | 764 | IF_SELINUX("Z") |
726 | IF_FEATURE_STAT_FORMAT("c:", &format) | 765 | IF_FEATURE_STAT_FORMAT("c:", &format) |
727 | ); | 766 | ); |
767 | #if ENABLE_FEATURE_STAT_FILESYSTEM | ||
728 | if (opts & OPT_FILESYS) /* -f */ | 768 | if (opts & OPT_FILESYS) /* -f */ |
729 | statfunc = do_statfs; | 769 | statfunc = do_statfs; |
770 | #endif | ||
730 | #if ENABLE_SELINUX | 771 | #if ENABLE_SELINUX |
731 | if (opts & OPT_SELINUX) { | 772 | if (opts & OPT_SELINUX) { |
732 | selinux_or_die(); | 773 | selinux_or_die(); |
diff --git a/coreutils/stty.c b/coreutils/stty.c index 378a848e7..b63b0b91a 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -1403,7 +1403,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv) | |||
1403 | perror_on_device_and_die("%s"); | 1403 | perror_on_device_and_die("%s"); |
1404 | 1404 | ||
1405 | if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { | 1405 | if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { |
1406 | get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL); | 1406 | G.max_col = get_terminal_width(STDOUT_FILENO); |
1407 | output_func(&mode, display_all); | 1407 | output_func(&mode, display_all); |
1408 | return EXIT_SUCCESS; | 1408 | return EXIT_SUCCESS; |
1409 | } | 1409 | } |
diff --git a/coreutils/tr.c b/coreutils/tr.c index e67948a36..2f49d5a86 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -91,7 +91,6 @@ static void map(char *pvector, | |||
91 | * Character classes, e.g. [:upper:] ==> A...Z | 91 | * Character classes, e.g. [:upper:] ==> A...Z |
92 | * Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?) | 92 | * Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?) |
93 | * not supported: | 93 | * not supported: |
94 | * \ooo-\ooo - octal ranges | ||
95 | * [x*N] - repeat char x N times | 94 | * [x*N] - repeat char x N times |
96 | * [x*] - repeat char x until it fills STRING2: | 95 | * [x*] - repeat char x until it fills STRING2: |
97 | * # echo qwe123 | /usr/bin/tr 123456789 '[d]' | 96 | * # echo qwe123 | /usr/bin/tr 123456789 '[d]' |
@@ -99,7 +98,7 @@ static void map(char *pvector, | |||
99 | * # echo qwe123 | /usr/bin/tr 123456789 '[d*]' | 98 | * # echo qwe123 | /usr/bin/tr 123456789 '[d*]' |
100 | * qweddd | 99 | * qweddd |
101 | */ | 100 | */ |
102 | static unsigned expand(const char *arg, char **buffer_p) | 101 | static unsigned expand(char *arg, char **buffer_p) |
103 | { | 102 | { |
104 | char *buffer = *buffer_p; | 103 | char *buffer = *buffer_p; |
105 | unsigned pos = 0; | 104 | unsigned pos = 0; |
@@ -113,9 +112,17 @@ static unsigned expand(const char *arg, char **buffer_p) | |||
113 | *buffer_p = buffer = xrealloc(buffer, size); | 112 | *buffer_p = buffer = xrealloc(buffer, size); |
114 | } | 113 | } |
115 | if (*arg == '\\') { | 114 | if (*arg == '\\') { |
115 | const char *z; | ||
116 | arg++; | 116 | arg++; |
117 | buffer[pos++] = bb_process_escape_sequence(&arg); | 117 | z = arg; |
118 | continue; | 118 | ac = bb_process_escape_sequence(&z); |
119 | arg = (char *)z; | ||
120 | arg--; | ||
121 | *arg = ac; | ||
122 | /* | ||
123 | * fall through, there may be a range. | ||
124 | * If not, current char will be treated anyway. | ||
125 | */ | ||
119 | } | 126 | } |
120 | if (arg[1] == '-') { /* "0-9..." */ | 127 | if (arg[1] == '-') { /* "0-9..." */ |
121 | ac = arg[2]; | 128 | ac = arg[2]; |
@@ -124,9 +131,15 @@ static unsigned expand(const char *arg, char **buffer_p) | |||
124 | continue; /* next iter will copy '-' and stop */ | 131 | continue; /* next iter will copy '-' and stop */ |
125 | } | 132 | } |
126 | i = (unsigned char) *arg; | 133 | i = (unsigned char) *arg; |
134 | arg += 3; /* skip 0-9 or 0-\ */ | ||
135 | if (ac == '\\') { | ||
136 | const char *z; | ||
137 | z = arg; | ||
138 | ac = bb_process_escape_sequence(&z); | ||
139 | arg = (char *)z; | ||
140 | } | ||
127 | while (i <= ac) /* ok: i is unsigned _int_ */ | 141 | while (i <= ac) /* ok: i is unsigned _int_ */ |
128 | buffer[pos++] = i++; | 142 | buffer[pos++] = i++; |
129 | arg += 3; /* skip 0-9 */ | ||
130 | continue; | 143 | continue; |
131 | } | 144 | } |
132 | if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV) | 145 | if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV) |
diff --git a/examples/var_service/README b/examples/var_service/README index 9ad1b2581..d096ad0b9 100644 --- a/examples/var_service/README +++ b/examples/var_service/README | |||
@@ -36,10 +36,10 @@ service accordingly. In effect, it allows you to unplug/plug-to-different-networ | |||
36 | and have your IP properly re-negotiated at once. | 36 | and have your IP properly re-negotiated at once. |
37 | 37 | ||
38 | var_service/dhcp_if_pinger - | 38 | var_service/dhcp_if_pinger - |
39 | Uses var_service/dhcp_if's data (/var/service/dhcp_if/dhcp_if.out file) | 39 | Uses var_service/dhcp_if's data to determine router IP. Pings it. |
40 | to determine router IP. Pings it. If ping fails, restarts /var/service/dhcp_if | 40 | If ping fails, restarts /var/service/dhcp_if service. |
41 | service. Basically, an example of watchdog service for networks | 41 | Basically, an example of watchdog service for networks which are not reliable |
42 | which are not reliable and need babysitting. | 42 | and need babysitting. |
43 | 43 | ||
44 | var_service/fw - | 44 | var_service/fw - |
45 | A *one-shot* service which reconfigures network based on current known state | 45 | A *one-shot* service which reconfigures network based on current known state |
diff --git a/examples/var_service/dhcp_if/convert2ntpconf b/examples/var_service/dhcp_if/convert2ntpconf index debf1ebfe..e9d829308 100755 --- a/examples/var_service/dhcp_if/convert2ntpconf +++ b/examples/var_service/dhcp_if/convert2ntpconf | |||
@@ -29,6 +29,6 @@ test "$ip" || exit 1 | |||
29 | { | 29 | { |
30 | for n in $ntpsrv; do | 30 | for n in $ntpsrv; do |
31 | echo "let cfg=cfg+1" | 31 | echo "let cfg=cfg+1" |
32 | echo "ntpip[\$cfg]='$n'"; | 32 | echo "ntpip[\$cfg]='$n'" |
33 | done | 33 | done |
34 | } >"$1" | 34 | } >"$1" |
diff --git a/examples/var_service/dhcp_if/dhcp_handler b/examples/var_service/dhcp_if/dhcp_handler index 927e02a17..3d2a5cb79 100755 --- a/examples/var_service/dhcp_if/dhcp_handler +++ b/examples/var_service/dhcp_if/dhcp_handler | |||
@@ -36,7 +36,7 @@ service=${PWD##*/} | |||
36 | file_ipconf="$service.ipconf" | 36 | file_ipconf="$service.ipconf" |
37 | file_ntpconf="$service.ntpconf" | 37 | file_ntpconf="$service.ntpconf" |
38 | dir_ipconf="/var/run/service/fw" | 38 | dir_ipconf="/var/run/service/fw" |
39 | dir_ntpconf="/var/run/service/ntp" | 39 | dir_ntpconf="/var/run/service/ntpd" |
40 | 40 | ||
41 | exec >/dev/null | 41 | exec >/dev/null |
42 | #exec >>"$0.out" #debug | 42 | #exec >>"$0.out" #debug |
@@ -47,7 +47,7 @@ echo "`date`: Params: $*" | |||
47 | if test x"$1" != x"bound" && test x"$1" != x"renew" ; then | 47 | if test x"$1" != x"bound" && test x"$1" != x"renew" ; then |
48 | # Reconfigure network with this interface disabled | 48 | # Reconfigure network with this interface disabled |
49 | echo "Deconfiguring" | 49 | echo "Deconfiguring" |
50 | rm "$service.out" | 50 | rm "env.out" |
51 | rm "$file_ipconf" | 51 | rm "$file_ipconf" |
52 | rm "$file_ntpconf" | 52 | rm "$file_ntpconf" |
53 | rm "$dir_ipconf/$file_ipconf" | 53 | rm "$dir_ipconf/$file_ipconf" |
@@ -57,7 +57,8 @@ if test x"$1" != x"bound" && test x"$1" != x"renew" ; then | |||
57 | fi | 57 | fi |
58 | 58 | ||
59 | # Bound: we've got the lease | 59 | # Bound: we've got the lease |
60 | #env >"$service.out" # debug | 60 | # Record information for e.g. dhcp_$IF_pinger service |
61 | env >"env.out" | ||
61 | 62 | ||
62 | ./convert2ipconf "$file_ipconf" | 63 | ./convert2ipconf "$file_ipconf" |
63 | # Reconfigure routing and firewall if needed | 64 | # Reconfigure routing and firewall if needed |
@@ -69,7 +70,7 @@ if test $? != 0; then | |||
69 | sv u /var/service/fw | 70 | sv u /var/service/fw |
70 | fi | 71 | fi |
71 | 72 | ||
72 | if test -d /var/service/ntp; then | 73 | if test -d /var/service/ntpd; then |
73 | ./convert2ntpconf "$file_ntpconf" | 74 | ./convert2ntpconf "$file_ntpconf" |
74 | # Reconfigure ntp server addresses if needed | 75 | # Reconfigure ntp server addresses if needed |
75 | diff --brief "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" >/dev/null 2>&1 | 76 | diff --brief "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" >/dev/null 2>&1 |
@@ -77,7 +78,7 @@ if test -d /var/service/ntp; then | |||
77 | echo "Reconfiguring ntp" | 78 | echo "Reconfiguring ntp" |
78 | mkdir -p "$dir_ntpconf" 2>/dev/null | 79 | mkdir -p "$dir_ntpconf" 2>/dev/null |
79 | cp "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" | 80 | cp "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" |
80 | sv t /var/service/ntp | 81 | sv t /var/service/ntpd |
81 | sv u /var/service/ntp | 82 | sv u /var/service/ntpd |
82 | fi | 83 | fi |
83 | fi | 84 | fi |
diff --git a/examples/var_service/dhcp_if/finish b/examples/var_service/dhcp_if/finish new file mode 100755 index 000000000..5e7667a2d --- /dev/null +++ b/examples/var_service/dhcp_if/finish | |||
@@ -0,0 +1,17 @@ | |||
1 | #!/bin/sh | ||
2 | # executed when service is taken down ("sv d .") | ||
3 | |||
4 | service=${PWD##*/} | ||
5 | file_ipconf="$service.ipconf" | ||
6 | file_ntpconf="$service.ntpconf" | ||
7 | dir_ipconf="/var/run/service/fw" | ||
8 | dir_ntpconf="/var/run/service/ntpd" | ||
9 | |||
10 | # Reconfigure network with this interface disabled | ||
11 | echo "Finish: deconfiguring" | ||
12 | rm "env.out" | ||
13 | rm "$file_ipconf" | ||
14 | rm "$file_ntpconf" | ||
15 | rm "$dir_ipconf/$file_ipconf" | ||
16 | rm "$dir_ntpconf/$file_ntpconf" | ||
17 | sv u /var/service/fw | ||
diff --git a/examples/var_service/dhcp_if/log/run b/examples/var_service/dhcp_if/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/dhcp_if/log/run +++ b/examples/var_service/dhcp_if/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/dhcp_if_pinger/run b/examples/var_service/dhcp_if_pinger/run index 1868510d1..e0e87a16a 100755 --- a/examples/var_service/dhcp_if_pinger/run +++ b/examples/var_service/dhcp_if_pinger/run | |||
@@ -21,9 +21,9 @@ if test -f "$0.log"; then | |||
21 | mv "$0.log.new" "$0.log" | 21 | mv "$0.log.new" "$0.log" |
22 | fi | 22 | fi |
23 | 23 | ||
24 | test -f "/var/service/dhcp_$if/dhcp_$if.out" || exec env - sleep "$ping_time" | 24 | test -f "/var/service/dhcp_$if/env.out" || exec env - sleep "$ping_time" |
25 | 25 | ||
26 | . "/var/service/dhcp_$if/dhcp_$if.out" | 26 | . "/var/service/dhcp_$if/env.out" |
27 | test x"$router" != x"" || exec env - sleep "$ping_time" | 27 | test x"$router" != x"" || exec env - sleep "$ping_time" |
28 | 28 | ||
29 | #msg "Pinging $router" | 29 | #msg "Pinging $router" |
diff --git a/examples/var_service/ftpd/log/run b/examples/var_service/ftpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ftpd/log/run +++ b/examples/var_service/ftpd/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/fw/run b/examples/var_service/fw/run index 396b678ab..81c7f2e7c 100755 --- a/examples/var_service/fw/run +++ b/examples/var_service/fw/run | |||
@@ -62,7 +62,7 @@ umask 077 | |||
62 | 62 | ||
63 | # Make sure rundir/ exists | 63 | # Make sure rundir/ exists |
64 | mkdir -p "$rundir" 2>/dev/null | 64 | mkdir -p "$rundir" 2>/dev/null |
65 | chown -R "$user:" "$rundir" | 65 | chown -R "$user": "$rundir" |
66 | chmod -R a=rX "$rundir" | 66 | chmod -R a=rX "$rundir" |
67 | rm -rf rundir 2>/dev/null | 67 | rm -rf rundir 2>/dev/null |
68 | ln -s "$rundir" rundir | 68 | ln -s "$rundir" rundir |
diff --git a/examples/var_service/httpd/log/run b/examples/var_service/httpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/httpd/log/run +++ b/examples/var_service/httpd/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/ifplugd_if/log/run b/examples/var_service/ifplugd_if/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ifplugd_if/log/run +++ b/examples/var_service/ifplugd_if/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/ifplugd_if/run b/examples/var_service/ifplugd_if/run index 2781cf9f9..c4f766e88 100755 --- a/examples/var_service/ifplugd_if/run +++ b/examples/var_service/ifplugd_if/run | |||
@@ -8,6 +8,9 @@ pwd="$PWD" | |||
8 | 8 | ||
9 | if="${PWD##*/ifplugd_}" | 9 | if="${PWD##*/ifplugd_}" |
10 | 10 | ||
11 | echo "* Upping iface $if" | ||
12 | ip link set dev "$if" up | ||
13 | |||
11 | echo "* Starting ifplugd on $if [$$]" | 14 | echo "* Starting ifplugd on $if [$$]" |
12 | exec \ | 15 | exec \ |
13 | env - PATH="$PATH" \ | 16 | env - PATH="$PATH" \ |
diff --git a/examples/var_service/inetd/log/run b/examples/var_service/inetd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/inetd/log/run +++ b/examples/var_service/inetd/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/ntpd/log/run b/examples/var_service/ntpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ntpd/log/run +++ b/examples/var_service/ntpd/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/ntpd/run b/examples/var_service/ntpd/run index 581d231a3..6f2a68188 100755 --- a/examples/var_service/ntpd/run +++ b/examples/var_service/ntpd/run | |||
@@ -15,7 +15,7 @@ default_p_opt="-p 0.$pool -p 1.$pool -p 2.$pool -p 3.$pool" | |||
15 | 15 | ||
16 | # Make sure rundir/ exists | 16 | # Make sure rundir/ exists |
17 | mkdir -p "$rundir" 2>/dev/null | 17 | mkdir -p "$rundir" 2>/dev/null |
18 | chown -R "$user:" "$rundir" | 18 | chown -R "$user": "$rundir" |
19 | chmod -R a=rX "$rundir" | 19 | chmod -R a=rX "$rundir" |
20 | rm -rf rundir 2>/dev/null | 20 | rm -rf rundir 2>/dev/null |
21 | ln -s "$rundir" rundir | 21 | ln -s "$rundir" rundir |
diff --git a/examples/var_service/tftpd/log/run b/examples/var_service/tftpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/tftpd/log/run +++ b/examples/var_service/tftpd/log/run | |||
@@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" | |||
6 | mkdir -p "$logdir" 2>/dev/null | 6 | mkdir -p "$logdir" 2>/dev/null |
7 | chown -R "$user": "$logdir" | 7 | chown -R "$user": "$logdir" |
8 | chmod -R go-rwxst,u+rwX "$logdir" | 8 | chmod -R go-rwxst,u+rwX "$logdir" |
9 | rm logdir | 9 | rm -rf logdir |
10 | ln -s "$logdir" logdir | 10 | ln -s "$logdir" logdir |
11 | 11 | ||
12 | # make this dir accessible to logger | 12 | # make this dir accessible to logger |
diff --git a/examples/var_service/zcip_if/README b/examples/var_service/zcip_if/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/zcip_if/README | |||
@@ -0,0 +1,5 @@ | |||
1 | The real README file is one directory up. | ||
2 | |||
3 | This directory's run script can have useful comments. | ||
4 | If it doesn't but you feel it should, please send a patch | ||
5 | to busybox's mailing list. | ||
diff --git a/examples/var_service/zcip_if/convert2ipconf b/examples/var_service/zcip_if/convert2ipconf new file mode 100755 index 000000000..c858723fb --- /dev/null +++ b/examples/var_service/zcip_if/convert2ipconf | |||
@@ -0,0 +1,24 @@ | |||
1 | #!/bin/sh | ||
2 | # convert: | ||
3 | |||
4 | #interface=eth1 | ||
5 | #ip=169.254.x.y | ||
6 | |||
7 | # into: | ||
8 | |||
9 | #let cfg=cfg+1 | ||
10 | #if[$cfg]=...; ip[$cfg]=...; ipmask[$cfg]=.../...; gw[$cfg]=...; net[$cfg]=... dns[$cfg]=... | ||
11 | |||
12 | exec >/dev/null | ||
13 | #exec >"$0.out" # debug | ||
14 | exec 2>&1 | ||
15 | |||
16 | test "$interface" || exit 1 | ||
17 | test "$ip" || exit 1 | ||
18 | |||
19 | { | ||
20 | echo "let cfg=cfg+1" | ||
21 | test "$interface" && echo "if[\$cfg]='$interface'" | ||
22 | test "$ip" && echo "ip[\$cfg]='$ip'" | ||
23 | test "$ip" && echo "ipmask[\$cfg]='$ip/16'" | ||
24 | } >"$1" | ||
diff --git a/examples/var_service/zcip_if/finish b/examples/var_service/zcip_if/finish new file mode 100755 index 000000000..95995cf5f --- /dev/null +++ b/examples/var_service/zcip_if/finish | |||
@@ -0,0 +1,13 @@ | |||
1 | #!/bin/sh | ||
2 | # executed when service is taken down ("sv d .") | ||
3 | |||
4 | service=${PWD##*/} | ||
5 | file_ipconf="$service.ipconf" | ||
6 | dir_ipconf="/var/run/service/fw" | ||
7 | |||
8 | # Reconfigure network with this interface disabled | ||
9 | echo "Finish: deconfiguring" | ||
10 | rm "env.out" | ||
11 | rm "$file_ipconf" | ||
12 | rm "$dir_ipconf/$file_ipconf" | ||
13 | sv u /var/service/fw | ||
diff --git a/examples/var_service/zcip_if/log/run b/examples/var_service/zcip_if/log/run new file mode 100755 index 000000000..69d74b73f --- /dev/null +++ b/examples/var_service/zcip_if/log/run | |||
@@ -0,0 +1,21 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | user=logger | ||
4 | |||
5 | logdir="/var/log/service/`(cd ..;basename $PWD)`" | ||
6 | mkdir -p "$logdir" 2>/dev/null | ||
7 | chown -R "$user": "$logdir" | ||
8 | chmod -R go-rwxst,u+rwX "$logdir" | ||
9 | rm -rf logdir | ||
10 | ln -s "$logdir" logdir | ||
11 | |||
12 | # make this dir accessible to logger | ||
13 | chmod a+rX . | ||
14 | |||
15 | exec >/dev/null | ||
16 | exec 2>&1 | ||
17 | exec \ | ||
18 | env - PATH="$PATH" \ | ||
19 | softlimit \ | ||
20 | setuidgid "$user" \ | ||
21 | svlogd -tt "$logdir" | ||
diff --git a/examples/var_service/zcip_if/p_log b/examples/var_service/zcip_if/p_log new file mode 100755 index 000000000..a2521be05 --- /dev/null +++ b/examples/var_service/zcip_if/p_log | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | cd log/logdir || exit 1 | ||
4 | cat @* current | $PAGER | ||
diff --git a/examples/var_service/zcip_if/run b/examples/var_service/zcip_if/run new file mode 100755 index 000000000..94a875465 --- /dev/null +++ b/examples/var_service/zcip_if/run | |||
@@ -0,0 +1,20 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | exec 2>&1 | ||
4 | exec </dev/null | ||
5 | |||
6 | pwd="$PWD" | ||
7 | |||
8 | if="${PWD##*/zcip_}" | ||
9 | |||
10 | echo "* Upping iface $if" | ||
11 | ip link set dev "$if" up | ||
12 | |||
13 | echo "* Starting zcip" | ||
14 | exec \ | ||
15 | env - PATH="$PATH" \ | ||
16 | softlimit \ | ||
17 | setuidgid root \ | ||
18 | zcip -fvv \ | ||
19 | "$if" \ | ||
20 | "$pwd/zcip_handler" | ||
diff --git a/examples/var_service/zcip_if/w_log b/examples/var_service/zcip_if/w_log new file mode 100755 index 000000000..aa36ef13b --- /dev/null +++ b/examples/var_service/zcip_if/w_log | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | cd log/logdir || exit 1 | ||
4 | watch -n2 'w=`ttysize w`; h=`ttysize h`; tail -$((h-3)) current 2>&1 | cut -b1-$((w-2))' | ||
diff --git a/examples/var_service/zcip_if/zcip_handler b/examples/var_service/zcip_if/zcip_handler new file mode 100755 index 000000000..3c6ca788b --- /dev/null +++ b/examples/var_service/zcip_if/zcip_handler | |||
@@ -0,0 +1,47 @@ | |||
1 | #!/bin/sh | ||
2 | # executed by zcip | ||
3 | # parameters: $1 and environment | ||
4 | # $1 is: | ||
5 | # | ||
6 | # init: zcip starts. Environment: | ||
7 | # interface=eth0 | ||
8 | # | ||
9 | # config: Address is obtained. | ||
10 | # interface=eth0 | ||
11 | # ip=169.254.a.b | ||
12 | # | ||
13 | # deconfig: Conflict or link went down. | ||
14 | # interface=eth0 | ||
15 | |||
16 | service=${PWD##*/} | ||
17 | file_ipconf="$service.ipconf" | ||
18 | dir_ipconf="/var/run/service/fw" | ||
19 | |||
20 | exec >/dev/null | ||
21 | #exec >>"$0.out" #debug | ||
22 | exec 2>&1 | ||
23 | |||
24 | echo "`date`: Params: $*" | ||
25 | |||
26 | if test x"$1" != x"config"; then | ||
27 | # Reconfigure network with this interface disabled | ||
28 | echo "Deconfiguring" | ||
29 | rm "$file_ipconf" | ||
30 | rm "$dir_ipconf/$file_ipconf" | ||
31 | sv u /var/service/fw | ||
32 | exit | ||
33 | fi | ||
34 | |||
35 | # "config": we've got the address | ||
36 | # Record information for e.g. dhcp_$IF_pinger service | ||
37 | env >"env.out" | ||
38 | |||
39 | ./convert2ipconf "$file_ipconf" | ||
40 | # Reconfigure routing and firewall if needed | ||
41 | diff --brief "$file_ipconf" "$dir_ipconf/$file_ipconf" >/dev/null 2>&1 | ||
42 | if test $? != 0; then | ||
43 | echo "Reconfiguring fw" | ||
44 | mkdir -p "$dir_ipconf" 2>/dev/null | ||
45 | cp "$file_ipconf" "$dir_ipconf/$file_ipconf" | ||
46 | sv u /var/service/fw | ||
47 | fi | ||
diff --git a/findutils/xargs.c b/findutils/xargs.c index dba74ea61..8b7ab7b6a 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -590,6 +590,9 @@ int xargs_main(int argc, char **argv) | |||
590 | G.argv = argv; | 590 | G.argv = argv; |
591 | argc = 0; | 591 | argc = 0; |
592 | read_args = process_stdin_with_replace; | 592 | read_args = process_stdin_with_replace; |
593 | /* Make -I imply -r. GNU findutils seems to do the same: */ | ||
594 | /* (otherwise "echo -n | xargs -I% echo %" would SEGV) */ | ||
595 | opt |= OPT_NO_EMPTY; | ||
593 | } else | 596 | } else |
594 | #endif | 597 | #endif |
595 | { | 598 | { |
diff --git a/include/applets.src.h b/include/applets.src.h index 5b597202e..6e1b02fc3 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
@@ -192,8 +192,6 @@ IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killal | |||
192 | IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) | 192 | IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) |
193 | //IF_LENGTH(APPLET_NOFORK(length, length, BB_DIR_USR_BIN, BB_SUID_DROP, length)) | 193 | //IF_LENGTH(APPLET_NOFORK(length, length, BB_DIR_USR_BIN, BB_SUID_DROP, length)) |
194 | IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) | 194 | IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) |
195 | IF_SETARCH(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) | ||
196 | IF_SETARCH(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) | ||
197 | IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) | 195 | IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) |
198 | IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 196 | IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
199 | IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 197 | IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
@@ -274,7 +272,6 @@ IF_SELINUXENABLED(APPLET(selinuxenabled, BB_DIR_USR_SBIN, BB_SUID_DROP)) | |||
274 | IF_SENDMAIL(APPLET(sendmail, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 272 | IF_SENDMAIL(APPLET(sendmail, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
275 | IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) | 273 | IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) |
276 | IF_SESTATUS(APPLET(sestatus, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 274 | IF_SESTATUS(APPLET(sestatus, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
277 | IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) | ||
278 | IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) | 275 | IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) |
279 | IF_SETENFORCE(APPLET(setenforce, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 276 | IF_SETENFORCE(APPLET(setenforce, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
280 | IF_SETFILES(APPLET(setfiles, BB_DIR_SBIN, BB_SUID_DROP)) | 277 | IF_SETFILES(APPLET(setfiles, BB_DIR_SBIN, BB_SUID_DROP)) |
diff --git a/include/bb_archive.h b/include/bb_archive.h index e2c8aede4..03f174839 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -87,6 +87,9 @@ typedef struct archive_handle_t { | |||
87 | off_t offset; | 87 | off_t offset; |
88 | 88 | ||
89 | /* Archiver specific. Can make it a union if it ever gets big */ | 89 | /* Archiver specific. Can make it a union if it ever gets big */ |
90 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
91 | unsigned tar__strip_components; | ||
92 | #endif | ||
90 | #define PAX_NEXT_FILE 0 | 93 | #define PAX_NEXT_FILE 0 |
91 | #define PAX_GLOBAL 1 | 94 | #define PAX_GLOBAL 1 |
92 | #if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB | 95 | #if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB |
diff --git a/include/libbb.h b/include/libbb.h index de00abe7f..7959884e3 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1347,11 +1347,6 @@ extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC; | |||
1347 | extern void selinux_or_die(void) FAST_FUNC; | 1347 | extern void selinux_or_die(void) FAST_FUNC; |
1348 | 1348 | ||
1349 | 1349 | ||
1350 | /* systemd support */ | ||
1351 | #define SD_LISTEN_FDS_START 3 | ||
1352 | int sd_listen_fds(void); | ||
1353 | |||
1354 | |||
1355 | /* setup_environment: | 1350 | /* setup_environment: |
1356 | * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die | 1351 | * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die |
1357 | * if clear_env = 1: cd(pw->pw_dir), clear environment, then set | 1352 | * if clear_env = 1: cd(pw->pw_dir), clear environment, then set |
@@ -1418,6 +1413,7 @@ extern void print_login_prompt(void) FAST_FUNC; | |||
1418 | char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC; | 1413 | char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC; |
1419 | /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ | 1414 | /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ |
1420 | int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC; | 1415 | int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC; |
1416 | int get_terminal_width(int fd) FAST_FUNC; | ||
1421 | 1417 | ||
1422 | int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; | 1418 | int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; |
1423 | 1419 | ||
diff --git a/libbb/Config.src b/libbb/Config.src index 19021fed1..6ba256290 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -16,7 +16,7 @@ config PASSWORD_MINLEN | |||
16 | 16 | ||
17 | config MD5_SMALL | 17 | config MD5_SMALL |
18 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" | 18 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" |
19 | default 1 | 19 | default 1 # all "fast or small" options default to small |
20 | range 0 3 | 20 | range 0 3 |
21 | help | 21 | help |
22 | Trade binary size versus speed for the md5sum algorithm. | 22 | Trade binary size versus speed for the md5sum algorithm. |
@@ -30,7 +30,7 @@ config MD5_SMALL | |||
30 | 30 | ||
31 | config SHA3_SMALL | 31 | config SHA3_SMALL |
32 | int "SHA3: Trade bytes for speed (0:fast, 1:slow)" | 32 | int "SHA3: Trade bytes for speed (0:fast, 1:slow)" |
33 | default 1 | 33 | default 1 # all "fast or small" options default to small |
34 | range 0 1 | 34 | range 0 1 |
35 | help | 35 | help |
36 | Trade binary size versus speed for the sha3sum algorithm. | 36 | Trade binary size versus speed for the sha3sum algorithm. |
@@ -40,7 +40,7 @@ config SHA3_SMALL | |||
40 | 40 | ||
41 | config FEATURE_FAST_TOP | 41 | config FEATURE_FAST_TOP |
42 | bool "Faster /proc scanning code (+100 bytes)" | 42 | bool "Faster /proc scanning code (+100 bytes)" |
43 | default y | 43 | default n # all "fast or small" options default to small |
44 | help | 44 | help |
45 | This option makes top (and ps) ~20% faster (or 20% less CPU hungry), | 45 | This option makes top (and ps) ~20% faster (or 20% less CPU hungry), |
46 | but code size is slightly bigger. | 46 | but code size is slightly bigger. |
@@ -114,7 +114,7 @@ config FEATURE_EDITING_SAVE_ON_EXIT | |||
114 | config FEATURE_REVERSE_SEARCH | 114 | config FEATURE_REVERSE_SEARCH |
115 | bool "Reverse history search" | 115 | bool "Reverse history search" |
116 | default y | 116 | default y |
117 | depends on FEATURE_EDITING_SAVEHISTORY | 117 | depends on FEATURE_EDITING |
118 | help | 118 | help |
119 | Enable readline-like Ctrl-R combination for reverse history search. | 119 | Enable readline-like Ctrl-R combination for reverse history search. |
120 | Increases code by about 0.5k. | 120 | Increases code by about 0.5k. |
@@ -208,7 +208,7 @@ config FEATURE_SKIP_ROOTFS | |||
208 | 208 | ||
209 | config MONOTONIC_SYSCALL | 209 | config MONOTONIC_SYSCALL |
210 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" | 210 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" |
211 | default n | 211 | default y |
212 | select PLATFORM_LINUX | 212 | select PLATFORM_LINUX |
213 | help | 213 | help |
214 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring | 214 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 7da7cad1c..1d6a4b274 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -628,7 +628,7 @@ static int busybox_main(char **argv) | |||
628 | output_width = 80; | 628 | output_width = 80; |
629 | if (ENABLE_FEATURE_AUTOWIDTH) { | 629 | if (ENABLE_FEATURE_AUTOWIDTH) { |
630 | /* Obtain the terminal width */ | 630 | /* Obtain the terminal width */ |
631 | get_terminal_width_height(0, &output_width, NULL); | 631 | output_width = get_terminal_width(2); |
632 | } | 632 | } |
633 | 633 | ||
634 | dup2(1, 2); | 634 | dup2(1, 2); |
@@ -659,10 +659,10 @@ static int busybox_main(char **argv) | |||
659 | ) | 659 | ) |
660 | IF_FEATURE_SH_STANDALONE( | 660 | IF_FEATURE_SH_STANDALONE( |
661 | "\tBusyBox is a multi-call binary that combines many common Unix\n" | 661 | "\tBusyBox is a multi-call binary that combines many common Unix\n" |
662 | "\tutilities into a single executable. The shell in this version\n" | 662 | "\tutilities into a single executable. The shell in this build\n" |
663 | "\thas been configured to prefer built-in utilities to external\n" | 663 | "\tis configured to run built-in utilities without $PATH search.\n" |
664 | "\tbinaries. This avoids having to install a link to busybox for\n" | 664 | "\tYou don't need to install a link to busybox for each utility.\n" |
665 | "\teach function to be invoked.\n" | 665 | "\tTo run external program, use full path (/sbin/ip instead of ip).\n" |
666 | ) | 666 | ) |
667 | "\n" | 667 | "\n" |
668 | #if ENABLE_GLOBBING | 668 | #if ENABLE_GLOBBING |
diff --git a/libbb/kernel_version.c b/libbb/kernel_version.c index 738ed022b..9b6c62299 100644 --- a/libbb/kernel_version.c +++ b/libbb/kernel_version.c | |||
@@ -20,16 +20,16 @@ | |||
20 | int FAST_FUNC get_linux_version_code(void) | 20 | int FAST_FUNC get_linux_version_code(void) |
21 | { | 21 | { |
22 | struct utsname name; | 22 | struct utsname name; |
23 | char *s, *t; | 23 | char *t; |
24 | int i, r; | 24 | int i, r; |
25 | 25 | ||
26 | uname(&name); /* never fails */ | 26 | uname(&name); /* never fails */ |
27 | s = name.release; | 27 | t = name.release; |
28 | r = 0; | 28 | r = 0; |
29 | for (i = 0; i < 3; i++) { | 29 | for (i = 0; i < 3; i++) { |
30 | t = strtok(s, "."); | 30 | t = strtok(t, "."); |
31 | r = r * 256 + (t ? atoi(t) : 0); | 31 | r = r * 256 + (t ? atoi(t) : 0); |
32 | s = NULL; | 32 | t = NULL; |
33 | } | 33 | } |
34 | return r; | 34 | return r; |
35 | } | 35 | } |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5cb40a508..04361b509 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -829,10 +829,12 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
829 | if (type == FIND_EXE_ONLY) { | 829 | if (type == FIND_EXE_ONLY) { |
830 | const char *p = applet_names; | 830 | const char *p = applet_names; |
831 | 831 | ||
832 | for (i=0; i < NUM_APPLETS; i++) { | 832 | i = 0; |
833 | while (i < NUM_APPLETS) { | ||
833 | if (strncmp(pfind, p, pf_len) == 0) | 834 | if (strncmp(pfind, p, pf_len) == 0) |
834 | add_match(xstrdup(p)); | 835 | add_match(xstrdup(p)); |
835 | p += strlen(p) + 1; | 836 | p += strlen(p) + 1; |
837 | i++; | ||
836 | } | 838 | } |
837 | } | 839 | } |
838 | #endif | 840 | #endif |
diff --git a/libbb/procps.c b/libbb/procps.c index 5a4ea59d0..452b50b82 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -589,12 +589,14 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | |||
589 | buf[sz] = ' '; | 589 | buf[sz] = ' '; |
590 | sz--; | 590 | sz--; |
591 | } | 591 | } |
592 | if (base[0] == '-') /* "-sh" (login shell)? */ | ||
593 | base++; | ||
592 | 594 | ||
593 | /* If comm differs from argv0, prepend "{comm} ". | 595 | /* If comm differs from argv0, prepend "{comm} ". |
594 | * It allows to see thread names set by prctl(PR_SET_NAME). | 596 | * It allows to see thread names set by prctl(PR_SET_NAME). |
595 | */ | 597 | */ |
596 | if (base[0] == '-') /* "-sh" (login shell)? */ | 598 | if (!comm) |
597 | base++; | 599 | return; |
598 | comm_len = strlen(comm); | 600 | comm_len = strlen(comm); |
599 | /* Why compare up to comm_len, not COMM_LEN-1? | 601 | /* Why compare up to comm_len, not COMM_LEN-1? |
600 | * Well, some processes rewrite argv, and use _spaces_ there | 602 | * Well, some processes rewrite argv, and use _spaces_ there |
@@ -613,7 +615,7 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | |||
613 | buf[col - 1] = '\0'; | 615 | buf[col - 1] = '\0'; |
614 | } | 616 | } |
615 | } else { | 617 | } else { |
616 | snprintf(buf, col, "[%s]", comm); | 618 | snprintf(buf, col, "[%s]", comm ? comm : "?"); |
617 | } | 619 | } |
618 | } | 620 | } |
619 | 621 | ||
diff --git a/libbb/progress.c b/libbb/progress.c index 372feb0c2..3c2f01667 100644 --- a/libbb/progress.c +++ b/libbb/progress.c | |||
@@ -45,13 +45,6 @@ enum { | |||
45 | STALLTIME = 5 | 45 | STALLTIME = 5 |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static unsigned int get_tty2_width(void) | ||
49 | { | ||
50 | unsigned width; | ||
51 | get_terminal_width_height(2, &width, NULL); | ||
52 | return width; | ||
53 | } | ||
54 | |||
55 | void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile) | 48 | void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile) |
56 | { | 49 | { |
57 | #if ENABLE_UNICODE_SUPPORT | 50 | #if ENABLE_UNICODE_SUPPORT |
@@ -80,7 +73,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
80 | { | 73 | { |
81 | uoff_t beg_and_transferred; | 74 | uoff_t beg_and_transferred; |
82 | unsigned since_last_update, elapsed; | 75 | unsigned since_last_update, elapsed; |
83 | int barlength; | 76 | int notty; |
84 | int kiloscale; | 77 | int kiloscale; |
85 | 78 | ||
86 | //transferred = 1234; /* use for stall detection testing */ | 79 | //transferred = 1234; /* use for stall detection testing */ |
@@ -137,18 +130,21 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
137 | } | 130 | } |
138 | } | 131 | } |
139 | 132 | ||
133 | notty = !isatty(STDERR_FILENO); | ||
134 | |||
140 | if (ENABLE_UNICODE_SUPPORT) | 135 | if (ENABLE_UNICODE_SUPPORT) |
141 | fprintf(stderr, "\r%s", p->curfile); | 136 | fprintf(stderr, "\r%s" + notty, p->curfile); |
142 | else | 137 | else |
143 | fprintf(stderr, "\r%-20.20s", p->curfile); | 138 | fprintf(stderr, "\r%-20.20s" + notty, p->curfile); |
144 | 139 | ||
145 | beg_and_transferred = beg_size + transferred; | 140 | beg_and_transferred = beg_size + transferred; |
146 | 141 | ||
147 | if (totalsize != 0) { | 142 | if (totalsize != 0) { |
143 | int barlength; | ||
148 | unsigned ratio = 100 * beg_and_transferred / totalsize; | 144 | unsigned ratio = 100 * beg_and_transferred / totalsize; |
149 | fprintf(stderr, "%4u%%", ratio); | 145 | fprintf(stderr, "%4u%%", ratio); |
150 | 146 | ||
151 | barlength = get_tty2_width() - 49; | 147 | barlength = get_terminal_width(2) - 49; |
152 | if (barlength > 0) { | 148 | if (barlength > 0) { |
153 | /* god bless gcc for variable arrays :) */ | 149 | /* god bless gcc for variable arrays :) */ |
154 | char buf[barlength + 1]; | 150 | char buf[barlength + 1]; |
@@ -204,4 +200,6 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
204 | hours = eta / 3600; | 200 | hours = eta / 3600; |
205 | fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60); | 201 | fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60); |
206 | } | 202 | } |
203 | if (notty) | ||
204 | fputc('\n', stderr); | ||
207 | } | 205 | } |
diff --git a/libbb/systemd_support.c b/libbb/systemd_support.c deleted file mode 100644 index 542a3efff..000000000 --- a/libbb/systemd_support.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Davide Cavalca <davide@geexbox.org> | ||
3 | * | ||
4 | * Based on http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c | ||
5 | * Copyright 2010 Lennart Poettering | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person | ||
8 | * obtaining a copy of this software and associated documentation files | ||
9 | * (the "Software"), to deal in the Software without restriction, | ||
10 | * including without limitation the rights to use, copy, modify, merge, | ||
11 | * publish, distribute, sublicense, and/or sell copies of the Software, | ||
12 | * and to permit persons to whom the Software is furnished to do so, | ||
13 | * subject to the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice shall be | ||
16 | * included in all copies or substantial portions of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
22 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
23 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
25 | * SOFTWARE. | ||
26 | */ | ||
27 | #include "libbb.h" | ||
28 | |||
29 | //config:config FEATURE_SYSTEMD | ||
30 | //config: bool "Enable systemd support" | ||
31 | //config: default y | ||
32 | //config: help | ||
33 | //config: If you plan to use busybox daemons on a system where daemons | ||
34 | //config: are controlled by systemd, enable this option. | ||
35 | //config: If you don't use systemd, it is still safe to enable it, | ||
36 | //config: but the downside is increased code size. | ||
37 | |||
38 | //kbuild:lib-$(CONFIG_FEATURE_SYSTEMD) += systemd_support.o | ||
39 | |||
40 | int sd_listen_fds(void) | ||
41 | { | ||
42 | const char *e; | ||
43 | int n; | ||
44 | int fd; | ||
45 | |||
46 | e = getenv("LISTEN_PID"); | ||
47 | if (!e) | ||
48 | return 0; | ||
49 | n = xatoi_positive(e); | ||
50 | /* Is this for us? */ | ||
51 | if (getpid() != (pid_t) n) | ||
52 | return 0; | ||
53 | |||
54 | e = getenv("LISTEN_FDS"); | ||
55 | if (!e) | ||
56 | return 0; | ||
57 | n = xatoi_positive(e); | ||
58 | for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) | ||
59 | close_on_exec_on(fd); | ||
60 | |||
61 | return n; | ||
62 | } | ||
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 0c9969640..206edb4a0 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -270,6 +270,12 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh | |||
270 | *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); | 270 | *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); |
271 | return err; | 271 | return err; |
272 | } | 272 | } |
273 | int FAST_FUNC get_terminal_width(int fd) | ||
274 | { | ||
275 | unsigned width; | ||
276 | get_terminal_width_height(fd, &width, NULL); | ||
277 | return width; | ||
278 | } | ||
273 | 279 | ||
274 | int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) | 280 | int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) |
275 | { | 281 | { |
diff --git a/loginutils/login.c b/loginutils/login.c index f1f04da19..67fe82e86 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -58,7 +58,7 @@ | |||
58 | //usage:#define login_full_usage "\n\n" | 58 | //usage:#define login_full_usage "\n\n" |
59 | //usage: "Begin a new session on the system\n" | 59 | //usage: "Begin a new session on the system\n" |
60 | //usage: "\n -f Don't authenticate (user already authenticated)" | 60 | //usage: "\n -f Don't authenticate (user already authenticated)" |
61 | //usage: "\n -h Name of the remote host" | 61 | //usage: "\n -h HOST Host user came from (for network logins)" |
62 | //usage: "\n -p Preserve environment" | 62 | //usage: "\n -p Preserve environment" |
63 | 63 | ||
64 | #include "libbb.h" | 64 | #include "libbb.h" |
diff --git a/miscutils/Config.src b/miscutils/Config.src index d69abf1a2..06f1c52ba 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src | |||
@@ -308,23 +308,13 @@ config LAST | |||
308 | help | 308 | help |
309 | 'last' displays a list of the last users that logged into the system. | 309 | 'last' displays a list of the last users that logged into the system. |
310 | 310 | ||
311 | choice | ||
312 | prompt "Choose last implementation" | ||
313 | depends on LAST | ||
314 | default FEATURE_LAST_FANCY | ||
315 | |||
316 | config FEATURE_LAST_SMALL | ||
317 | bool "small" | ||
318 | help | ||
319 | This is a small version of last with just the basic set of | ||
320 | features. | ||
321 | |||
322 | config FEATURE_LAST_FANCY | 311 | config FEATURE_LAST_FANCY |
323 | bool "huge" | 312 | bool "Turn on output of extra information" |
313 | default y | ||
314 | depends on LAST | ||
324 | help | 315 | help |
325 | 'last' displays detailed information about the last users that | 316 | 'last' displays detailed information about the last users that |
326 | logged into the system (mimics sysvinit last). +900 bytes. | 317 | logged into the system (mimics sysvinit last). +900 bytes. |
327 | endchoice | ||
328 | 318 | ||
329 | config HDPARM | 319 | config HDPARM |
330 | bool "hdparm" | 320 | bool "hdparm" |
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 77033c258..9557c41db 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c | |||
@@ -150,7 +150,7 @@ static void fb_open(const char *strfb_device) | |||
150 | 150 | ||
151 | // map the device in memory | 151 | // map the device in memory |
152 | G.addr = mmap(NULL, | 152 | G.addr = mmap(NULL, |
153 | G.scr_var.yres * G.scr_fix.line_length, | 153 | (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length, |
154 | PROT_WRITE, MAP_SHARED, fbfd, 0); | 154 | PROT_WRITE, MAP_SHARED, fbfd, 0); |
155 | if (G.addr == MAP_FAILED) | 155 | if (G.addr == MAP_FAILED) |
156 | bb_perror_msg_and_die("mmap"); | 156 | bb_perror_msg_and_die("mmap"); |
diff --git a/modutils/Config.src b/modutils/Config.src index 449ac65af..0b11832bc 100644 --- a/modutils/Config.src +++ b/modutils/Config.src | |||
@@ -38,9 +38,6 @@ config MODPROBE_SMALL | |||
38 | - rmmod is an alias to modprobe -r | 38 | - rmmod is an alias to modprobe -r |
39 | - depmod generates modules.dep.bb | 39 | - depmod generates modules.dep.bb |
40 | 40 | ||
41 | As of 2008-07, this code is experimental. It is 14kb smaller | ||
42 | than "non-small" modutils. | ||
43 | |||
44 | config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 41 | config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
45 | bool "Accept module options on modprobe command line" | 42 | bool "Accept module options on modprobe command line" |
46 | default y | 43 | default y |
diff --git a/modutils/modinfo.c b/modutils/modinfo.c index 8e74b6438..aa641ad54 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c | |||
@@ -5,11 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
7 | */ | 7 | */ |
8 | |||
9 | //applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP)) | ||
10 | |||
11 | //kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o | ||
12 | |||
13 | //config:config MODINFO | 8 | //config:config MODINFO |
14 | //config: bool "modinfo" | 9 | //config: bool "modinfo" |
15 | //config: default y | 10 | //config: default y |
@@ -17,26 +12,46 @@ | |||
17 | //config: help | 12 | //config: help |
18 | //config: Show information about a Linux Kernel module | 13 | //config: Show information about a Linux Kernel module |
19 | 14 | ||
15 | //applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP)) | ||
16 | |||
17 | //kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o | ||
18 | |||
20 | #include <fnmatch.h> | 19 | #include <fnmatch.h> |
21 | #include <sys/utsname.h> /* uname() */ | 20 | #include <sys/utsname.h> /* uname() */ |
22 | #include "libbb.h" | 21 | #include "libbb.h" |
23 | #include "modutils.h" | 22 | #include "modutils.h" |
24 | 23 | ||
25 | 24 | static const char *const shortcuts[] = { | |
26 | enum { | 25 | "filename", // -n |
27 | OPT_TAGS = (1 << 12) - 1, /* shortcut count */ | 26 | "author", // -a |
28 | OPT_F = (1 << 12), /* field name */ | 27 | "description", // -d |
29 | OPT_0 = (1 << 13), /* \0 as separator */ | 28 | "license", // -l |
29 | "parm", // -p | ||
30 | "version", // the rest has no shortcut options | ||
31 | "alias", | ||
32 | "srcversion", | ||
33 | "depends", | ||
34 | "uts_release", | ||
35 | "intree", | ||
36 | "vermagic", | ||
37 | "firmware", | ||
30 | }; | 38 | }; |
31 | 39 | ||
32 | struct modinfo_env { | 40 | enum { |
33 | char *field; | 41 | OPT_0 = (1 << 0), /* \0 as separator */ |
34 | int tags; | 42 | OPT_F = (1 << 1), /* field name */ |
43 | /* first bits are for -nadlp options, the rest are for | ||
44 | * fields not selectable with "shortcut" options | ||
45 | */ | ||
46 | OPT_n = (1 << 2), | ||
47 | OPT_TAGS = ((1 << ARRAY_SIZE(shortcuts)) - 1) << 2, | ||
35 | }; | 48 | }; |
36 | 49 | ||
37 | static void display(const char *data, const char *pattern, int flag) | 50 | static void display(const char *data, const char *pattern) |
38 | { | 51 | { |
39 | if (flag) { | 52 | int flag = option_mask32 >> 1; /* shift out -0 bit */ |
53 | if (flag & (flag-1)) { | ||
54 | /* more than one field to show: print "FIELD:" pfx */ | ||
40 | int n = printf("%s:", pattern); | 55 | int n = printf("%s:", pattern); |
41 | while (n++ < 16) | 56 | while (n++ < 16) |
42 | bb_putchar(' '); | 57 | bb_putchar(' '); |
@@ -45,55 +60,45 @@ static void display(const char *data, const char *pattern, int flag) | |||
45 | } | 60 | } |
46 | 61 | ||
47 | static void modinfo(const char *path, const char *version, | 62 | static void modinfo(const char *path, const char *version, |
48 | const struct modinfo_env *env) | 63 | const char *field) |
49 | { | 64 | { |
50 | static const char *const shortcuts[] = { | ||
51 | "filename", | ||
52 | "license", | ||
53 | "author", | ||
54 | "description", | ||
55 | "version", | ||
56 | "alias", | ||
57 | "srcversion", | ||
58 | "depends", | ||
59 | "uts_release", | ||
60 | "vermagic", | ||
61 | "parm", | ||
62 | "firmware", | ||
63 | }; | ||
64 | size_t len; | 65 | size_t len; |
65 | int j; | 66 | int j; |
66 | char *ptr, *the_module; | 67 | char *ptr, *the_module; |
67 | const char *field = env->field; | 68 | char *allocated; |
68 | int tags = env->tags; | 69 | int tags = option_mask32; |
69 | |||
70 | if (tags & 1) { /* filename */ | ||
71 | display(path, shortcuts[0], 1 != tags); | ||
72 | } | ||
73 | 70 | ||
71 | allocated = NULL; | ||
74 | len = MAXINT(ssize_t); | 72 | len = MAXINT(ssize_t); |
75 | the_module = xmalloc_open_zipped_read_close(path, &len); | 73 | the_module = xmalloc_open_zipped_read_close(path, &len); |
76 | if (!the_module) { | 74 | if (!the_module) { |
77 | if (path[0] == '/') | 75 | if (path[0] == '/') |
78 | return; | 76 | return; |
79 | /* Newer depmod puts relative paths in modules.dep */ | 77 | /* Newer depmod puts relative paths in modules.dep */ |
80 | path = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path); | 78 | path = allocated = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path); |
81 | the_module = xmalloc_open_zipped_read_close(path, &len); | 79 | the_module = xmalloc_open_zipped_read_close(path, &len); |
82 | free((char*)path); | 80 | if (!the_module) { |
83 | if (!the_module) | 81 | bb_error_msg("module '%s' not found", path); |
84 | return; | 82 | goto ret; |
83 | } | ||
85 | } | 84 | } |
86 | 85 | ||
87 | if (field) | 86 | for (j = 1; (1<<j) & (OPT_TAGS|OPT_F); j++) { |
88 | tags |= OPT_F; | ||
89 | for (j = 1; (1<<j) & (OPT_TAGS + OPT_F); j++) { | ||
90 | const char *pattern; | 87 | const char *pattern; |
91 | 88 | ||
92 | if (!((1<<j) & tags)) | 89 | if (!((1<<j) & tags)) |
93 | continue; | 90 | continue; |
91 | |||
94 | pattern = field; | 92 | pattern = field; |
95 | if ((1<<j) & OPT_TAGS) | 93 | if ((1<<j) & OPT_TAGS) |
96 | pattern = shortcuts[j]; | 94 | pattern = shortcuts[j-2]; |
95 | |||
96 | if (strcmp(pattern, shortcuts[0]) == 0) { | ||
97 | /* "-n" or "-F filename" */ | ||
98 | display(path, shortcuts[0]); | ||
99 | continue; | ||
100 | } | ||
101 | |||
97 | ptr = the_module; | 102 | ptr = the_module; |
98 | while (1) { | 103 | while (1) { |
99 | char *after_pattern; | 104 | char *after_pattern; |
@@ -106,7 +111,7 @@ static void modinfo(const char *path, const char *version, | |||
106 | /* field prefixes are 0x80 or 0x00 */ | 111 | /* field prefixes are 0x80 or 0x00 */ |
107 | if ((ptr[-1] & 0x7F) == 0x00) { | 112 | if ((ptr[-1] & 0x7F) == 0x00) { |
108 | ptr = after_pattern + 1; | 113 | ptr = after_pattern + 1; |
109 | display(ptr, pattern, (1<<j) != tags); | 114 | display(ptr, pattern); |
110 | ptr += strlen(ptr); | 115 | ptr += strlen(ptr); |
111 | } | 116 | } |
112 | } | 117 | } |
@@ -114,15 +119,18 @@ static void modinfo(const char *path, const char *version, | |||
114 | } | 119 | } |
115 | } | 120 | } |
116 | free(the_module); | 121 | free(the_module); |
122 | ret: | ||
123 | free(allocated); | ||
117 | } | 124 | } |
118 | 125 | ||
119 | //usage:#define modinfo_trivial_usage | 126 | //usage:#define modinfo_trivial_usage |
120 | //usage: "[-adlp0] [-F keyword] MODULE" | 127 | //usage: "[-adlpn0] [-F keyword] MODULE" |
121 | //usage:#define modinfo_full_usage "\n\n" | 128 | //usage:#define modinfo_full_usage "\n\n" |
122 | //usage: " -a Shortcut for '-F author'" | 129 | //usage: " -a Shortcut for '-F author'" |
123 | //usage: "\n -d Shortcut for '-F description'" | 130 | //usage: "\n -d Shortcut for '-F description'" |
124 | //usage: "\n -l Shortcut for '-F license'" | 131 | //usage: "\n -l Shortcut for '-F license'" |
125 | //usage: "\n -p Shortcut for '-F parm'" | 132 | //usage: "\n -p Shortcut for '-F parm'" |
133 | ////usage: "\n -n Shortcut for '-F filename'" | ||
126 | //usage: "\n -F keyword Keyword to look for" | 134 | //usage: "\n -F keyword Keyword to look for" |
127 | //usage: "\n -0 Separate output with NULs" | 135 | //usage: "\n -0 Separate output with NULs" |
128 | //usage:#define modinfo_example_usage | 136 | //usage:#define modinfo_example_usage |
@@ -131,7 +139,7 @@ static void modinfo(const char *path, const char *version, | |||
131 | int modinfo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 139 | int modinfo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
132 | int modinfo_main(int argc UNUSED_PARAM, char **argv) | 140 | int modinfo_main(int argc UNUSED_PARAM, char **argv) |
133 | { | 141 | { |
134 | struct modinfo_env env; | 142 | const char *field; |
135 | char name[MODULE_NAME_LEN]; | 143 | char name[MODULE_NAME_LEN]; |
136 | struct utsname uts; | 144 | struct utsname uts; |
137 | parser_t *parser; | 145 | parser_t *parser; |
@@ -139,10 +147,12 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv) | |||
139 | unsigned opts; | 147 | unsigned opts; |
140 | unsigned i; | 148 | unsigned i; |
141 | 149 | ||
142 | env.field = NULL; | 150 | field = NULL; |
143 | opt_complementary = "-1"; /* minimum one param */ | 151 | opt_complementary = "-1"; /* minimum one param */ |
144 | opts = getopt32(argv, "nladvAsDumpF:0", &env.field); | 152 | opts = getopt32(argv, "0F:nadlp", &field); |
145 | env.tags = opts & OPT_TAGS ? opts & OPT_TAGS : OPT_TAGS; | 153 | /* If no field selected, show all */ |
154 | if (!(opts & (OPT_TAGS|OPT_F))) | ||
155 | option_mask32 |= OPT_TAGS; | ||
146 | argv += optind; | 156 | argv += optind; |
147 | 157 | ||
148 | uname(&uts); | 158 | uname(&uts); |
@@ -159,7 +169,7 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv) | |||
159 | filename2modname(bb_basename(tokens[0]), name); | 169 | filename2modname(bb_basename(tokens[0]), name); |
160 | for (i = 0; argv[i]; i++) { | 170 | for (i = 0; argv[i]; i++) { |
161 | if (fnmatch(argv[i], name, 0) == 0) { | 171 | if (fnmatch(argv[i], name, 0) == 0) { |
162 | modinfo(tokens[0], uts.release, &env); | 172 | modinfo(tokens[0], uts.release, field); |
163 | argv[i] = (char *) ""; | 173 | argv[i] = (char *) ""; |
164 | } | 174 | } |
165 | } | 175 | } |
@@ -169,7 +179,7 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv) | |||
169 | 179 | ||
170 | for (i = 0; argv[i]; i++) { | 180 | for (i = 0; argv[i]; i++) { |
171 | if (argv[i][0]) { | 181 | if (argv[i][0]) { |
172 | modinfo(argv[i], uts.release, &env); | 182 | modinfo(argv[i], uts.release, field); |
173 | } | 183 | } |
174 | } | 184 | } |
175 | 185 | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 314a7a1cb..05bf02cf8 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -461,9 +461,8 @@ static int do_modprobe(struct module_entry *m) | |||
461 | rc = bb_delete_module(m2->modname, O_EXCL); | 461 | rc = bb_delete_module(m2->modname, O_EXCL); |
462 | if (rc) { | 462 | if (rc) { |
463 | if (first) { | 463 | if (first) { |
464 | bb_error_msg("can't unload module %s: %s", | 464 | bb_perror_msg("can't unload module '%s'", |
465 | humanly_readable_name(m2), | 465 | humanly_readable_name(m2)); |
466 | moderror(rc)); | ||
467 | break; | 466 | break; |
468 | } | 467 | } |
469 | } else { | 468 | } else { |
@@ -622,7 +621,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
622 | * autoclean will be removed". | 621 | * autoclean will be removed". |
623 | */ | 622 | */ |
624 | if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0) | 623 | if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0) |
625 | bb_perror_msg_and_die("rmmod"); | 624 | bb_perror_nomsg_and_die(); |
626 | } | 625 | } |
627 | return EXIT_SUCCESS; | 626 | return EXIT_SUCCESS; |
628 | } | 627 | } |
diff --git a/modutils/modutils.c b/modutils/modutils.c index 84300d931..ef4134af5 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c | |||
@@ -190,6 +190,11 @@ int FAST_FUNC bb_delete_module(const char *module, unsigned int flags) | |||
190 | return errno; | 190 | return errno; |
191 | } | 191 | } |
192 | 192 | ||
193 | /* Note: not suitable for delete_module() errnos. | ||
194 | * For them, probably only EWOULDBLOCK needs explaining: | ||
195 | * "Other modules depend on us". So far we don't do such | ||
196 | * translation and don't use moderror() for removal errors. | ||
197 | */ | ||
193 | const char* FAST_FUNC moderror(int err) | 198 | const char* FAST_FUNC moderror(int err) |
194 | { | 199 | { |
195 | switch (err) { | 200 | switch (err) { |
diff --git a/modutils/rmmod.c b/modutils/rmmod.c index f13ff9eb6..5c353ef95 100644 --- a/modutils/rmmod.c +++ b/modutils/rmmod.c | |||
@@ -28,7 +28,7 @@ | |||
28 | int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 28 | int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
29 | int rmmod_main(int argc UNUSED_PARAM, char **argv) | 29 | int rmmod_main(int argc UNUSED_PARAM, char **argv) |
30 | { | 30 | { |
31 | int n; | 31 | int n, err; |
32 | unsigned flags = O_NONBLOCK | O_EXCL; | 32 | unsigned flags = O_NONBLOCK | O_EXCL; |
33 | 33 | ||
34 | /* Parse command line. */ | 34 | /* Parse command line. */ |
@@ -40,7 +40,8 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv) | |||
40 | flags |= O_TRUNC; | 40 | flags |= O_TRUNC; |
41 | if (n & 4) { | 41 | if (n & 4) { |
42 | /* Unload _all_ unused modules via NULL delete_module() call */ | 42 | /* Unload _all_ unused modules via NULL delete_module() call */ |
43 | if (bb_delete_module(NULL, flags) != 0 && errno != EFAULT) | 43 | err = bb_delete_module(NULL, flags); |
44 | if (err && err != EFAULT) | ||
44 | bb_perror_msg_and_die("rmmod"); | 45 | bb_perror_msg_and_die("rmmod"); |
45 | return EXIT_SUCCESS; | 46 | return EXIT_SUCCESS; |
46 | } | 47 | } |
@@ -58,9 +59,10 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv) | |||
58 | safe_strncpy(modname, bname, MODULE_NAME_LEN); | 59 | safe_strncpy(modname, bname, MODULE_NAME_LEN); |
59 | else | 60 | else |
60 | filename2modname(bname, modname); | 61 | filename2modname(bname, modname); |
61 | if (bb_delete_module(modname, flags)) | 62 | err = bb_delete_module(modname, flags); |
62 | bb_error_msg_and_die("can't unload '%s': %s", | 63 | if (err) |
63 | modname, moderror(errno)); | 64 | bb_perror_msg_and_die("can't unload module '%s'", |
65 | modname); | ||
64 | } | 66 | } |
65 | 67 | ||
66 | return EXIT_SUCCESS; | 68 | return EXIT_SUCCESS; |
diff --git a/networking/Config.src b/networking/Config.src index 8c7417f86..27c604a31 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -497,7 +497,7 @@ config FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN | |||
497 | 497 | ||
498 | config FEATURE_INETD_RPC | 498 | config FEATURE_INETD_RPC |
499 | bool "Support RPC services" | 499 | bool "Support RPC services" |
500 | default y | 500 | default n # very rarely used, and needs Sun RPC support in libc |
501 | depends on INETD | 501 | depends on INETD |
502 | select FEATURE_HAVE_RPC | 502 | select FEATURE_HAVE_RPC |
503 | help | 503 | help |
diff --git a/networking/httpd.c b/networking/httpd.c index 00169c36d..ed15fd883 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -967,19 +967,30 @@ static void send_headers(int responseNum) | |||
967 | } | 967 | } |
968 | #endif | 968 | #endif |
969 | if (responseNum == HTTP_MOVED_TEMPORARILY) { | 969 | if (responseNum == HTTP_MOVED_TEMPORARILY) { |
970 | len += sprintf(iobuf + len, "Location: %s/%s%s\r\n", | 970 | /* Responding to "GET /dir" with |
971 | * "HTTP/1.0 302 Found" "Location: /dir/" | ||
972 | * - IOW, asking them to repeat with a slash. | ||
973 | * Here, overflow IS possible, can't use sprintf: | ||
974 | * mkdir test | ||
975 | * python -c 'print("get /test?" + ("x" * 8192))' | busybox httpd -i -h . | ||
976 | */ | ||
977 | len += snprintf(iobuf + len, IOBUF_SIZE-3 - len, | ||
978 | "Location: %s/%s%s\r\n", | ||
971 | found_moved_temporarily, | 979 | found_moved_temporarily, |
972 | (g_query ? "?" : ""), | 980 | (g_query ? "?" : ""), |
973 | (g_query ? g_query : "")); | 981 | (g_query ? g_query : "")); |
982 | if (len > IOBUF_SIZE-3) | ||
983 | len = IOBUF_SIZE-3; | ||
974 | } | 984 | } |
975 | 985 | ||
976 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES | 986 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES |
977 | if (error_page && access(error_page, R_OK) == 0) { | 987 | if (error_page && access(error_page, R_OK) == 0) { |
978 | strcat(iobuf, "\r\n"); | 988 | iobuf[len++] = '\r'; |
979 | len += 2; | 989 | iobuf[len++] = '\n'; |
980 | 990 | if (DEBUG) { | |
981 | if (DEBUG) | 991 | iobuf[len] = '\0'; |
982 | fprintf(stderr, "headers: '%s'\n", iobuf); | 992 | fprintf(stderr, "headers: '%s'\n", iobuf); |
993 | } | ||
983 | full_write(STDOUT_FILENO, iobuf, len); | 994 | full_write(STDOUT_FILENO, iobuf, len); |
984 | if (DEBUG) | 995 | if (DEBUG) |
985 | fprintf(stderr, "writing error page: '%s'\n", error_page); | 996 | fprintf(stderr, "writing error page: '%s'\n", error_page); |
@@ -1021,8 +1032,10 @@ static void send_headers(int responseNum) | |||
1021 | responseNum, responseString, | 1032 | responseNum, responseString, |
1022 | responseNum, responseString, infoString); | 1033 | responseNum, responseString, infoString); |
1023 | } | 1034 | } |
1024 | if (DEBUG) | 1035 | if (DEBUG) { |
1036 | iobuf[len] = '\0'; | ||
1025 | fprintf(stderr, "headers: '%s'\n", iobuf); | 1037 | fprintf(stderr, "headers: '%s'\n", iobuf); |
1038 | } | ||
1026 | if (full_write(STDOUT_FILENO, iobuf, len) != len) { | 1039 | if (full_write(STDOUT_FILENO, iobuf, len) != len) { |
1027 | if (verbose > 1) | 1040 | if (verbose > 1) |
1028 | bb_perror_msg("error"); | 1041 | bb_perror_msg("error"); |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 7c45e8927..d477ff6d1 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -394,8 +394,8 @@ static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) | |||
394 | # if ENABLE_FEATURE_IFUPDOWN_IP | 394 | # if ENABLE_FEATURE_IFUPDOWN_IP |
395 | result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); | 395 | result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); |
396 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); | 396 | result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); |
397 | /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking */ | 397 | /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ |
398 | result += execute("[[ip route add ::/0 via %gateway%]][[ metric %metric%]]", ifd, exec); | 398 | result += execute("[[ip route add ::/0 via %gateway% dev %iface%]][[ metric %metric%]]", ifd, exec); |
399 | # else | 399 | # else |
400 | result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); | 400 | result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); |
401 | result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); | 401 | result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); |
@@ -421,7 +421,8 @@ static int FAST_FUNC v4tunnel_up(struct interface_defn_t *ifd, execfn *exec) | |||
421 | "%endpoint%[[ local %local%]][[ ttl %ttl%]]", ifd, exec); | 421 | "%endpoint%[[ local %local%]][[ ttl %ttl%]]", ifd, exec); |
422 | result += execute("ip link set %iface% up", ifd, exec); | 422 | result += execute("ip link set %iface% up", ifd, exec); |
423 | result += execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec); | 423 | result += execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec); |
424 | result += execute("[[ip route add ::/0 via %gateway%]]", ifd, exec); | 424 | /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ |
425 | result += execute("[[ip route add ::/0 via %gateway% dev %iface%]]", ifd, exec); | ||
425 | return ((result == 4) ? 4 : 0); | 426 | return ((result == 4) ? 4 : 0); |
426 | } | 427 | } |
427 | 428 | ||
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index e2b85fc7b..af9eb46f7 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c | |||
@@ -136,7 +136,6 @@ unsigned FAST_FUNC ll_index_to_flags(int idx) | |||
136 | int FAST_FUNC xll_name_to_index(const char *name) | 136 | int FAST_FUNC xll_name_to_index(const char *name) |
137 | { | 137 | { |
138 | int ret = 0; | 138 | int ret = 0; |
139 | int sock_fd; | ||
140 | 139 | ||
141 | /* caching is not warranted - no users which repeatedly call it */ | 140 | /* caching is not warranted - no users which repeatedly call it */ |
142 | #ifdef UNUSED | 141 | #ifdef UNUSED |
@@ -164,30 +163,8 @@ int FAST_FUNC xll_name_to_index(const char *name) | |||
164 | } | 163 | } |
165 | } | 164 | } |
166 | } | 165 | } |
167 | /* We have not found the interface in our cache, but the kernel | ||
168 | * may still know about it. One reason is that we may be using | ||
169 | * module on-demand loading, which means that the kernel will | ||
170 | * load the module and make the interface exist only when | ||
171 | * we explicitely request it (check for dev_load() in net/core/dev.c). | ||
172 | * I can think of other similar scenario, but they are less common... | ||
173 | * Jean II */ | ||
174 | #endif | 166 | #endif |
175 | 167 | ret = if_nametoindex(name); | |
176 | sock_fd = socket(AF_INET, SOCK_DGRAM, 0); | ||
177 | if (sock_fd >= 0) { | ||
178 | struct ifreq ifr; | ||
179 | int tmp; | ||
180 | |||
181 | strncpy_IFNAMSIZ(ifr.ifr_name, name); | ||
182 | ifr.ifr_ifindex = -1; | ||
183 | tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr); | ||
184 | close(sock_fd); | ||
185 | if (tmp >= 0) | ||
186 | /* In theory, we should redump the interface list | ||
187 | * to update our cache, this is left as an exercise | ||
188 | * to the reader... Jean II */ | ||
189 | ret = ifr.ifr_ifindex; | ||
190 | } | ||
191 | /* out:*/ | 168 | /* out:*/ |
192 | if (ret <= 0) | 169 | if (ret <= 0) |
193 | bb_error_msg_and_die("can't find device '%s'", name); | 170 | bb_error_msg_and_die("can't find device '%s'", name); |
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c index 64cd73ec7..987cc9aff 100644 --- a/networking/udhcp/dumpleases.c +++ b/networking/udhcp/dumpleases.c | |||
@@ -4,18 +4,20 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | //usage:#define dumpleases_trivial_usage | 6 | //usage:#define dumpleases_trivial_usage |
7 | //usage: "[-r|-a] [-f LEASEFILE]" | 7 | //usage: "[-r|-a] [-d] [-f LEASEFILE]" |
8 | //usage:#define dumpleases_full_usage "\n\n" | 8 | //usage:#define dumpleases_full_usage "\n\n" |
9 | //usage: "Display DHCP leases granted by udhcpd\n" | 9 | //usage: "Display DHCP leases granted by udhcpd\n" |
10 | //usage: IF_LONG_OPTS( | 10 | //usage: IF_LONG_OPTS( |
11 | //usage: "\n -f,--file=FILE Lease file" | 11 | //usage: "\n -f,--file=FILE Lease file" |
12 | //usage: "\n -r,--remaining Show remaining time" | 12 | //usage: "\n -r,--remaining Show remaining time" |
13 | //usage: "\n -a,--absolute Show expiration time" | 13 | //usage: "\n -a,--absolute Show expiration time" |
14 | //usage: "\n -d,--decimal Show time in seconds" | ||
14 | //usage: ) | 15 | //usage: ) |
15 | //usage: IF_NOT_LONG_OPTS( | 16 | //usage: IF_NOT_LONG_OPTS( |
16 | //usage: "\n -f FILE Lease file" | 17 | //usage: "\n -f FILE Lease file" |
17 | //usage: "\n -r Show remaining time" | 18 | //usage: "\n -r Show remaining time" |
18 | //usage: "\n -a Show expiration time" | 19 | //usage: "\n -a Show expiration time" |
20 | //usage: "\n -d Show time in seconds" | ||
19 | //usage: ) | 21 | //usage: ) |
20 | 22 | ||
21 | #include "common.h" | 23 | #include "common.h" |
@@ -28,21 +30,22 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) | |||
28 | int fd; | 30 | int fd; |
29 | int i; | 31 | int i; |
30 | unsigned opt; | 32 | unsigned opt; |
31 | int64_t written_at, curr, expires_abs; | 33 | int64_t written_at, curr; |
32 | const char *file = LEASES_FILE; | 34 | const char *file = LEASES_FILE; |
33 | struct dyn_lease lease; | 35 | struct dyn_lease lease; |
34 | struct in_addr addr; | ||
35 | 36 | ||
36 | enum { | 37 | enum { |
37 | OPT_a = 0x1, // -a | 38 | OPT_a = 0x1, // -a |
38 | OPT_r = 0x2, // -r | 39 | OPT_r = 0x2, // -r |
39 | OPT_f = 0x4, // -f | 40 | OPT_f = 0x4, // -f |
41 | OPT_d = 0x8, // -d | ||
40 | }; | 42 | }; |
41 | #if ENABLE_LONG_OPTS | 43 | #if ENABLE_LONG_OPTS |
42 | static const char dumpleases_longopts[] ALIGN1 = | 44 | static const char dumpleases_longopts[] ALIGN1 = |
43 | "absolute\0" No_argument "a" | 45 | "absolute\0" No_argument "a" |
44 | "remaining\0" No_argument "r" | 46 | "remaining\0" No_argument "r" |
45 | "file\0" Required_argument "f" | 47 | "file\0" Required_argument "f" |
48 | "decimal\0" No_argument "d" | ||
46 | ; | 49 | ; |
47 | 50 | ||
48 | applet_long_options = dumpleases_longopts; | 51 | applet_long_options = dumpleases_longopts; |
@@ -50,13 +53,16 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) | |||
50 | init_unicode(); | 53 | init_unicode(); |
51 | 54 | ||
52 | opt_complementary = "=0:a--r:r--a"; | 55 | opt_complementary = "=0:a--r:r--a"; |
53 | opt = getopt32(argv, "arf:", &file); | 56 | opt = getopt32(argv, "arf:d", &file); |
54 | 57 | ||
55 | fd = xopen(file, O_RDONLY); | 58 | fd = xopen(file, O_RDONLY); |
56 | 59 | ||
57 | printf("Mac Address IP Address Host Name Expires %s\n", (opt & OPT_a) ? "at" : "in"); | ||
58 | /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ | ||
59 | /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ | 60 | /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ |
61 | /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ | ||
62 | printf("Mac %-14s" "IP %-13s" "Host %-15s" "Expires %s\n", | ||
63 | "Address", "Address", "Name", | ||
64 | (opt & OPT_a) ? "at" : "in" | ||
65 | ); | ||
60 | 66 | ||
61 | xread(fd, &written_at, sizeof(written_at)); | 67 | xread(fd, &written_at, sizeof(written_at)); |
62 | written_at = SWAP_BE64(written_at); | 68 | written_at = SWAP_BE64(written_at); |
@@ -65,6 +71,9 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) | |||
65 | written_at = curr; /* lease file from future! :) */ | 71 | written_at = curr; /* lease file from future! :) */ |
66 | 72 | ||
67 | while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { | 73 | while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { |
74 | struct in_addr addr; | ||
75 | int64_t expires_abs; | ||
76 | |||
68 | const char *fmt = ":%02x" + 1; | 77 | const char *fmt = ":%02x" + 1; |
69 | for (i = 0; i < 6; i++) { | 78 | for (i = 0; i < 6; i++) { |
70 | printf(fmt, lease.lease_mac[i]); | 79 | printf(fmt, lease.lease_mac[i]); |
@@ -87,6 +96,13 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) | |||
87 | puts("expired"); | 96 | puts("expired"); |
88 | continue; | 97 | continue; |
89 | } | 98 | } |
99 | if (opt & OPT_d) { | ||
100 | /* -d: decimal time */ | ||
101 | if (!(opt & OPT_a)) | ||
102 | expires_abs -= curr; | ||
103 | printf("%llu\n", (unsigned long long) expires_abs); | ||
104 | continue; | ||
105 | } | ||
90 | if (!(opt & OPT_a)) { /* no -a */ | 106 | if (!(opt & OPT_a)) { /* no -a */ |
91 | unsigned d, h, m; | 107 | unsigned d, h, m; |
92 | unsigned expires = expires_abs - curr; | 108 | unsigned expires = expires_abs - curr; |
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 745340ad3..844bb60b1 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c | |||
@@ -65,10 +65,15 @@ struct dyn_lease* FAST_FUNC add_lease( | |||
65 | if (hostname_len > sizeof(oldest->hostname)) | 65 | if (hostname_len > sizeof(oldest->hostname)) |
66 | hostname_len = sizeof(oldest->hostname); | 66 | hostname_len = sizeof(oldest->hostname); |
67 | p = safe_strncpy(oldest->hostname, hostname, hostname_len); | 67 | p = safe_strncpy(oldest->hostname, hostname, hostname_len); |
68 | /* sanitization (s/non-ASCII/^/g) */ | 68 | /* |
69 | * Sanitization (s/bad_char/./g). | ||
70 | * The intent is not to allow only "DNS-valid" hostnames, | ||
71 | * but merely make dumpleases output safe for shells to use. | ||
72 | * We accept "0-9A-Za-z._-", all other chars turn to dots. | ||
73 | */ | ||
69 | while (*p) { | 74 | while (*p) { |
70 | if (*p < ' ' || *p > 126) | 75 | if (!isalnum(*p) && *p != '-' && *p != '_') |
71 | *p = '^'; | 76 | *p = '.'; |
72 | p++; | 77 | p++; |
73 | } | 78 | } |
74 | } | 79 | } |
diff --git a/networking/wget.c b/networking/wget.c index 0082ced39..edf8fd8af 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -102,7 +102,8 @@ | |||
102 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" | 102 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" |
103 | //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" | 103 | //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" |
104 | /* Since we ignore these opts, we don't show them in --help */ | 104 | /* Since we ignore these opts, we don't show them in --help */ |
105 | /* //usage: " [--no-check-certificate] [--no-cache]" */ | 105 | /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ |
106 | /* //usage: " [-nv] [-nc] [-nH] [-np]" */ | ||
106 | //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | 107 | //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." |
107 | //usage: ) | 108 | //usage: ) |
108 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( | 109 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( |
@@ -1225,19 +1226,22 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
1225 | "directory-prefix\0" Required_argument "P" | 1226 | "directory-prefix\0" Required_argument "P" |
1226 | "proxy\0" Required_argument "Y" | 1227 | "proxy\0" Required_argument "Y" |
1227 | "user-agent\0" Required_argument "U" | 1228 | "user-agent\0" Required_argument "U" |
1228 | #if ENABLE_FEATURE_WGET_TIMEOUT | 1229 | IF_FEATURE_WGET_TIMEOUT( |
1229 | "timeout\0" Required_argument "T" | 1230 | "timeout\0" Required_argument "T") |
1230 | #endif | ||
1231 | /* Ignored: */ | 1231 | /* Ignored: */ |
1232 | // "tries\0" Required_argument "t" | 1232 | IF_DESKTOP( "tries\0" Required_argument "t") |
1233 | "header\0" Required_argument "\xff" | ||
1234 | "post-data\0" Required_argument "\xfe" | ||
1233 | /* Ignored (we always use PASV): */ | 1235 | /* Ignored (we always use PASV): */ |
1234 | "passive-ftp\0" No_argument "\xff" | 1236 | IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") |
1235 | "header\0" Required_argument "\xfe" | ||
1236 | "post-data\0" Required_argument "\xfd" | ||
1237 | /* Ignored (we don't do ssl) */ | 1237 | /* Ignored (we don't do ssl) */ |
1238 | "no-check-certificate\0" No_argument "\xfc" | 1238 | IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") |
1239 | /* Ignored (we don't support caching) */ | 1239 | /* Ignored (we don't support caching) */ |
1240 | "no-cache\0" No_argument "\xfb" | 1240 | IF_DESKTOP( "no-cache\0" No_argument "\xf0") |
1241 | IF_DESKTOP( "no-verbose\0" No_argument "\xf0") | ||
1242 | IF_DESKTOP( "no-clobber\0" No_argument "\xf0") | ||
1243 | IF_DESKTOP( "no-host-directories\0" No_argument "\xf0") | ||
1244 | IF_DESKTOP( "no-parent\0" No_argument "\xf0") | ||
1241 | ; | 1245 | ; |
1242 | #endif | 1246 | #endif |
1243 | 1247 | ||
@@ -1257,14 +1261,25 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
1257 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 1261 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
1258 | applet_long_options = wget_longopts; | 1262 | applet_long_options = wget_longopts; |
1259 | #endif | 1263 | #endif |
1260 | opt_complementary = "-1" | 1264 | opt_complementary = "-1" /* at least one URL */ |
1261 | IF_FEATURE_WGET_TIMEOUT(":T+") | 1265 | IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */ |
1262 | IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); | 1266 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ |
1263 | getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", | 1267 | getopt32(argv, "csqO:P:Y:U:T:" |
1264 | &G.fname_out, &G.dir_prefix, | 1268 | /*ignored:*/ "t:" |
1269 | /*ignored:*/ "n::" | ||
1270 | /* wget has exactly four -n<letter> opts, all of which we can ignore: | ||
1271 | * -nv --no-verbose: be moderately quiet (-q is full quiet) | ||
1272 | * -nc --no-clobber: abort if exists, neither download to FILE.n nor overwrite FILE | ||
1273 | * -nH --no-host-directories: wget -r http://host/ won't create host/ | ||
1274 | * -np --no-parent | ||
1275 | * "n::" above says that we accept -n[ARG]. | ||
1276 | * Specifying "n:" would be a bug: "-n ARG" would eat ARG! | ||
1277 | */ | ||
1278 | , &G.fname_out, &G.dir_prefix, | ||
1265 | &G.proxy_flag, &G.user_agent, | 1279 | &G.proxy_flag, &G.user_agent, |
1266 | IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), | 1280 | IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), |
1267 | NULL /* -t RETRIES */ | 1281 | NULL, /* -t RETRIES */ |
1282 | NULL /* -n[ARG] */ | ||
1268 | IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) | 1283 | IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) |
1269 | IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) | 1284 | IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) |
1270 | ); | 1285 | ); |
diff --git a/networking/zcip.c b/networking/zcip.c index d15c67d55..1d6910555 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -345,7 +345,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
345 | state = PROBE; | 345 | state = PROBE; |
346 | while (1) { | 346 | while (1) { |
347 | struct pollfd fds[1]; | 347 | struct pollfd fds[1]; |
348 | unsigned deadline_us; | 348 | unsigned deadline_us = deadline_us; |
349 | struct arp_packet p; | 349 | struct arp_packet p; |
350 | int ip_conflict; | 350 | int ip_conflict; |
351 | int n; | 351 | int n; |
@@ -361,8 +361,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
361 | // make the kernel filter out all packets except | 361 | // make the kernel filter out all packets except |
362 | // ones we'd care about. | 362 | // ones we'd care about. |
363 | } | 363 | } |
364 | // Set deadline_us to the point in time when we timeout | 364 | if (timeout_ms >= 0) { |
365 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; | 365 | // Set deadline_us to the point in time when we timeout |
366 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; | ||
367 | } | ||
366 | 368 | ||
367 | VDBG("...wait %d %s nsent=%u\n", | 369 | VDBG("...wait %d %s nsent=%u\n", |
368 | timeout_ms, argv_intf, nsent); | 370 | timeout_ms, argv_intf, nsent); |
diff --git a/procps/pmap.c b/procps/pmap.c index fd995a54d..aa221cfb8 100644 --- a/procps/pmap.c +++ b/procps/pmap.c | |||
@@ -20,7 +20,7 @@ | |||
20 | //usage:#define pmap_trivial_usage | 20 | //usage:#define pmap_trivial_usage |
21 | //usage: "[-xq] PID" | 21 | //usage: "[-xq] PID" |
22 | //usage:#define pmap_full_usage "\n\n" | 22 | //usage:#define pmap_full_usage "\n\n" |
23 | //usage: "Display detailed process memory usage" | 23 | //usage: "Display process memory usage" |
24 | //usage: "\n" | 24 | //usage: "\n" |
25 | //usage: "\n -x Show details" | 25 | //usage: "\n -x Show details" |
26 | //usage: "\n -q Quiet" | 26 | //usage: "\n -q Quiet" |
@@ -66,7 +66,7 @@ static int procps_get_maps(pid_t pid, unsigned opt) | |||
66 | int ret; | 66 | int ret; |
67 | char buf[256]; | 67 | char buf[256]; |
68 | 68 | ||
69 | read_cmdline(buf, sizeof(buf), pid, "no such process"); | 69 | read_cmdline(buf, sizeof(buf), pid, NULL); |
70 | printf("%u: %s\n", (int)pid, buf); | 70 | printf("%u: %s\n", (int)pid, buf); |
71 | 71 | ||
72 | if (!(opt & OPT_q) && (opt & OPT_x)) | 72 | if (!(opt & OPT_q) && (opt & OPT_x)) |
diff --git a/procps/ps.c b/procps/ps.c index 07ff7568f..8c373376d 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -638,7 +638,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv) | |||
638 | * and such large widths */ | 638 | * and such large widths */ |
639 | terminal_width = MAX_WIDTH; | 639 | terminal_width = MAX_WIDTH; |
640 | if (isatty(1)) { | 640 | if (isatty(1)) { |
641 | get_terminal_width_height(0, &terminal_width, NULL); | 641 | terminal_width = get_terminal_width(0); |
642 | if (--terminal_width > MAX_WIDTH) | 642 | if (--terminal_width > MAX_WIDTH) |
643 | terminal_width = MAX_WIDTH; | 643 | terminal_width = MAX_WIDTH; |
644 | } | 644 | } |
@@ -688,7 +688,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
688 | if (w_count) { | 688 | if (w_count) { |
689 | terminal_width = (w_count == 1) ? 132 : MAX_WIDTH; | 689 | terminal_width = (w_count == 1) ? 132 : MAX_WIDTH; |
690 | } else { | 690 | } else { |
691 | get_terminal_width_height(0, &terminal_width, NULL); | 691 | terminal_width = get_terminal_width(0); |
692 | /* Go one less... */ | 692 | /* Go one less... */ |
693 | if (--terminal_width > MAX_WIDTH) | 693 | if (--terminal_width > MAX_WIDTH) |
694 | terminal_width = MAX_WIDTH; | 694 | terminal_width = MAX_WIDTH; |
diff --git a/procps/pstree.c b/procps/pstree.c index ed1a41289..c5fb83688 100644 --- a/procps/pstree.c +++ b/procps/pstree.c | |||
@@ -381,7 +381,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv) | |||
381 | 381 | ||
382 | INIT_G(); | 382 | INIT_G(); |
383 | 383 | ||
384 | get_terminal_width_height(0, &G.output_width, NULL); | 384 | G.output_width = get_terminal_width(0); |
385 | 385 | ||
386 | opt_complementary = "?1"; | 386 | opt_complementary = "?1"; |
387 | getopt32(argv, "p"); | 387 | getopt32(argv, "p"); |
diff --git a/procps/watch.c b/procps/watch.c index 0397f21bf..97aa04767 100644 --- a/procps/watch.c +++ b/procps/watch.c | |||
@@ -72,7 +72,7 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |||
72 | 72 | ||
73 | // STDERR_FILENO is procps3 compat: | 73 | // STDERR_FILENO is procps3 compat: |
74 | // "watch ls 2>/dev/null" does not detect tty size | 74 | // "watch ls 2>/dev/null" does not detect tty size |
75 | get_terminal_width_height(STDERR_FILENO, &new_width, NULL); | 75 | new_width = get_terminal_width(STDERR_FILENO); |
76 | if (new_width != width) { | 76 | if (new_width != width) { |
77 | width = new_width; | 77 | width = new_width; |
78 | free(header); | 78 | free(header); |
diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README index 9757ff0e4..ecb63f9ef 100644 --- a/qemu_multiarch_testing/README +++ b/qemu_multiarch_testing/README | |||
@@ -11,6 +11,11 @@ hdc.img, from hdc.dir/* data. This requires root for loop mount. | |||
11 | one or more system-image-ARCH directories into this directory | 11 | one or more system-image-ARCH directories into this directory |
12 | (the one which contains this README). | 12 | (the one which contains this README). |
13 | 13 | ||
14 | * Install qemu-system-ARCH. The arch names may differ from | ||
15 | system-image-ARCH: for example, all ARM flavors (armv4l...armv6l) | ||
16 | are served by the same qemu - qemu-system-arm. On my machine, | ||
17 | I needed to install qemu-system-{arm,mips,x86,ppc,sparc,m68k,sh4}. | ||
18 | |||
14 | * Run: ./parallel-build-hdc-img.sh system-image-DIR1 system-image-DIR2... | 19 | * Run: ./parallel-build-hdc-img.sh system-image-DIR1 system-image-DIR2... |
15 | (background it if you don't want to see "Waiting to finish" thing). | 20 | (background it if you don't want to see "Waiting to finish" thing). |
16 | This runs build in several qemu virtual machines in parallel. | 21 | This runs build in several qemu virtual machines in parallel. |
diff --git a/scripts/trylink b/scripts/trylink index 48c487bcd..6e1187ed0 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -47,18 +47,22 @@ try() { | |||
47 | 47 | ||
48 | check_cc() { | 48 | check_cc() { |
49 | local tempname="$(mktemp)" | 49 | local tempname="$(mktemp)" |
50 | local r | ||
51 | echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c | ||
50 | # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( | 52 | # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( |
51 | # "-xc": C language. "/dev/null" is an empty source file. | 53 | # Was using "-xc /dev/null", but we need a valid C program. |
52 | if $CC $CPPFLAGS $CFLAGS $1 -shared -xc /dev/null -o "$tempname".o >/dev/null 2>&1; then | 54 | # "eval" may be needed if CFLAGS can contain |
53 | echo "$1"; | 55 | # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' |
54 | else | 56 | # and we need shell to process quotes! |
55 | echo "$2"; | 57 | $CC $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 |
56 | fi | 58 | r=$? |
57 | rm -f "$tempname" "$tempname".o | 59 | rm -f "$tempname" "$tempname".c "$tempname".o |
60 | return $r | ||
58 | } | 61 | } |
59 | 62 | ||
60 | check_libc_is_glibc() { | 63 | check_libc_is_glibc() { |
61 | local tempname="$(mktemp)" | 64 | local tempname="$(mktemp)" |
65 | local r | ||
62 | echo "\ | 66 | echo "\ |
63 | #include <stdlib.h> | 67 | #include <stdlib.h> |
64 | /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */ | 68 | /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */ |
@@ -66,12 +70,10 @@ check_libc_is_glibc() { | |||
66 | syntax error here | 70 | syntax error here |
67 | #endif | 71 | #endif |
68 | " >"$tempname".c | 72 | " >"$tempname".c |
69 | if $CC $CPPFLAGS $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1; then | 73 | ! $CC $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 |
70 | echo "$2"; | 74 | r=$? |
71 | else | 75 | rm -f "$tempname" "$tempname".c "$tempname".o |
72 | echo "$1"; | 76 | return $r |
73 | fi | ||
74 | rm -f "$tempname" "$tempname".[co] | ||
75 | } | 77 | } |
76 | 78 | ||
77 | EXE="$1" | 79 | EXE="$1" |
@@ -83,32 +85,41 @@ A_FILES="$6" | |||
83 | LDLIBS="$7" | 85 | LDLIBS="$7" |
84 | 86 | ||
85 | # The --sort-section option is not supported by older versions of ld | 87 | # The --sort-section option is not supported by older versions of ld |
86 | SORT_SECTION=`check_cc "-Wl,--sort-section,alignment" ""` | 88 | SORT_SECTION="-Wl,--sort-section,alignment" |
89 | if ! check_cc "-Wl,--sort-section,alignment"; then | ||
90 | echo "Your linker does not support --sort-section,alignment" | ||
91 | SORT_SECTION="" | ||
92 | fi | ||
87 | 93 | ||
88 | START_GROUP="-Wl,--start-group" | 94 | START_GROUP="-Wl,--start-group" |
89 | END_GROUP="-Wl,--end-group" | 95 | END_GROUP="-Wl,--end-group" |
90 | INFO_OPTS="-Wl,--warn-common -Wl,-Map,$EXE.map -Wl,--verbose" | 96 | INFO_OPTS="-Wl,--warn-common -Wl,-Map,$EXE.map -Wl,--verbose" |
91 | 97 | ||
92 | # gold may not support --sort-common (yet) | 98 | # gold may not support --sort-common (yet) |
93 | SORT_COMMON=`check_cc "-Wl,--sort-common" ""` | 99 | SORT_COMMON="-Wl,--sort-common" |
100 | if ! check_cc "-Wl,--sort-common"; then | ||
101 | echo "Your linker does not support --sort-common" | ||
102 | SORT_COMMON="" | ||
103 | fi | ||
94 | 104 | ||
95 | # Static linking against glibc produces buggy executables | 105 | # Static linking against glibc produces buggy executables |
96 | # (glibc does not cope well with ld --gc-sections). | 106 | # (glibc does not cope well with ld --gc-sections). |
97 | # See sources.redhat.com/bugzilla/show_bug.cgi?id=3400 | 107 | # See sources.redhat.com/bugzilla/show_bug.cgi?id=3400 |
98 | # Note that glibc is unsuitable for static linking anyway. | 108 | # Note that glibc is unsuitable for static linking anyway. |
99 | # We are removing -Wl,--gc-sections from link command line. | 109 | # We are removing -Wl,--gc-sections from link command line. |
100 | GC_SECTIONS=`( | 110 | GC_SECTIONS="-Wl,--gc-sections" |
101 | . ./.config | 111 | if (. ./.config && test x"$CONFIG_STATIC" = x"y") then |
102 | if test x"$CONFIG_STATIC" = x"y"; then | 112 | if check_libc_is_glibc; then |
103 | check_libc_is_glibc "" "-Wl,--gc-sections" | 113 | echo "Static linking against glibc, can't use --gc-sections" |
104 | else | 114 | GC_SECTIONS="" |
105 | echo "-Wl,--gc-sections" | 115 | fi |
106 | fi | 116 | fi |
107 | )` | ||
108 | |||
109 | # The --gc-sections option is not supported by older versions of ld | 117 | # The --gc-sections option is not supported by older versions of ld |
110 | if test -n "$GC_SECTIONS"; then | 118 | if test -n "$GC_SECTIONS"; then |
111 | GC_SECTIONS=`check_cc "$GC_SECTIONS" ""` | 119 | if ! check_cc "$GC_SECTIONS"; then |
120 | echo "Your linker does not support $GC_SECTIONS" | ||
121 | GC_SECTIONS="" | ||
122 | fi | ||
112 | fi | 123 | fi |
113 | 124 | ||
114 | # Sanitize lib list (dups, extra spaces etc) | 125 | # Sanitize lib list (dups, extra spaces etc) |
diff --git a/shell/ash.c b/shell/ash.c index 21fc05f01..08b6aa430 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2747,7 +2747,7 @@ updatepwd(const char *dir) | |||
2747 | new = stack_putstr(p, new); | 2747 | new = stack_putstr(p, new); |
2748 | USTPUTC('/', new); | 2748 | USTPUTC('/', new); |
2749 | } | 2749 | } |
2750 | p = strtok(0, "/"); | 2750 | p = strtok(NULL, "/"); |
2751 | } | 2751 | } |
2752 | if (new > lim) | 2752 | if (new > lim) |
2753 | STUNPUTC(new); | 2753 | STUNPUTC(new); |
@@ -5731,7 +5731,7 @@ popredir(int drop, int restore) | |||
5731 | struct redirtab *rp; | 5731 | struct redirtab *rp; |
5732 | int i; | 5732 | int i; |
5733 | 5733 | ||
5734 | if (--g_nullredirs >= 0) | 5734 | if (--g_nullredirs >= 0 || redirlist == NULL) |
5735 | return; | 5735 | return; |
5736 | INT_OFF; | 5736 | INT_OFF; |
5737 | rp = redirlist; | 5737 | rp = redirlist; |
@@ -8159,14 +8159,15 @@ findkwd(const char *s) | |||
8159 | * Locate and print what a word is... | 8159 | * Locate and print what a word is... |
8160 | */ | 8160 | */ |
8161 | static int | 8161 | static int |
8162 | describe_command(char *command, int describe_command_verbose) | 8162 | describe_command(char *command, const char *path, int describe_command_verbose) |
8163 | { | 8163 | { |
8164 | struct cmdentry entry; | 8164 | struct cmdentry entry; |
8165 | struct tblentry *cmdp; | 8165 | struct tblentry *cmdp; |
8166 | #if ENABLE_ASH_ALIAS | 8166 | #if ENABLE_ASH_ALIAS |
8167 | const struct alias *ap; | 8167 | const struct alias *ap; |
8168 | #endif | 8168 | #endif |
8169 | const char *path = pathval(); | 8169 | |
8170 | path = path ? path : pathval(); | ||
8170 | 8171 | ||
8171 | if (describe_command_verbose) { | 8172 | if (describe_command_verbose) { |
8172 | out1str(command); | 8173 | out1str(command); |
@@ -8266,7 +8267,7 @@ typecmd(int argc UNUSED_PARAM, char **argv) | |||
8266 | verbose = 0; | 8267 | verbose = 0; |
8267 | } | 8268 | } |
8268 | while (argv[i]) { | 8269 | while (argv[i]) { |
8269 | err |= describe_command(argv[i++], verbose); | 8270 | err |= describe_command(argv[i++], NULL, verbose); |
8270 | } | 8271 | } |
8271 | return err; | 8272 | return err; |
8272 | } | 8273 | } |
@@ -8280,6 +8281,7 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
8280 | VERIFY_BRIEF = 1, | 8281 | VERIFY_BRIEF = 1, |
8281 | VERIFY_VERBOSE = 2, | 8282 | VERIFY_VERBOSE = 2, |
8282 | } verify = 0; | 8283 | } verify = 0; |
8284 | const char *path = NULL; | ||
8283 | 8285 | ||
8284 | while ((c = nextopt("pvV")) != '\0') | 8286 | while ((c = nextopt("pvV")) != '\0') |
8285 | if (c == 'V') | 8287 | if (c == 'V') |
@@ -8290,9 +8292,11 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
8290 | else if (c != 'p') | 8292 | else if (c != 'p') |
8291 | abort(); | 8293 | abort(); |
8292 | #endif | 8294 | #endif |
8295 | else | ||
8296 | path = bb_default_path; | ||
8293 | /* Mimic bash: just "command -v" doesn't complain, it's a nop */ | 8297 | /* Mimic bash: just "command -v" doesn't complain, it's a nop */ |
8294 | if (verify && (*argptr != NULL)) { | 8298 | if (verify && (*argptr != NULL)) { |
8295 | return describe_command(*argptr, verify - VERIFY_BRIEF); | 8299 | return describe_command(*argptr, path, verify - VERIFY_BRIEF); |
8296 | } | 8300 | } |
8297 | 8301 | ||
8298 | return 0; | 8302 | return 0; |
@@ -9296,14 +9300,15 @@ parse_command_args(char **argv, const char **path) | |||
9296 | for (;;) { | 9300 | for (;;) { |
9297 | cp = *++argv; | 9301 | cp = *++argv; |
9298 | if (!cp) | 9302 | if (!cp) |
9299 | return 0; | 9303 | return NULL; |
9300 | if (*cp++ != '-') | 9304 | if (*cp++ != '-') |
9301 | break; | 9305 | break; |
9302 | c = *cp++; | 9306 | c = *cp++; |
9303 | if (!c) | 9307 | if (!c) |
9304 | break; | 9308 | break; |
9305 | if (c == '-' && !*cp) { | 9309 | if (c == '-' && !*cp) { |
9306 | argv++; | 9310 | if (!*++argv) |
9311 | return NULL; | ||
9307 | break; | 9312 | break; |
9308 | } | 9313 | } |
9309 | do { | 9314 | do { |
@@ -9313,7 +9318,7 @@ parse_command_args(char **argv, const char **path) | |||
9313 | break; | 9318 | break; |
9314 | default: | 9319 | default: |
9315 | /* run 'typecmd' for other options */ | 9320 | /* run 'typecmd' for other options */ |
9316 | return 0; | 9321 | return NULL; |
9317 | } | 9322 | } |
9318 | c = *cp++; | 9323 | c = *cp++; |
9319 | } while (c); | 9324 | } while (c); |
@@ -9400,6 +9405,9 @@ localcmd(int argc UNUSED_PARAM, char **argv) | |||
9400 | { | 9405 | { |
9401 | char *name; | 9406 | char *name; |
9402 | 9407 | ||
9408 | if (!funcnest) | ||
9409 | ash_msg_and_raise_error("not in a function"); | ||
9410 | |||
9403 | argv = argptr; | 9411 | argv = argptr; |
9404 | while ((name = *argv++) != NULL) { | 9412 | while ((name = *argv++) != NULL) { |
9405 | mklocal(name); | 9413 | mklocal(name); |
@@ -9865,7 +9873,7 @@ evalcommand(union node *cmd, int flags) | |||
9865 | if (evalbltin(cmdentry.u.cmd, argc, argv)) { | 9873 | if (evalbltin(cmdentry.u.cmd, argc, argv)) { |
9866 | int exit_status; | 9874 | int exit_status; |
9867 | int i = exception_type; | 9875 | int i = exception_type; |
9868 | if (i == EXEXIT) | 9876 | if (i == EXEXIT || i == EXEXEC) |
9869 | goto raise; | 9877 | goto raise; |
9870 | exit_status = 2; | 9878 | exit_status = 2; |
9871 | if (i == EXINT) | 9879 | if (i == EXINT) |
@@ -10959,7 +10967,7 @@ static union node *andor(void); | |||
10959 | static union node *pipeline(void); | 10967 | static union node *pipeline(void); |
10960 | static union node *parse_command(void); | 10968 | static union node *parse_command(void); |
10961 | static void parseheredoc(void); | 10969 | static void parseheredoc(void); |
10962 | static char nexttoken_ends_list(void); | 10970 | static int peektoken(void); |
10963 | static int readtoken(void); | 10971 | static int readtoken(void); |
10964 | 10972 | ||
10965 | static union node * | 10973 | static union node * |
@@ -10968,11 +10976,27 @@ list(int nlflag) | |||
10968 | union node *n1, *n2, *n3; | 10976 | union node *n1, *n2, *n3; |
10969 | int tok; | 10977 | int tok; |
10970 | 10978 | ||
10971 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | ||
10972 | if (nlflag == 2 && nexttoken_ends_list()) | ||
10973 | return NULL; | ||
10974 | n1 = NULL; | 10979 | n1 = NULL; |
10975 | for (;;) { | 10980 | for (;;) { |
10981 | switch (peektoken()) { | ||
10982 | case TNL: | ||
10983 | if (!(nlflag & 1)) | ||
10984 | break; | ||
10985 | parseheredoc(); | ||
10986 | return n1; | ||
10987 | |||
10988 | case TEOF: | ||
10989 | if (!n1 && (nlflag & 1)) | ||
10990 | n1 = NODE_EOF; | ||
10991 | parseheredoc(); | ||
10992 | return n1; | ||
10993 | } | ||
10994 | |||
10995 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | ||
10996 | if (nlflag == 2 && tokname_array[peektoken()][0]) | ||
10997 | return n1; | ||
10998 | nlflag |= 2; | ||
10999 | |||
10976 | n2 = andor(); | 11000 | n2 = andor(); |
10977 | tok = readtoken(); | 11001 | tok = readtoken(); |
10978 | if (tok == TBACKGND) { | 11002 | if (tok == TBACKGND) { |
@@ -10998,37 +11022,15 @@ list(int nlflag) | |||
10998 | n1 = n3; | 11022 | n1 = n3; |
10999 | } | 11023 | } |
11000 | switch (tok) { | 11024 | switch (tok) { |
11025 | case TNL: | ||
11026 | case TEOF: | ||
11027 | tokpushback = 1; | ||
11028 | /* fall through */ | ||
11001 | case TBACKGND: | 11029 | case TBACKGND: |
11002 | case TSEMI: | 11030 | case TSEMI: |
11003 | tok = readtoken(); | ||
11004 | /* fall through */ | ||
11005 | case TNL: | ||
11006 | if (tok == TNL) { | ||
11007 | parseheredoc(); | ||
11008 | if (nlflag == 1) | ||
11009 | return n1; | ||
11010 | } else { | ||
11011 | tokpushback = 1; | ||
11012 | } | ||
11013 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | ||
11014 | if (nexttoken_ends_list()) { | ||
11015 | /* Testcase: "<<EOF; then <W". | ||
11016 | * It used to segfault w/o this check: | ||
11017 | */ | ||
11018 | if (heredoclist) { | ||
11019 | raise_error_unexpected_syntax(-1); | ||
11020 | } | ||
11021 | return n1; | ||
11022 | } | ||
11023 | break; | 11031 | break; |
11024 | case TEOF: | ||
11025 | if (heredoclist) | ||
11026 | parseheredoc(); | ||
11027 | else | ||
11028 | pungetc(); /* push back EOF on input */ | ||
11029 | return n1; | ||
11030 | default: | 11032 | default: |
11031 | if (nlflag == 1) | 11033 | if ((nlflag & 1)) |
11032 | raise_error_unexpected_syntax(-1); | 11034 | raise_error_unexpected_syntax(-1); |
11033 | tokpushback = 1; | 11035 | tokpushback = 1; |
11034 | return n1; | 11036 | return n1; |
@@ -11356,7 +11358,7 @@ parse_command(void) | |||
11356 | n1 = stzalloc(sizeof(struct nfor)); | 11358 | n1 = stzalloc(sizeof(struct nfor)); |
11357 | n1->type = NFOR; | 11359 | n1->type = NFOR; |
11358 | n1->nfor.var = wordtext; | 11360 | n1->nfor.var = wordtext; |
11359 | checkkwd = CHKKWD | CHKALIAS; | 11361 | checkkwd = CHKNL | CHKKWD | CHKALIAS; |
11360 | if (readtoken() == TIN) { | 11362 | if (readtoken() == TIN) { |
11361 | app = ≈ | 11363 | app = ≈ |
11362 | while (readtoken() == TWORD) { | 11364 | while (readtoken() == TWORD) { |
@@ -11383,7 +11385,7 @@ parse_command(void) | |||
11383 | * Newline or semicolon here is optional (but note | 11385 | * Newline or semicolon here is optional (but note |
11384 | * that the original Bourne shell only allowed NL). | 11386 | * that the original Bourne shell only allowed NL). |
11385 | */ | 11387 | */ |
11386 | if (lasttoken != TNL && lasttoken != TSEMI) | 11388 | if (lasttoken != TSEMI) |
11387 | tokpushback = 1; | 11389 | tokpushback = 1; |
11388 | } | 11390 | } |
11389 | checkkwd = CHKNL | CHKKWD | CHKALIAS; | 11391 | checkkwd = CHKNL | CHKKWD | CHKALIAS; |
@@ -11402,10 +11404,8 @@ parse_command(void) | |||
11402 | /*n2->narg.next = NULL; - stzalloc did it */ | 11404 | /*n2->narg.next = NULL; - stzalloc did it */ |
11403 | n2->narg.text = wordtext; | 11405 | n2->narg.text = wordtext; |
11404 | n2->narg.backquote = backquotelist; | 11406 | n2->narg.backquote = backquotelist; |
11405 | do { | 11407 | checkkwd = CHKNL | CHKKWD | CHKALIAS; |
11406 | checkkwd = CHKKWD | CHKALIAS; | 11408 | if (readtoken() != TIN) |
11407 | } while (readtoken() == TNL); | ||
11408 | if (lasttoken != TIN) | ||
11409 | raise_error_unexpected_syntax(TIN); | 11409 | raise_error_unexpected_syntax(TIN); |
11410 | cpp = &n1->ncase.cases; | 11410 | cpp = &n1->ncase.cases; |
11411 | next_case: | 11411 | next_case: |
@@ -12336,6 +12336,7 @@ static int | |||
12336 | readtoken(void) | 12336 | readtoken(void) |
12337 | { | 12337 | { |
12338 | int t; | 12338 | int t; |
12339 | int kwd = checkkwd; | ||
12339 | #if DEBUG | 12340 | #if DEBUG |
12340 | smallint alreadyseen = tokpushback; | 12341 | smallint alreadyseen = tokpushback; |
12341 | #endif | 12342 | #endif |
@@ -12349,7 +12350,7 @@ readtoken(void) | |||
12349 | /* | 12350 | /* |
12350 | * eat newlines | 12351 | * eat newlines |
12351 | */ | 12352 | */ |
12352 | if (checkkwd & CHKNL) { | 12353 | if (kwd & CHKNL) { |
12353 | while (t == TNL) { | 12354 | while (t == TNL) { |
12354 | parseheredoc(); | 12355 | parseheredoc(); |
12355 | t = xxreadtoken(); | 12356 | t = xxreadtoken(); |
@@ -12363,7 +12364,7 @@ readtoken(void) | |||
12363 | /* | 12364 | /* |
12364 | * check for keywords | 12365 | * check for keywords |
12365 | */ | 12366 | */ |
12366 | if (checkkwd & CHKKWD) { | 12367 | if (kwd & CHKKWD) { |
12367 | const char *const *pp; | 12368 | const char *const *pp; |
12368 | 12369 | ||
12369 | pp = findkwd(wordtext); | 12370 | pp = findkwd(wordtext); |
@@ -12397,14 +12398,14 @@ readtoken(void) | |||
12397 | return t; | 12398 | return t; |
12398 | } | 12399 | } |
12399 | 12400 | ||
12400 | static char | 12401 | static int |
12401 | nexttoken_ends_list(void) | 12402 | peektoken(void) |
12402 | { | 12403 | { |
12403 | int t; | 12404 | int t; |
12404 | 12405 | ||
12405 | t = readtoken(); | 12406 | t = readtoken(); |
12406 | tokpushback = 1; | 12407 | tokpushback = 1; |
12407 | return tokname_array[t][0]; | 12408 | return t; |
12408 | } | 12409 | } |
12409 | 12410 | ||
12410 | /* | 12411 | /* |
@@ -12414,18 +12415,12 @@ nexttoken_ends_list(void) | |||
12414 | static union node * | 12415 | static union node * |
12415 | parsecmd(int interact) | 12416 | parsecmd(int interact) |
12416 | { | 12417 | { |
12417 | int t; | ||
12418 | |||
12419 | tokpushback = 0; | 12418 | tokpushback = 0; |
12419 | checkkwd = 0; | ||
12420 | heredoclist = 0; | ||
12420 | doprompt = interact; | 12421 | doprompt = interact; |
12421 | setprompt_if(doprompt, doprompt); | 12422 | setprompt_if(doprompt, doprompt); |
12422 | needprompt = 0; | 12423 | needprompt = 0; |
12423 | t = readtoken(); | ||
12424 | if (t == TEOF) | ||
12425 | return NODE_EOF; | ||
12426 | if (t == TNL) | ||
12427 | return NULL; | ||
12428 | tokpushback = 1; | ||
12429 | return list(1); | 12424 | return list(1); |
12430 | } | 12425 | } |
12431 | 12426 | ||
diff --git a/shell/ash_test/ash-heredoc/heredoc2.right b/shell/ash_test/ash-heredoc/heredoc2.right new file mode 100644 index 000000000..a486f1ac4 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc2.right | |||
@@ -0,0 +1,2 @@ | |||
1 | bar | ||
2 | bar | ||
diff --git a/shell/ash_test/ash-heredoc/heredoc2.tests b/shell/ash_test/ash-heredoc/heredoc2.tests new file mode 100755 index 000000000..6d9ccb6cc --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc2.tests | |||
@@ -0,0 +1,7 @@ | |||
1 | foo () { | ||
2 | cat <<EOF && { echo "$1" ; } | ||
3 | $1 | ||
4 | EOF | ||
5 | } | ||
6 | |||
7 | foo "bar" | ||
diff --git a/shell/ash_test/ash-heredoc/heredoc3.right b/shell/ash_test/ash-heredoc/heredoc3.right new file mode 100644 index 000000000..ce0136250 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc3.right | |||
@@ -0,0 +1 @@ | |||
hello | |||
diff --git a/shell/ash_test/ash-heredoc/heredoc3.tests b/shell/ash_test/ash-heredoc/heredoc3.tests new file mode 100755 index 000000000..96c227cc1 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc3.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | echo hello >greeting | ||
2 | cat <<EOF && | ||
3 | $(cat greeting) | ||
4 | EOF | ||
5 | { | ||
6 | echo $? | ||
7 | cat greeting | ||
8 | } >/dev/null | ||
9 | rm greeting | ||
diff --git a/shell/ash_test/ash-misc/command.right b/shell/ash_test/ash-misc/command.right new file mode 100644 index 000000000..7f746d9c4 --- /dev/null +++ b/shell/ash_test/ash-misc/command.right | |||
@@ -0,0 +1 @@ | |||
recho: not found | |||
diff --git a/shell/ash_test/ash-misc/command.tests b/shell/ash_test/ash-misc/command.tests new file mode 100755 index 000000000..5d445af51 --- /dev/null +++ b/shell/ash_test/ash-misc/command.tests | |||
@@ -0,0 +1 @@ | |||
command -p -V recho | |||
diff --git a/shell/ash_test/ash-misc/command2.right b/shell/ash_test/ash-misc/command2.right new file mode 100644 index 000000000..8d2165f69 --- /dev/null +++ b/shell/ash_test/ash-misc/command2.right | |||
@@ -0,0 +1,2 @@ | |||
1 | test1 | ||
2 | ./command2.tests: ./test1.sh: line 1: ./test2.sh: Permission denied | ||
diff --git a/shell/ash_test/ash-misc/command2.tests b/shell/ash_test/ash-misc/command2.tests new file mode 100755 index 000000000..9d9de9a89 --- /dev/null +++ b/shell/ash_test/ash-misc/command2.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | echo "echo test1; ./test2.sh" >test1.sh | ||
2 | echo "echo test2" >test2.sh | ||
3 | |||
4 | command . ./test1.sh | ||
5 | |||
6 | rm -f test1.sh test2.sh | ||
diff --git a/shell/ash_test/ash-misc/exec.right b/shell/ash_test/ash-misc/exec.right new file mode 100644 index 000000000..1741a38dd --- /dev/null +++ b/shell/ash_test/ash-misc/exec.right | |||
@@ -0,0 +1,2 @@ | |||
1 | ./exec.tests: exec: line 2: ./test1.sh: not found | ||
2 | 127 | ||
diff --git a/shell/ash_test/ash-misc/exec.tests b/shell/ash_test/ash-misc/exec.tests new file mode 100755 index 000000000..624915de1 --- /dev/null +++ b/shell/ash_test/ash-misc/exec.tests | |||
@@ -0,0 +1,3 @@ | |||
1 | rm -f test1.sh | ||
2 | (exec ./test1.sh) | ||
3 | echo $? | ||
diff --git a/shell/ash_test/ash-misc/for.right b/shell/ash_test/ash-misc/for.right new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/shell/ash_test/ash-misc/for.right | |||
@@ -0,0 +1 @@ | |||
OK | |||
diff --git a/shell/ash_test/ash-misc/for.tests b/shell/ash_test/ash-misc/for.tests new file mode 100755 index 000000000..4889a9f2d --- /dev/null +++ b/shell/ash_test/ash-misc/for.tests | |||
@@ -0,0 +1,5 @@ | |||
1 | for i | ||
2 | in OK | ||
3 | do | ||
4 | echo $i | ||
5 | done | ||
diff --git a/shell/ash_test/ash-misc/local2.right b/shell/ash_test/ash-misc/local2.right new file mode 100644 index 000000000..630ef7979 --- /dev/null +++ b/shell/ash_test/ash-misc/local2.right | |||
@@ -0,0 +1 @@ | |||
./local2.tests: local: line 1: not in a function | |||
diff --git a/shell/ash_test/ash-misc/local2.tests b/shell/ash_test/ash-misc/local2.tests new file mode 100755 index 000000000..8e14037c5 --- /dev/null +++ b/shell/ash_test/ash-misc/local2.tests | |||
@@ -0,0 +1 @@ | |||
local x=1 | |||
diff --git a/shell/ash_test/run-all b/shell/ash_test/run-all index ad93e251d..354cc1fcf 100755 --- a/shell/ash_test/run-all +++ b/shell/ash_test/run-all | |||
@@ -31,8 +31,9 @@ do_test() | |||
31 | *.orig|*~) ;; | 31 | *.orig|*~) ;; |
32 | #*) echo $x ; sh $x ;; | 32 | #*) echo $x ; sh $x ;; |
33 | *) | 33 | *) |
34 | echo -n "$1/$x: " | ||
34 | sh "$x" >"$TOPDIR/$noslash-$x.fail" 2>&1 && \ | 35 | sh "$x" >"$TOPDIR/$noslash-$x.fail" 2>&1 && \ |
35 | { echo "$1/$x: ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "$1/$x: fail"; | 36 | { echo "ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "fail"; |
36 | ;; | 37 | ;; |
37 | esac | 38 | esac |
38 | done | 39 | done |
@@ -42,11 +43,12 @@ do_test() | |||
42 | test -x "$x" || continue | 43 | test -x "$x" || continue |
43 | name="${x%%.tests}" | 44 | name="${x%%.tests}" |
44 | test -f "$name.right" || continue | 45 | test -f "$name.right" || continue |
46 | echo -n "$1/$x: " | ||
45 | { | 47 | { |
46 | "$THIS_SH" "./$x" >"$name.xx" 2>&1 | 48 | "$THIS_SH" "./$x" >"$name.xx" 2>&1 |
47 | diff -u "$name.xx" "$name.right" >"$TOPDIR/$noslash-$x.fail" \ | 49 | diff -u "$name.xx" "$name.right" >"$TOPDIR/$noslash-$x.fail" \ |
48 | && rm -f "$name.xx" "$TOPDIR/$noslash-$x.fail" | 50 | && rm -f "$name.xx" "$TOPDIR/$noslash-$x.fail" |
49 | } && echo "$1/$x: ok" || echo "$1/$x: fail" | 51 | } && echo "ok" || echo "fail" |
50 | done | 52 | done |
51 | ) | 53 | ) |
52 | } | 54 | } |
diff --git a/shell/hush_test/hush-misc/for.right b/shell/hush_test/hush-misc/for.right new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/shell/hush_test/hush-misc/for.right | |||
@@ -0,0 +1 @@ | |||
OK | |||
diff --git a/shell/hush_test/hush-misc/for.tests b/shell/hush_test/hush-misc/for.tests new file mode 100755 index 000000000..4889a9f2d --- /dev/null +++ b/shell/hush_test/hush-misc/for.tests | |||
@@ -0,0 +1,5 @@ | |||
1 | for i | ||
2 | in OK | ||
3 | do | ||
4 | echo $i | ||
5 | done | ||
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 288b29cf7..0ea557a6c 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -936,11 +936,6 @@ static NOINLINE int create_socket(void) | |||
936 | int sock_fd; | 936 | int sock_fd; |
937 | char *dev_log_name; | 937 | char *dev_log_name; |
938 | 938 | ||
939 | #if ENABLE_FEATURE_SYSTEMD | ||
940 | if (sd_listen_fds() == 1) | ||
941 | return SD_LISTEN_FDS_START; | ||
942 | #endif | ||
943 | |||
944 | memset(&sunx, 0, sizeof(sunx)); | 939 | memset(&sunx, 0, sizeof(sunx)); |
945 | sunx.sun_family = AF_UNIX; | 940 | sunx.sun_family = AF_UNIX; |
946 | 941 | ||
diff --git a/testsuite/sort.tests b/testsuite/sort.tests index c4b223464..c51a8e475 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests | |||
@@ -106,6 +106,50 @@ a/a:a | |||
106 | a:b | 106 | a:b |
107 | " "" | 107 | " "" |
108 | 108 | ||
109 | testing "sort with ENDCHAR" "sort -t. -k1,1.1 -k2 input" "\ | ||
110 | ab.1 | ||
111 | aa.2 | ||
112 | " "\ | ||
113 | aa.2 | ||
114 | ab.1 | ||
115 | " "" | ||
116 | |||
117 | testing "glibc build sort" "sort -t. -k 1,1 -k 2n,2n -k 3 input" "\ | ||
118 | GLIBC_2.1 | ||
119 | GLIBC_2.1.1 | ||
120 | GLIBC_2.2 | ||
121 | GLIBC_2.2.1 | ||
122 | GLIBC_2.10 | ||
123 | GLIBC_2.20 | ||
124 | GLIBC_2.21 | ||
125 | " "\ | ||
126 | GLIBC_2.21 | ||
127 | GLIBC_2.1.1 | ||
128 | GLIBC_2.2.1 | ||
129 | GLIBC_2.2 | ||
130 | GLIBC_2.20 | ||
131 | GLIBC_2.10 | ||
132 | GLIBC_2.1 | ||
133 | " "" | ||
134 | |||
135 | testing "glibc build sort unique" "sort -u -t. -k 1,1 -k 2n,2n -k 3 input" "\ | ||
136 | GLIBC_2.1 | ||
137 | GLIBC_2.1.1 | ||
138 | GLIBC_2.2 | ||
139 | GLIBC_2.2.1 | ||
140 | GLIBC_2.10 | ||
141 | GLIBC_2.20 | ||
142 | GLIBC_2.21 | ||
143 | " "\ | ||
144 | GLIBC_2.10 | ||
145 | GLIBC_2.2.1 | ||
146 | GLIBC_2.1.1 | ||
147 | GLIBC_2.20 | ||
148 | GLIBC_2.2 | ||
149 | GLIBC_2.1 | ||
150 | GLIBC_2.21 | ||
151 | " "" | ||
152 | |||
109 | testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ | 153 | testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ |
110 | a c | 154 | a c |
111 | " "\ | 155 | " "\ |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 4929f4e49..890a73dd5 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -53,6 +53,15 @@ dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $? | |||
53 | "" "" | 53 | "" "" |
54 | SKIP= | 54 | SKIP= |
55 | 55 | ||
56 | # "tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input": | ||
57 | # GNU tar 1.26 records as hardlinks: | ||
58 | # input_hard2 -> input_hard1 | ||
59 | # input_hard1 -> input_hard1 (!!!) | ||
60 | # input_dir/file -> input_dir/file | ||
61 | # input -> input | ||
62 | # As of 1.24.0, we don't record last two: for them, nlink==1 | ||
63 | # and we check for "hardlink"ness only files with nlink!=1 | ||
64 | # We also don't use "hrw-r--r--" notation for hardlinks in "tar tv" listing. | ||
56 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES | 65 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES |
57 | testing "tar hardlinks and repeated files" '\ | 66 | testing "tar hardlinks and repeated files" '\ |
58 | rm -rf input_* test.tar 2>/dev/null | 67 | rm -rf input_* test.tar 2>/dev/null |
@@ -64,6 +73,7 @@ chmod -R 644 * | |||
64 | chmod 755 input_dir | 73 | chmod 755 input_dir |
65 | tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input | 74 | tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input |
66 | tar tvf test.tar | sed "s/.*[0-9] input/input/" | 75 | tar tvf test.tar | sed "s/.*[0-9] input/input/" |
76 | rm -rf input_dir | ||
67 | tar xf test.tar 2>&1 | 77 | tar xf test.tar 2>&1 |
68 | echo Ok: $? | 78 | echo Ok: $? |
69 | ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" | 79 | ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" |
@@ -246,6 +256,49 @@ Ok | |||
246 | "" "" | 256 | "" "" |
247 | SKIP= | 257 | SKIP= |
248 | 258 | ||
259 | # attack.tar.bz2 has symlink pointing to a system file | ||
260 | # followed by a regular file with the same name | ||
261 | # containing "root::0:0::/root:/bin/sh": | ||
262 | # lrwxrwxrwx root/root passwd -> /tmp/passwd | ||
263 | # -rw-r--r-- root/root passwd | ||
264 | # naive tar implementation may end up creating the symlink | ||
265 | # and then writing into it. | ||
266 | # The correct implementation unlinks target before | ||
267 | # creating the second file. | ||
268 | # We test that /tmp/passwd remains empty: | ||
269 | optional UUDECODE FEATURE_SEAMLESS_BZ2 | ||
270 | testing "tar does not extract into symlinks" "\ | ||
271 | >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? | ||
272 | " "\ | ||
273 | 0 | ||
274 | " \ | ||
275 | "" "\ | ||
276 | begin-base64 644 attack.tar.bz2 | ||
277 | QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 | ||
278 | po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL | ||
279 | DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 | ||
280 | l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= | ||
281 | ==== | ||
282 | " | ||
283 | SKIP= | ||
284 | # And same with -k | ||
285 | optional UUDECODE FEATURE_SEAMLESS_BZ2 | ||
286 | testing "tar -k does not extract into symlinks" "\ | ||
287 | >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? | ||
288 | " "\ | ||
289 | tar: can't open 'passwd': File exists | ||
290 | 0 | ||
291 | " \ | ||
292 | "" "\ | ||
293 | begin-base64 644 attack.tar.bz2 | ||
294 | QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 | ||
295 | po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL | ||
296 | DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 | ||
297 | l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= | ||
298 | ==== | ||
299 | " | ||
300 | SKIP= | ||
301 | |||
249 | 302 | ||
250 | cd .. && rm -rf tar.tempdir || exit 1 | 303 | cd .. && rm -rf tar.tempdir || exit 1 |
251 | 304 | ||
diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index 8677a0306..d8738a3bd 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | . ./testing.sh | 8 | . ./testing.sh |
9 | 9 | ||
10 | # testing "test name" "options" "expected result" "file input" "stdin" | 10 | # testing "test name" "commands" "expected result" "file input" "stdin" |
11 | # file input will be file called "input" | 11 | # file input will be file called "input" |
12 | # test can create a file "actual" instead of writing to stdout | 12 | # test can create a file "actual" instead of writing to stdout |
13 | 13 | ||
@@ -30,6 +30,28 @@ testing "unzip (subdir only)" "unzip -q foo.zip foo/ && test -d foo && test ! -f | |||
30 | rmdir foo | 30 | rmdir foo |
31 | rm foo.zip | 31 | rm foo.zip |
32 | 32 | ||
33 | # File containing some damaged encrypted stream | ||
34 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ | ||
35 | "Archive: bad.zip | ||
36 | inflating: ]3j½r«IK-%Ix | ||
37 | unzip: corrupted data | ||
38 | unzip: inflate error | ||
39 | 1 | ||
40 | " \ | ||
41 | "" "\ | ||
42 | begin-base64 644 bad.zip | ||
43 | UEsDBBQAAgkIAAAAIQA5AAAANwAAADwAAAAQAAcAXTNqwr1ywqtJGxJLLSVJ | ||
44 | eCkBD0AdKBk8JzQsIj01JC0/ORJQSwMEFAECCAAAAAAhADoAAAAPAAAANgAA | ||
45 | AAwAAQASw73Ct1DCokohPXQiNjoUNTUiHRwgLT4WHlBLAQIQABQAAggIAAAA | ||
46 | oQA5AAAANwAAADwAAAAQQAcADAAAACwAMgCAAAAAAABdM2rCvXLCq0kbEkst | ||
47 | JUl4KQEPQB0oGSY4Cz4QNgEnJSYIPVBLAQIAABQAAggAAAAAIQAqAAAADwAA | ||
48 | BDYAAAAMAAEADQAAADIADQAAAEEAAAASw73Ct1DKokohPXQiNzA+FAI1HCcW | ||
49 | NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM= | ||
50 | ==== | ||
51 | " | ||
52 | |||
53 | rm * | ||
54 | |||
33 | # Clean up scratch directory. | 55 | # Clean up scratch directory. |
34 | 56 | ||
35 | cd .. | 57 | cd .. |
diff --git a/util-linux/Config.src b/util-linux/Config.src index 854b3682e..922cabdb8 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src | |||
@@ -489,16 +489,6 @@ config SCRIPTREPLAY | |||
489 | This program replays a typescript, using timing information | 489 | This program replays a typescript, using timing information |
490 | given by script -t. | 490 | given by script -t. |
491 | 491 | ||
492 | config SETARCH | ||
493 | bool "setarch" | ||
494 | default y | ||
495 | select PLATFORM_LINUX | ||
496 | help | ||
497 | The linux32 utility is used to create a 32bit environment for the | ||
498 | specified program (usually a shell). It only makes sense to have | ||
499 | this util on a system that supports both 64bit and 32bit userland | ||
500 | (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). | ||
501 | |||
502 | config SWAPONOFF | 492 | config SWAPONOFF |
503 | bool "swaponoff" | 493 | bool "swaponoff" |
504 | default y | 494 | default y |
diff --git a/util-linux/Kbuild.src b/util-linux/Kbuild.src index 468fc6bc1..0b87c52ac 100644 --- a/util-linux/Kbuild.src +++ b/util-linux/Kbuild.src | |||
@@ -40,7 +40,6 @@ lib-$(CONFIG_READPROFILE) += readprofile.o | |||
40 | lib-$(CONFIG_RTCWAKE) += rtcwake.o | 40 | lib-$(CONFIG_RTCWAKE) += rtcwake.o |
41 | lib-$(CONFIG_SCRIPT) += script.o | 41 | lib-$(CONFIG_SCRIPT) += script.o |
42 | lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o | 42 | lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o |
43 | lib-$(CONFIG_SETARCH) += setarch.o | ||
44 | lib-$(CONFIG_SWAPONOFF) += swaponoff.o | 43 | lib-$(CONFIG_SWAPONOFF) += swaponoff.o |
45 | lib-$(CONFIG_SWITCH_ROOT) += switch_root.o | 44 | lib-$(CONFIG_SWITCH_ROOT) += switch_root.o |
46 | lib-$(CONFIG_UMOUNT) += umount.o | 45 | lib-$(CONFIG_UMOUNT) += umount.o |
diff --git a/util-linux/setarch.c b/util-linux/setarch.c index 7b9421af1..2e989ec2a 100644 --- a/util-linux/setarch.c +++ b/util-linux/setarch.c | |||
@@ -6,13 +6,30 @@ | |||
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 | */ | 8 | */ |
9 | //config:config SETARCH | ||
10 | //config: bool "setarch" | ||
11 | //config: default y | ||
12 | //config: select PLATFORM_LINUX | ||
13 | //config: help | ||
14 | //config: The linux32 utility is used to create a 32bit environment for the | ||
15 | //config: specified program (usually a shell). It only makes sense to have | ||
16 | //config: this util on a system that supports both 64bit and 32bit userland | ||
17 | //config: (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). | ||
18 | |||
19 | //applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) | ||
20 | //applet:IF_SETARCH(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) | ||
21 | //applet:IF_SETARCH(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) | ||
22 | |||
23 | //kbuild:lib-$(CONFIG_SETARCH) += setarch.o | ||
9 | 24 | ||
10 | //usage:#define setarch_trivial_usage | 25 | //usage:#define setarch_trivial_usage |
11 | //usage: "personality PROG ARGS" | 26 | //usage: "PERSONALITY [-R] PROG ARGS" |
12 | //usage:#define setarch_full_usage "\n\n" | 27 | //usage:#define setarch_full_usage "\n\n" |
13 | //usage: "Personality may be:\n" | 28 | //usage: "PERSONALITY may be:" |
14 | //usage: " linux32 Set 32bit uname emulation\n" | 29 | //usage: "\n"" linux32 Set 32bit uname emulation" |
15 | //usage: " linux64 Set 64bit uname emulation" | 30 | //usage: "\n"" linux64 Set 64bit uname emulation" |
31 | //usage: "\n" | ||
32 | //usage: "\n"" -R Disable address space randomization" | ||
16 | //usage: | 33 | //usage: |
17 | //usage:#define linux32_trivial_usage NOUSAGE_STR | 34 | //usage:#define linux32_trivial_usage NOUSAGE_STR |
18 | //usage:#define linux32_full_usage "" | 35 | //usage:#define linux32_full_usage "" |
@@ -20,14 +37,18 @@ | |||
20 | //usage:#define linux64_trivial_usage NOUSAGE_STR | 37 | //usage:#define linux64_trivial_usage NOUSAGE_STR |
21 | //usage:#define linux64_full_usage "" | 38 | //usage:#define linux64_full_usage "" |
22 | 39 | ||
40 | #include "libbb.h" | ||
23 | #include <sys/personality.h> | 41 | #include <sys/personality.h> |
24 | 42 | ||
25 | #include "libbb.h" | 43 | #ifndef ADDR_NO_RANDOMIZE |
44 | # define ADDR_NO_RANDOMIZE 0x0040000 | ||
45 | #endif | ||
26 | 46 | ||
27 | int setarch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 47 | int setarch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
28 | int setarch_main(int argc UNUSED_PARAM, char **argv) | 48 | int setarch_main(int argc UNUSED_PARAM, char **argv) |
29 | { | 49 | { |
30 | int pers; | 50 | unsigned opts; |
51 | unsigned long pers; | ||
31 | 52 | ||
32 | /* Figure out what personality we are supposed to switch to ... | 53 | /* Figure out what personality we are supposed to switch to ... |
33 | * we can be invoked as either: | 54 | * we can be invoked as either: |
@@ -35,7 +56,7 @@ int setarch_main(int argc UNUSED_PARAM, char **argv) | |||
35 | * argv[0] == "personality" | 56 | * argv[0] == "personality" |
36 | */ | 57 | */ |
37 | if (ENABLE_SETARCH && applet_name[0] == 's' | 58 | if (ENABLE_SETARCH && applet_name[0] == 's' |
38 | && argv[1] && strncpy(argv[1], "linux", 5) | 59 | && argv[1] && is_prefixed_with(argv[1], "linux") |
39 | ) { | 60 | ) { |
40 | applet_name = argv[1]; | 61 | applet_name = argv[1]; |
41 | argv++; | 62 | argv++; |
@@ -47,15 +68,18 @@ int setarch_main(int argc UNUSED_PARAM, char **argv) | |||
47 | else | 68 | else |
48 | bb_show_usage(); | 69 | bb_show_usage(); |
49 | 70 | ||
50 | argv++; | 71 | opts = getopt32(argv, "+R"); /* '+': stop at first non-option */ |
51 | if (argv[0] == NULL) | 72 | if (opts) |
52 | bb_show_usage(); | 73 | pers |= ADDR_NO_RANDOMIZE; |
53 | 74 | ||
54 | /* Try to set personality */ | 75 | /* Try to set personality */ |
55 | if (personality(pers) >= 0) { | 76 | if (personality(pers) < 0) |
56 | /* Try to execute the program */ | 77 | bb_perror_msg_and_die("personality(0x%lx)", pers); |
57 | BB_EXECVP(argv[0], argv); | 78 | |
58 | } | 79 | argv += optind; |
80 | if (!argv[0]) | ||
81 | (--argv)[0] = (char*)"/bin/sh"; | ||
59 | 82 | ||
60 | bb_simple_perror_msg_and_die(argv[0]); | 83 | /* Try to execute the program */ |
84 | BB_EXECVP_or_die(argv); | ||
61 | } | 85 | } |