diff options
author | Ron Yorston <rmy@pobox.com> | 2014-01-02 10:25:11 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-01-02 10:25:11 +0000 |
commit | b8f278ee745778806118f57fb7884d205eba05ad (patch) | |
tree | fef237f6dd302c59918cf389a60c120e58d3e086 | |
parent | 3fd34651ea72ea1c335d3170f234cb0517fd897f (diff) | |
parent | 57434022cefde87133b8ad39fb3b79c1274e7684 (diff) | |
download | busybox-w32-b8f278ee745778806118f57fb7884d205eba05ad.tar.gz busybox-w32-b8f278ee745778806118f57fb7884d205eba05ad.tar.bz2 busybox-w32-b8f278ee745778806118f57fb7884d205eba05ad.zip |
Merge branch 'busybox' into merge
Conflicts:
archival/Config.src
shell/ash.c
141 files changed, 1724 insertions, 1162 deletions
@@ -1,5 +1,5 @@ | |||
1 | VERSION = 1 | 1 | VERSION = 1 |
2 | PATCHLEVEL = 22 | 2 | PATCHLEVEL = 23 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = .git | 4 | EXTRAVERSION = .git |
5 | NAME = Unnamed | 5 | NAME = Unnamed |
diff --git a/Makefile.custom b/Makefile.custom index 3561e5768..8c95ef2d4 100644 --- a/Makefile.custom +++ b/Makefile.custom | |||
@@ -74,6 +74,10 @@ release: distclean | |||
74 | -print \ | 74 | -print \ |
75 | -exec rm -r -f {} \; ; \ | 75 | -exec rm -r -f {} \; ; \ |
76 | find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type f \ | 76 | find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type f \ |
77 | -name .gitignore \ | ||
78 | -print \ | ||
79 | -exec rm -f {} \; ; \ | ||
80 | find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type f \ | ||
77 | -name .\#* \ | 81 | -name .\#* \ |
78 | -print \ | 82 | -print \ |
79 | -exec rm -f {} \; ; \ | 83 | -exec rm -f {} \; ; \ |
@@ -127,11 +127,6 @@ patch | |||
127 | 127 | ||
128 | And while we're at it, a new patch filename quoting format is apparently | 128 | And while we're at it, a new patch filename quoting format is apparently |
129 | coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 | 129 | coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 |
130 | --- | ||
131 | tail | ||
132 | ./busybox tail -f foo.c~ TODO | ||
133 | should not print fmt=header_fmt for subsequent date >> TODO; i.e. only | ||
134 | fmt+ if another (not the current) file did change | ||
135 | 130 | ||
136 | Architectural issues: | 131 | Architectural issues: |
137 | 132 | ||
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 152d5f441..94b974e09 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -53,7 +53,7 @@ int main(int argc, char **argv) | |||
53 | { | 53 | { |
54 | int i; | 54 | int i; |
55 | int ofs; | 55 | int ofs; |
56 | unsigned MAX_APPLET_NAME_LEN = 1; | 56 | // unsigned MAX_APPLET_NAME_LEN = 1; |
57 | 57 | ||
58 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); | 58 | qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); |
59 | 59 | ||
@@ -89,8 +89,8 @@ int main(int argc, char **argv) | |||
89 | printf("const char applet_names[] ALIGN1 = \"\"\n"); | 89 | printf("const char applet_names[] ALIGN1 = \"\"\n"); |
90 | for (i = 0; i < NUM_APPLETS; i++) { | 90 | for (i = 0; i < NUM_APPLETS; i++) { |
91 | printf("\"%s\" \"\\0\"\n", applets[i].name); | 91 | printf("\"%s\" \"\\0\"\n", applets[i].name); |
92 | if (MAX_APPLET_NAME_LEN < strlen(applets[i].name)) | 92 | // if (MAX_APPLET_NAME_LEN < strlen(applets[i].name)) |
93 | MAX_APPLET_NAME_LEN = strlen(applets[i].name); | 93 | // MAX_APPLET_NAME_LEN = strlen(applets[i].name); |
94 | } | 94 | } |
95 | printf(";\n\n"); | 95 | printf(";\n\n"); |
96 | 96 | ||
@@ -130,8 +130,8 @@ int main(int argc, char **argv) | |||
130 | printf("};\n"); | 130 | printf("};\n"); |
131 | #endif | 131 | #endif |
132 | //printf("#endif /* SKIP_definitions */\n"); | 132 | //printf("#endif /* SKIP_definitions */\n"); |
133 | printf("\n"); | 133 | // printf("\n"); |
134 | printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); | 134 | // printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); |
135 | 135 | ||
136 | if (argv[2]) { | 136 | if (argv[2]) { |
137 | char line_old[80]; | 137 | char line_old[80]; |
diff --git a/applets/usage_compressed b/applets/usage_compressed index af66bc5dc..fb6e1c286 100755 --- a/applets/usage_compressed +++ b/applets/usage_compressed | |||
@@ -10,20 +10,20 @@ test "$SED" || SED=sed | |||
10 | test "$DD" || DD=dd | 10 | test "$DD" || DD=dd |
11 | 11 | ||
12 | # Some people were bitten by their system lacking a (proper) od | 12 | # Some people were bitten by their system lacking a (proper) od |
13 | od -v -t x1 </dev/null >/dev/null | 13 | od -v -b </dev/null >/dev/null |
14 | if test $? != 0; then | 14 | if test $? != 0; then |
15 | echo 'od tool is not installed or cannot accept "-v -t x1" options' | 15 | echo 'od tool is not installed or cannot accept "-v -b" options' |
16 | exit 1 | 16 | exit 1 |
17 | fi | 17 | fi |
18 | 18 | ||
19 | exec >"$target.$$" | 19 | exec >"$target.$$" |
20 | 20 | ||
21 | echo '#define UNPACKED_USAGE "" \' | 21 | echo '#define UNPACKED_USAGE "" \' |
22 | "$loc/usage" | od -v -t x1 \ | 22 | "$loc/usage" | od -v -b \ |
23 | | $SED -e 's/^[^ ]*//' \ | 23 | | $SED -e 's/^[^ ]*//' \ |
24 | -e 's/ //g' \ | 24 | -e 's/ //g' \ |
25 | -e '/^$/d' \ | 25 | -e '/^$/d' \ |
26 | -e 's/\(..\)/\\x\1/g' \ | 26 | -e 's/\(...\)/\\\1/g' \ |
27 | -e 's/^/"/' \ | 27 | -e 's/^/"/' \ |
28 | -e 's/$/" \\/' | 28 | -e 's/$/" \\/' |
29 | echo '' | 29 | echo '' |
@@ -39,11 +39,11 @@ echo '#define PACKED_USAGE \' | |||
39 | ## -e '/^$/d' \ | 39 | ## -e '/^$/d' \ |
40 | ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' | 40 | ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' |
41 | ## -e 's/$/ \\/' | 41 | ## -e 's/$/ \\/' |
42 | "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -t x1 \ | 42 | "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ |
43 | | $SED -e 's/^[^ ]*//' \ | 43 | | $SED -e 's/^[^ ]*//' \ |
44 | -e 's/ //g' \ | 44 | -e 's/ //g' \ |
45 | -e '/^$/d' \ | 45 | -e '/^$/d' \ |
46 | -e 's/\(..\)/0x\1,/g' \ | 46 | -e 's/\(...\)/0\1,/g' \ |
47 | -e 's/$/ \\/' | 47 | -e 's/$/ \\/' |
48 | echo '' | 48 | echo '' |
49 | 49 | ||
diff --git a/archival/Config.src b/archival/Config.src index 13c33c795..76635ba78 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -5,8 +5,6 @@ | |||
5 | 5 | ||
6 | menu "Archival Utilities" | 6 | menu "Archival Utilities" |
7 | 7 | ||
8 | INSERT | ||
9 | |||
10 | config FEATURE_SEAMLESS_XZ | 8 | config FEATURE_SEAMLESS_XZ |
11 | bool "Make tar, rpm, modprobe etc understand .xz data" | 9 | bool "Make tar, rpm, modprobe etc understand .xz data" |
12 | default y | 10 | default y |
@@ -37,353 +35,6 @@ config FEATURE_SEAMLESS_Z | |||
37 | help | 35 | help |
38 | Make tar, rpm, modprobe etc understand .Z data. | 36 | Make tar, rpm, modprobe etc understand .Z data. |
39 | 37 | ||
40 | config AR | 38 | INSERT |
41 | bool "ar" | ||
42 | default n # needs to be improved to be able to replace binutils ar | ||
43 | help | ||
44 | ar is an archival utility program used to create, modify, and | ||
45 | extract contents from archives. An archive is a single file holding | ||
46 | a collection of other files in a structure that makes it possible to | ||
47 | retrieve the original individual files (called archive members). | ||
48 | The original files' contents, mode (permissions), timestamp, owner, | ||
49 | and group are preserved in the archive, and can be restored on | ||
50 | extraction. | ||
51 | |||
52 | The stored filename is limited to 15 characters. (for more information | ||
53 | see long filename support). | ||
54 | ar has 60 bytes of overheads for every stored file. | ||
55 | |||
56 | This implementation of ar can extract archives, it cannot create or | ||
57 | modify them. | ||
58 | On an x86 system, the ar applet adds about 1K. | ||
59 | |||
60 | Unless you have a specific application which requires ar, you should | ||
61 | probably say N here. | ||
62 | |||
63 | config FEATURE_AR_LONG_FILENAMES | ||
64 | bool "Support for long filenames (not needed for debs)" | ||
65 | default y | ||
66 | depends on AR | ||
67 | help | ||
68 | By default the ar format can only store the first 15 characters | ||
69 | of the filename, this option removes that limitation. | ||
70 | It supports the GNU ar long filename method which moves multiple long | ||
71 | filenames into a the data section of a new ar entry. | ||
72 | |||
73 | config FEATURE_AR_CREATE | ||
74 | bool "Support archive creation" | ||
75 | default y | ||
76 | depends on AR | ||
77 | help | ||
78 | This enables archive creation (-c and -r) with busybox ar. | ||
79 | |||
80 | config BUNZIP2 | ||
81 | bool "bunzip2" | ||
82 | default y | ||
83 | help | ||
84 | bunzip2 is a compression utility using the Burrows-Wheeler block | ||
85 | sorting text compression algorithm, and Huffman coding. Compression | ||
86 | is generally considerably better than that achieved by more | ||
87 | conventional LZ77/LZ78-based compressors, and approaches the | ||
88 | performance of the PPM family of statistical compressors. | ||
89 | |||
90 | Unless you have a specific application which requires bunzip2, you | ||
91 | should probably say N here. | ||
92 | |||
93 | config BZIP2 | ||
94 | bool "bzip2" | ||
95 | default y | ||
96 | help | ||
97 | bzip2 is a compression utility using the Burrows-Wheeler block | ||
98 | sorting text compression algorithm, and Huffman coding. Compression | ||
99 | is generally considerably better than that achieved by more | ||
100 | conventional LZ77/LZ78-based compressors, and approaches the | ||
101 | performance of the PPM family of statistical compressors. | ||
102 | |||
103 | Unless you have a specific application which requires bzip2, you | ||
104 | should probably say N here. | ||
105 | |||
106 | config CPIO | ||
107 | bool "cpio" | ||
108 | default y | ||
109 | help | ||
110 | cpio is an archival utility program used to create, modify, and | ||
111 | extract contents from archives. | ||
112 | cpio has 110 bytes of overheads for every stored file. | ||
113 | |||
114 | This implementation of cpio can extract cpio archives created in the | ||
115 | "newc" or "crc" format, it cannot create or modify them. | ||
116 | |||
117 | Unless you have a specific application which requires cpio, you | ||
118 | should probably say N here. | ||
119 | |||
120 | config FEATURE_CPIO_O | ||
121 | bool "Support for archive creation" | ||
122 | default y | ||
123 | depends on CPIO | ||
124 | help | ||
125 | This implementation of cpio can create cpio archives in the "newc" | ||
126 | format only. | ||
127 | |||
128 | config FEATURE_CPIO_P | ||
129 | bool "Support for passthrough mode" | ||
130 | default y | ||
131 | depends on FEATURE_CPIO_O | ||
132 | help | ||
133 | Passthrough mode. Rarely used. | ||
134 | |||
135 | config DPKG | ||
136 | bool "dpkg" | ||
137 | default n | ||
138 | select FEATURE_SEAMLESS_GZ | ||
139 | help | ||
140 | dpkg is a medium-level tool to install, build, remove and manage | ||
141 | Debian packages. | ||
142 | |||
143 | This implementation of dpkg has a number of limitations, | ||
144 | you should use the official dpkg if possible. | ||
145 | |||
146 | config DPKG_DEB | ||
147 | bool "dpkg_deb" | ||
148 | default n | ||
149 | select FEATURE_SEAMLESS_GZ | ||
150 | help | ||
151 | dpkg-deb unpacks and provides information about Debian archives. | ||
152 | |||
153 | This implementation of dpkg-deb cannot pack archives. | ||
154 | |||
155 | Unless you have a specific application which requires dpkg-deb, | ||
156 | say N here. | ||
157 | |||
158 | config FEATURE_DPKG_DEB_EXTRACT_ONLY | ||
159 | bool "Extract only (-x)" | ||
160 | default n | ||
161 | depends on DPKG_DEB | ||
162 | help | ||
163 | This reduces dpkg-deb to the equivalent of | ||
164 | "ar -p <deb> data.tar.gz | tar -zx". However it saves space as none | ||
165 | of the extra dpkg-deb, ar or tar options are needed, they are linked | ||
166 | to internally. | ||
167 | |||
168 | config GUNZIP | ||
169 | bool "gunzip" | ||
170 | default y | ||
171 | help | ||
172 | gunzip is used to decompress archives created by gzip. | ||
173 | You can use the `-t' option to test the integrity of | ||
174 | an archive, without decompressing it. | ||
175 | |||
176 | config GZIP | ||
177 | bool "gzip" | ||
178 | default y | ||
179 | help | ||
180 | gzip is used to compress files. | ||
181 | It's probably the most widely used UNIX compression program. | ||
182 | |||
183 | config FEATURE_GZIP_LONG_OPTIONS | ||
184 | bool "Enable long options" | ||
185 | default y | ||
186 | depends on GZIP && LONG_OPTS | ||
187 | help | ||
188 | Enable use of long options, increases size by about 106 Bytes | ||
189 | |||
190 | config GZIP_FAST | ||
191 | int "Trade memory for gzip speed (0:small,slow - 2:fast,big)" | ||
192 | default 0 | ||
193 | range 0 2 | ||
194 | depends on GZIP | ||
195 | help | ||
196 | Enable big memory options for gzip. | ||
197 | 0: small buffers, small hash-tables | ||
198 | 1: larger buffers, larger hash-tables | ||
199 | 2: larger buffers, largest hash-tables | ||
200 | Larger models may give slightly better compression | ||
201 | |||
202 | config LZOP | ||
203 | bool "lzop" | ||
204 | default y | ||
205 | depends on PLATFORM_POSIX || WIN32_NET | ||
206 | help | ||
207 | Lzop compression/decompresion. | ||
208 | |||
209 | config LZOP_COMPR_HIGH | ||
210 | bool "lzop compression levels 7,8,9 (not very useful)" | ||
211 | default n | ||
212 | depends on LZOP | ||
213 | help | ||
214 | High levels (7,8,9) of lzop compression. These levels | ||
215 | are actually slower than gzip at equivalent compression ratios | ||
216 | and take up 3.2K of code. | ||
217 | |||
218 | config RPM2CPIO | ||
219 | bool "rpm2cpio" | ||
220 | default y | ||
221 | help | ||
222 | Converts a RPM file into a CPIO archive. | ||
223 | |||
224 | config RPM | ||
225 | bool "rpm" | ||
226 | default y | ||
227 | help | ||
228 | Mini RPM applet - queries and extracts RPM packages. | ||
229 | |||
230 | config TAR | ||
231 | bool "tar" | ||
232 | default y | ||
233 | help | ||
234 | tar is an archiving program. It's commonly used with gzip to | ||
235 | create compressed archives. It's probably the most widely used | ||
236 | UNIX archive program. | ||
237 | |||
238 | config FEATURE_TAR_CREATE | ||
239 | bool "Enable archive creation" | ||
240 | default y | ||
241 | depends on TAR | ||
242 | help | ||
243 | If you enable this option you'll be able to create | ||
244 | tar archives using the `-c' option. | ||
245 | |||
246 | config FEATURE_TAR_AUTODETECT | ||
247 | bool "Autodetect compressed tarballs" | ||
248 | default y | ||
249 | depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ) | ||
250 | help | ||
251 | With this option tar can automatically detect compressed | ||
252 | tarballs. Currently it works only on files (not pipes etc). | ||
253 | |||
254 | config FEATURE_TAR_FROM | ||
255 | bool "Enable -X (exclude from) and -T (include from) options)" | ||
256 | default y | ||
257 | depends on TAR | ||
258 | help | ||
259 | If you enable this option you'll be able to specify | ||
260 | a list of files to include or exclude from an archive. | ||
261 | |||
262 | config FEATURE_TAR_OLDGNU_COMPATIBILITY | ||
263 | bool "Support for old tar header format" | ||
264 | default y | ||
265 | depends on TAR || DPKG | ||
266 | help | ||
267 | This option is required to unpack archives created in | ||
268 | the old GNU format; help to kill this old format by | ||
269 | repacking your ancient archives with the new format. | ||
270 | |||
271 | config FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
272 | bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" | ||
273 | default y | ||
274 | depends on TAR || DPKG | ||
275 | help | ||
276 | This option is required to unpack archives created by some old | ||
277 | version of Sun's tar (it was calculating checksum using signed | ||
278 | arithmetic). It is said to be fixed in newer Sun tar, but "old" | ||
279 | tarballs still exist. | ||
280 | |||
281 | config FEATURE_TAR_GNU_EXTENSIONS | ||
282 | bool "Support for GNU tar extensions (long filenames)" | ||
283 | default y | ||
284 | depends on TAR || DPKG | ||
285 | help | ||
286 | With this option busybox supports GNU long filenames and | ||
287 | linknames. | ||
288 | |||
289 | config FEATURE_TAR_LONG_OPTIONS | ||
290 | bool "Enable long options" | ||
291 | default y | ||
292 | depends on TAR && LONG_OPTS | ||
293 | help | ||
294 | Enable use of long options, increases size by about 400 Bytes | ||
295 | |||
296 | config FEATURE_TAR_TO_COMMAND | ||
297 | bool "Support for writing to an external program" | ||
298 | default y | ||
299 | depends on TAR && FEATURE_TAR_LONG_OPTIONS | ||
300 | help | ||
301 | If you enable this option you'll be able to instruct tar to send | ||
302 | the contents of each extracted file to the standard input of an | ||
303 | external program. | ||
304 | |||
305 | config FEATURE_TAR_UNAME_GNAME | ||
306 | bool "Enable use of user and group names" | ||
307 | default y | ||
308 | depends on TAR | ||
309 | help | ||
310 | Enables use of user and group names in tar. This affects contents | ||
311 | listings (-t) and preserving permissions when unpacking (-p). | ||
312 | +200 bytes. | ||
313 | |||
314 | config FEATURE_TAR_NOPRESERVE_TIME | ||
315 | bool "Enable -m (do not preserve time) option" | ||
316 | default y | ||
317 | depends on TAR | ||
318 | help | ||
319 | With this option busybox supports GNU tar -m | ||
320 | (do not preserve time) option. | ||
321 | |||
322 | config FEATURE_TAR_SELINUX | ||
323 | bool "Support for extracting SELinux labels" | ||
324 | default n | ||
325 | depends on TAR && SELINUX | ||
326 | help | ||
327 | With this option busybox supports restoring SELinux labels | ||
328 | when extracting files from tar archives. | ||
329 | |||
330 | config UNCOMPRESS | ||
331 | bool "uncompress" | ||
332 | default n | ||
333 | help | ||
334 | uncompress is used to decompress archives created by compress. | ||
335 | Not much used anymore, replaced by gzip/gunzip. | ||
336 | |||
337 | config UNLZMA | ||
338 | bool "unlzma" | ||
339 | default y | ||
340 | help | ||
341 | unlzma is a compression utility using the Lempel-Ziv-Markov chain | ||
342 | compression algorithm, and range coding. Compression | ||
343 | is generally considerably better than that achieved by the bzip2 | ||
344 | compressors. | ||
345 | |||
346 | The BusyBox unlzma applet is limited to decompression only. | ||
347 | On an x86 system, this applet adds about 4K. | ||
348 | |||
349 | config FEATURE_LZMA_FAST | ||
350 | bool "Optimize unlzma for speed" | ||
351 | default n | ||
352 | depends on UNLZMA | ||
353 | help | ||
354 | This option reduces decompression time by about 25% at the cost of | ||
355 | a 1K bigger binary. | ||
356 | |||
357 | config LZMA | ||
358 | bool "Provide lzma alias which supports only unpacking" | ||
359 | default y | ||
360 | depends on UNLZMA | ||
361 | help | ||
362 | Enable this option if you want commands like "lzma -d" to work. | ||
363 | IOW: you'll get lzma applet, but it will always require -d option. | ||
364 | |||
365 | config UNXZ | ||
366 | bool "unxz" | ||
367 | default y | ||
368 | help | ||
369 | unxz is a unlzma successor. | ||
370 | |||
371 | config XZ | ||
372 | bool "Provide xz alias which supports only unpacking" | ||
373 | default y | ||
374 | depends on UNXZ | ||
375 | help | ||
376 | Enable this option if you want commands like "xz -d" to work. | ||
377 | IOW: you'll get xz applet, but it will always require -d option. | ||
378 | |||
379 | config UNZIP | ||
380 | bool "unzip" | ||
381 | default y | ||
382 | help | ||
383 | unzip will list or extract files from a ZIP archive, | ||
384 | commonly found on DOS/WIN systems. The default behavior | ||
385 | (with no options) is to extract the archive into the | ||
386 | current directory. Use the `-d' option to extract to a | ||
387 | directory of your choice. | ||
388 | 39 | ||
389 | endmenu | 40 | endmenu |
diff --git a/archival/Kbuild.src b/archival/Kbuild.src index 3466452f7..a6fd2eac0 100644 --- a/archival/Kbuild.src +++ b/archival/Kbuild.src | |||
@@ -9,22 +9,3 @@ libs-y += libarchive/ | |||
9 | lib-y:= | 9 | lib-y:= |
10 | 10 | ||
11 | INSERT | 11 | INSERT |
12 | |||
13 | lib-$(CONFIG_AR) += ar.o | ||
14 | lib-$(CONFIG_CPIO) += cpio.o | ||
15 | lib-$(CONFIG_DPKG) += dpkg.o | ||
16 | lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o | ||
17 | lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o | ||
18 | lib-$(CONFIG_RPM) += rpm.o | ||
19 | lib-$(CONFIG_TAR) += tar.o | ||
20 | lib-$(CONFIG_UNZIP) += unzip.o | ||
21 | |||
22 | lib-$(CONFIG_LZOP) += lzop.o bbunzip.o | ||
23 | lib-$(CONFIG_GZIP) += gzip.o bbunzip.o | ||
24 | lib-$(CONFIG_BZIP2) += bzip2.o bbunzip.o | ||
25 | |||
26 | lib-$(CONFIG_UNXZ) += bbunzip.o | ||
27 | lib-$(CONFIG_UNLZMA) += bbunzip.o | ||
28 | lib-$(CONFIG_BUNZIP2) += bbunzip.o | ||
29 | lib-$(CONFIG_GUNZIP) += bbunzip.o | ||
30 | lib-$(CONFIG_UNCOMPRESS) += bbunzip.o | ||
diff --git a/archival/ar.c b/archival/ar.c index 88236e878..f86c52d9b 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -17,6 +17,49 @@ | |||
17 | * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html | 17 | * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html |
18 | */ | 18 | */ |
19 | 19 | ||
20 | //config:config AR | ||
21 | //config: bool "ar" | ||
22 | //config: default n # needs to be improved to be able to replace binutils ar | ||
23 | //config: help | ||
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 | ||
26 | //config: a collection of other files in a structure that makes it possible to | ||
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: | ||
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. | ||
39 | //config: | ||
40 | //config: Unless you have a specific application which requires ar, you should | ||
41 | //config: probably say N here. | ||
42 | //config: | ||
43 | //config:config FEATURE_AR_LONG_FILENAMES | ||
44 | //config: bool "Support for long filenames (not needed for debs)" | ||
45 | //config: default y | ||
46 | //config: depends on AR | ||
47 | //config: help | ||
48 | //config: By default the ar format can only store the first 15 characters | ||
49 | //config: of the filename, this option removes that limitation. | ||
50 | //config: It supports the GNU ar long filename method which moves multiple long | ||
51 | //config: filenames into a the data section of a new ar entry. | ||
52 | //config: | ||
53 | //config:config FEATURE_AR_CREATE | ||
54 | //config: bool "Support archive creation" | ||
55 | //config: default y | ||
56 | //config: depends on AR | ||
57 | //config: help | ||
58 | //config: This enables archive creation (-c and -r) with busybox ar. | ||
59 | |||
60 | //applet:IF_AR(APPLET(ar, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
61 | //kbuild:lib-$(CONFIG_AR) += ar.o | ||
62 | |||
20 | //usage:#define ar_trivial_usage | 63 | //usage:#define ar_trivial_usage |
21 | //usage: "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES" | 64 | //usage: "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES" |
22 | //usage:#define ar_full_usage "\n\n" | 65 | //usage:#define ar_full_usage "\n\n" |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 9d1cd9485..3de8e1d48 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -7,6 +7,9 @@ | |||
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | #include "bb_archive.h" | 8 | #include "bb_archive.h" |
9 | 9 | ||
10 | /* lzop_main() uses bbunpack(), need this: */ | ||
11 | //kbuild:lib-$(CONFIG_LZOP) += bbunzip.o | ||
12 | |||
10 | /* Note: must be kept in sync with archival/lzop.c */ | 13 | /* Note: must be kept in sync with archival/lzop.c */ |
11 | enum { | 14 | enum { |
12 | OPT_STDOUT = 1 << 0, | 15 | OPT_STDOUT = 1 << 0, |
@@ -207,7 +210,6 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
207 | * | 210 | * |
208 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 211 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
209 | */ | 212 | */ |
210 | |||
211 | //usage:#define uncompress_trivial_usage | 213 | //usage:#define uncompress_trivial_usage |
212 | //usage: "[-cf] [FILE]..." | 214 | //usage: "[-cf] [FILE]..." |
213 | //usage:#define uncompress_full_usage "\n\n" | 215 | //usage:#define uncompress_full_usage "\n\n" |
@@ -215,6 +217,15 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
215 | //usage: "\n -c Write to stdout" | 217 | //usage: "\n -c Write to stdout" |
216 | //usage: "\n -f Overwrite" | 218 | //usage: "\n -f Overwrite" |
217 | 219 | ||
220 | //config:config UNCOMPRESS | ||
221 | //config: bool "uncompress" | ||
222 | //config: default n | ||
223 | //config: help | ||
224 | //config: uncompress is used to decompress archives created by compress. | ||
225 | //config: Not much used anymore, replaced by gzip/gunzip. | ||
226 | |||
227 | //applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP)) | ||
228 | //kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o | ||
218 | #if ENABLE_UNCOMPRESS | 229 | #if ENABLE_UNCOMPRESS |
219 | static | 230 | static |
220 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) | 231 | IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) |
@@ -255,11 +266,7 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
255 | * Portions of the lzw code are derived from the public domain 'compress' | 266 | * Portions of the lzw code are derived from the public domain 'compress' |
256 | * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, | 267 | * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, |
257 | * Ken Turkowski, Dave Mack and Peter Jannesen. | 268 | * Ken Turkowski, Dave Mack and Peter Jannesen. |
258 | * | ||
259 | * See the license_msg below and the file COPYING for the software license. | ||
260 | * See the file algorithm.doc for the compression algorithms and file formats. | ||
261 | */ | 269 | */ |
262 | |||
263 | //usage:#define gunzip_trivial_usage | 270 | //usage:#define gunzip_trivial_usage |
264 | //usage: "[-cft] [FILE]..." | 271 | //usage: "[-cft] [FILE]..." |
265 | //usage:#define gunzip_full_usage "\n\n" | 272 | //usage:#define gunzip_full_usage "\n\n" |
@@ -280,6 +287,18 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
280 | //usage:#define zcat_full_usage "\n\n" | 287 | //usage:#define zcat_full_usage "\n\n" |
281 | //usage: "Decompress to stdout" | 288 | //usage: "Decompress to stdout" |
282 | 289 | ||
290 | //config:config GUNZIP | ||
291 | //config: bool "gunzip" | ||
292 | //config: default y | ||
293 | //config: help | ||
294 | //config: gunzip is used to decompress archives created by gzip. | ||
295 | //config: You can use the `-t' option to test the integrity of | ||
296 | //config: an archive, without decompressing it. | ||
297 | |||
298 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) | ||
299 | //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) | ||
300 | //kbuild:lib-$(CONFIG_GZIP) += bbunzip.o | ||
301 | //kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o | ||
283 | #if ENABLE_GUNZIP | 302 | #if ENABLE_GUNZIP |
284 | static | 303 | static |
285 | char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) | 304 | char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) |
@@ -358,8 +377,24 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
358 | //usage: "[FILE]..." | 377 | //usage: "[FILE]..." |
359 | //usage:#define bzcat_full_usage "\n\n" | 378 | //usage:#define bzcat_full_usage "\n\n" |
360 | //usage: "Decompress to stdout" | 379 | //usage: "Decompress to stdout" |
380 | |||
381 | //config:config BUNZIP2 | ||
382 | //config: bool "bunzip2" | ||
383 | //config: default y | ||
384 | //config: help | ||
385 | //config: bunzip2 is a compression utility using the Burrows-Wheeler block | ||
386 | //config: sorting text compression algorithm, and Huffman coding. Compression | ||
387 | //config: is generally considerably better than that achieved by more | ||
388 | //config: conventional LZ77/LZ78-based compressors, and approaches the | ||
389 | //config: performance of the PPM family of statistical compressors. | ||
390 | //config: | ||
391 | //config: Unless you have a specific application which requires bunzip2, you | ||
392 | //config: should probably say N here. | ||
393 | |||
361 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | 394 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) |
362 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | 395 | //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) |
396 | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o | ||
397 | //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o | ||
363 | #if ENABLE_BUNZIP2 | 398 | #if ENABLE_BUNZIP2 |
364 | static | 399 | static |
365 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) | 400 | IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) |
@@ -387,7 +422,6 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
387 | * | 422 | * |
388 | * Licensed under GPLv2, see file LICENSE in this source tree. | 423 | * Licensed under GPLv2, see file LICENSE in this source tree. |
389 | */ | 424 | */ |
390 | |||
391 | //usage:#define unlzma_trivial_usage | 425 | //usage:#define unlzma_trivial_usage |
392 | //usage: "[-cf] [FILE]..." | 426 | //usage: "[-cf] [FILE]..." |
393 | //usage:#define unlzma_full_usage "\n\n" | 427 | //usage:#define unlzma_full_usage "\n\n" |
@@ -428,6 +462,38 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
428 | //usage:#define xzcat_full_usage "\n\n" | 462 | //usage:#define xzcat_full_usage "\n\n" |
429 | //usage: "Decompress to stdout" | 463 | //usage: "Decompress to stdout" |
430 | 464 | ||
465 | //config:config UNLZMA | ||
466 | //config: bool "unlzma" | ||
467 | //config: default y | ||
468 | //config: help | ||
469 | //config: unlzma is a compression utility using the Lempel-Ziv-Markov chain | ||
470 | //config: compression algorithm, and range coding. Compression | ||
471 | //config: is generally considerably better than that achieved by the bzip2 | ||
472 | //config: compressors. | ||
473 | //config: | ||
474 | //config: The BusyBox unlzma applet is limited to decompression only. | ||
475 | //config: On an x86 system, this applet adds about 4K. | ||
476 | //config: | ||
477 | //config:config FEATURE_LZMA_FAST | ||
478 | //config: bool "Optimize unlzma for speed" | ||
479 | //config: default n | ||
480 | //config: depends on UNLZMA | ||
481 | //config: help | ||
482 | //config: This option reduces decompression time by about 25% at the cost of | ||
483 | //config: a 1K bigger binary. | ||
484 | //config: | ||
485 | //config:config LZMA | ||
486 | //config: bool "Provide lzma alias which supports only unpacking" | ||
487 | //config: default y | ||
488 | //config: depends on UNLZMA | ||
489 | //config: help | ||
490 | //config: Enable this option if you want commands like "lzma -d" to work. | ||
491 | //config: IOW: you'll get lzma applet, but it will always require -d option. | ||
492 | |||
493 | //applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
494 | //applet:IF_UNLZMA(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) | ||
495 | //applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) | ||
496 | //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o | ||
431 | #if ENABLE_UNLZMA | 497 | #if ENABLE_UNLZMA |
432 | static | 498 | static |
433 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) | 499 | IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) |
@@ -453,6 +519,24 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
453 | #endif | 519 | #endif |
454 | 520 | ||
455 | 521 | ||
522 | //config:config UNXZ | ||
523 | //config: bool "unxz" | ||
524 | //config: default y | ||
525 | //config: help | ||
526 | //config: unxz is a unlzma successor. | ||
527 | //config: | ||
528 | //config:config XZ | ||
529 | //config: bool "Provide xz alias which supports only unpacking" | ||
530 | //config: default y | ||
531 | //config: depends on UNXZ | ||
532 | //config: help | ||
533 | //config: Enable this option if you want commands like "xz -d" to work. | ||
534 | //config: IOW: you'll get xz applet, but it will always require -d option. | ||
535 | |||
536 | //applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
537 | //applet:IF_UNXZ(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) | ||
538 | //applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) | ||
539 | //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o | ||
456 | #if ENABLE_UNXZ | 540 | #if ENABLE_UNXZ |
457 | static | 541 | static |
458 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) | 542 | IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) |
diff --git a/archival/bzip2.c b/archival/bzip2.c index dd77c8efc..f7718b411 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -7,6 +7,22 @@ | |||
7 | * about bzip2 library code. | 7 | * about bzip2 library code. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | //config:config BZIP2 | ||
11 | //config: bool "bzip2" | ||
12 | //config: default y | ||
13 | //config: help | ||
14 | //config: bzip2 is a compression utility using the Burrows-Wheeler block | ||
15 | //config: sorting text compression algorithm, and Huffman coding. Compression | ||
16 | //config: is generally considerably better than that achieved by more | ||
17 | //config: conventional LZ77/LZ78-based compressors, and approaches the | ||
18 | //config: performance of the PPM family of statistical compressors. | ||
19 | //config: | ||
20 | //config: Unless you have a specific application which requires bzip2, you | ||
21 | //config: should probably say N here. | ||
22 | |||
23 | //applet:IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
24 | //kbuild:lib-$(CONFIG_BZIP2) += bzip2.o | ||
25 | |||
10 | //usage:#define bzip2_trivial_usage | 26 | //usage:#define bzip2_trivial_usage |
11 | //usage: "[OPTIONS] [FILE]..." | 27 | //usage: "[OPTIONS] [FILE]..." |
12 | //usage:#define bzip2_full_usage "\n\n" | 28 | //usage:#define bzip2_full_usage "\n\n" |
diff --git a/archival/cpio.c b/archival/cpio.c index 699c6dbb7..1cce7c8b4 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -9,11 +9,42 @@ | |||
9 | * Limitations: | 9 | * Limitations: |
10 | * Doesn't check CRC's | 10 | * Doesn't check CRC's |
11 | * Only supports new ASCII and CRC formats | 11 | * Only supports new ASCII and CRC formats |
12 | * | ||
13 | */ | 12 | */ |
14 | #include "libbb.h" | 13 | #include "libbb.h" |
15 | #include "bb_archive.h" | 14 | #include "bb_archive.h" |
16 | 15 | ||
16 | //config:config CPIO | ||
17 | //config: bool "cpio" | ||
18 | //config: default y | ||
19 | //config: help | ||
20 | //config: cpio is an archival utility program used to create, modify, and | ||
21 | //config: extract contents from archives. | ||
22 | //config: cpio has 110 bytes of overheads for every stored file. | ||
23 | //config: | ||
24 | //config: This implementation of cpio can extract cpio archives created in the | ||
25 | //config: "newc" or "crc" format, it cannot create or modify them. | ||
26 | //config: | ||
27 | //config: Unless you have a specific application which requires cpio, you | ||
28 | //config: should probably say N here. | ||
29 | //config: | ||
30 | //config:config FEATURE_CPIO_O | ||
31 | //config: bool "Support for archive creation" | ||
32 | //config: default y | ||
33 | //config: depends on CPIO | ||
34 | //config: help | ||
35 | //config: This implementation of cpio can create cpio archives in the "newc" | ||
36 | //config: format only. | ||
37 | //config: | ||
38 | //config:config FEATURE_CPIO_P | ||
39 | //config: bool "Support for passthrough mode" | ||
40 | //config: default y | ||
41 | //config: depends on FEATURE_CPIO_O | ||
42 | //config: help | ||
43 | //config: Passthrough mode. Rarely used. | ||
44 | |||
45 | //applet:IF_CPIO(APPLET(cpio, BB_DIR_BIN, BB_SUID_DROP)) | ||
46 | //kbuild:lib-$(CONFIG_CPIO) += cpio.o | ||
47 | |||
17 | //usage:#define cpio_trivial_usage | 48 | //usage:#define cpio_trivial_usage |
18 | //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") | 49 | //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") |
19 | //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") | 50 | //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") |
diff --git a/archival/dpkg.c b/archival/dpkg.c index ed86f3355..2893cfc2d 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * | 14 | * |
15 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 15 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
16 | */ | 16 | */ |
17 | |||
18 | /* | 17 | /* |
19 | * known difference between busybox dpkg and the official dpkg that i don't | 18 | * known difference between busybox dpkg and the official dpkg that i don't |
20 | * consider important, its worth keeping a note of differences anyway, just to | 19 | * consider important, its worth keeping a note of differences anyway, just to |
@@ -25,9 +24,22 @@ | |||
25 | * | 24 | * |
26 | * bugs that need to be fixed | 25 | * bugs that need to be fixed |
27 | * - (unknown, please let me know when you find any) | 26 | * - (unknown, please let me know when you find any) |
28 | * | ||
29 | */ | 27 | */ |
30 | 28 | ||
29 | //config:config DPKG | ||
30 | //config: bool "dpkg" | ||
31 | //config: default n | ||
32 | //config: select FEATURE_SEAMLESS_GZ | ||
33 | //config: help | ||
34 | //config: dpkg is a medium-level tool to install, build, remove and manage | ||
35 | //config: Debian packages. | ||
36 | //config: | ||
37 | //config: This implementation of dpkg has a number of limitations, | ||
38 | //config: you should use the official dpkg if possible. | ||
39 | |||
40 | //applet:IF_DPKG(APPLET(dpkg, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
41 | //kbuild:lib-$(CONFIG_DPKG) += dpkg.o | ||
42 | |||
31 | //usage:#define dpkg_trivial_usage | 43 | //usage:#define dpkg_trivial_usage |
32 | //usage: "[-ilCPru] [-F OPT] PACKAGE" | 44 | //usage: "[-ilCPru] [-F OPT] PACKAGE" |
33 | //usage:#define dpkg_full_usage "\n\n" | 45 | //usage:#define dpkg_full_usage "\n\n" |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index a04ec9407..13f9db991 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
@@ -5,8 +5,33 @@ | |||
5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | //config:config DPKG_DEB | ||
9 | //config: bool "dpkg_deb" | ||
10 | //config: default n | ||
11 | //config: select FEATURE_SEAMLESS_GZ | ||
12 | //config: help | ||
13 | //config: dpkg-deb unpacks and provides information about Debian archives. | ||
14 | //config: | ||
15 | //config: This implementation of dpkg-deb cannot pack archives. | ||
16 | //config: | ||
17 | //config: Unless you have a specific application which requires dpkg-deb, | ||
18 | //config: say N here. | ||
19 | //config: | ||
20 | //config:config FEATURE_DPKG_DEB_EXTRACT_ONLY | ||
21 | //config: bool "Extract only (-x)" | ||
22 | //config: default n | ||
23 | //config: depends on DPKG_DEB | ||
24 | //config: help | ||
25 | //config: This reduces dpkg-deb to the equivalent of | ||
26 | //config: "ar -p <deb> data.tar.gz | tar -zx". However it saves space as none | ||
27 | //config: of the extra dpkg-deb, ar or tar options are needed, they are linked | ||
28 | //config: to internally. | ||
29 | |||
30 | //applet:IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb)) | ||
31 | //kbuild:lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o | ||
32 | |||
8 | //usage:#define dpkg_deb_trivial_usage | 33 | //usage:#define dpkg_deb_trivial_usage |
9 | //usage: "[-cefxX] FILE [argument" | 34 | //usage: "[-cefxX] FILE [argument]" |
10 | //usage:#define dpkg_deb_full_usage "\n\n" | 35 | //usage:#define dpkg_deb_full_usage "\n\n" |
11 | //usage: "Perform actions on Debian packages (.debs)\n" | 36 | //usage: "Perform actions on Debian packages (.debs)\n" |
12 | //usage: "\n -c List contents of filesystem tree" | 37 | //usage: "\n -c List contents of filesystem tree" |
diff --git a/archival/gzip.c b/archival/gzip.c index 31ccab3cd..1e779c9c3 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * | 15 | * |
16 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 16 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
17 | */ | 17 | */ |
18 | |||
19 | /* big objects in bss: | 18 | /* big objects in bss: |
20 | * 00000020 b bl_count | 19 | * 00000020 b bl_count |
21 | * 00000074 b base_length | 20 | * 00000074 b base_length |
@@ -31,7 +30,6 @@ | |||
31 | * 00000480 b static_ltree | 30 | * 00000480 b static_ltree |
32 | * 000008f4 b dyn_ltree | 31 | * 000008f4 b dyn_ltree |
33 | */ | 32 | */ |
34 | |||
35 | /* TODO: full support for -v for DESKTOP | 33 | /* TODO: full support for -v for DESKTOP |
36 | * "/usr/bin/gzip -v a bogus aa" should say: | 34 | * "/usr/bin/gzip -v a bogus aa" should say: |
37 | a: 85.1% -- replaced with a.gz | 35 | a: 85.1% -- replaced with a.gz |
@@ -39,6 +37,35 @@ gzip: bogus: No such file or directory | |||
39 | aa: 85.1% -- replaced with aa.gz | 37 | aa: 85.1% -- replaced with aa.gz |
40 | */ | 38 | */ |
41 | 39 | ||
40 | //config:config GZIP | ||
41 | //config: bool "gzip" | ||
42 | //config: default y | ||
43 | //config: help | ||
44 | //config: gzip is used to compress files. | ||
45 | //config: It's probably the most widely used UNIX compression program. | ||
46 | //config: | ||
47 | //config:config FEATURE_GZIP_LONG_OPTIONS | ||
48 | //config: bool "Enable long options" | ||
49 | //config: default y | ||
50 | //config: depends on GZIP && LONG_OPTS | ||
51 | //config: help | ||
52 | //config: Enable use of long options, increases size by about 106 Bytes | ||
53 | //config: | ||
54 | //config:config GZIP_FAST | ||
55 | //config: int "Trade memory for gzip speed (0:small,slow - 2:fast,big)" | ||
56 | //config: default 0 | ||
57 | //config: range 0 2 | ||
58 | //config: depends on GZIP | ||
59 | //config: help | ||
60 | //config: Enable big memory options for gzip. | ||
61 | //config: 0: small buffers, small hash-tables | ||
62 | //config: 1: larger buffers, larger hash-tables | ||
63 | //config: 2: larger buffers, largest hash-tables | ||
64 | //config: Larger models may give slightly better compression | ||
65 | |||
66 | //applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP)) | ||
67 | //kbuild:lib-$(CONFIG_GZIP) += gzip.o | ||
68 | |||
42 | //usage:#define gzip_trivial_usage | 69 | //usage:#define gzip_trivial_usage |
43 | //usage: "[-cfd] [FILE]..." | 70 | //usage: "[-cfd] [FILE]..." |
44 | //usage:#define gzip_full_usage "\n\n" | 71 | //usage:#define gzip_full_usage "\n\n" |
diff --git a/archival/libarchive/bz/compress.c b/archival/libarchive/bz/compress.c index e9f1afdaf..23de9d3f5 100644 --- a/archival/libarchive/bz/compress.c +++ b/archival/libarchive/bz/compress.c | |||
@@ -249,7 +249,7 @@ void generateMTFValues(EState* s) | |||
249 | static NOINLINE | 249 | static NOINLINE |
250 | void sendMTFValues(EState* s) | 250 | void sendMTFValues(EState* s) |
251 | { | 251 | { |
252 | int32_t v, t, i, j, gs, ge, totc, bt, bc, iter; | 252 | int32_t v, t, i, j, gs, ge, bt, bc, iter; |
253 | int32_t nSelectors, alphaSize, minLen, maxLen, selCtr; | 253 | int32_t nSelectors, alphaSize, minLen, maxLen, selCtr; |
254 | int32_t nGroups; | 254 | int32_t nGroups; |
255 | 255 | ||
@@ -345,7 +345,6 @@ void sendMTFValues(EState* s) | |||
345 | } | 345 | } |
346 | #endif | 346 | #endif |
347 | nSelectors = 0; | 347 | nSelectors = 0; |
348 | totc = 0; | ||
349 | gs = 0; | 348 | gs = 0; |
350 | while (1) { | 349 | while (1) { |
351 | /*--- Set group start & end marks. --*/ | 350 | /*--- Set group start & end marks. --*/ |
@@ -411,7 +410,6 @@ void sendMTFValues(EState* s) | |||
411 | bt = t; | 410 | bt = t; |
412 | } | 411 | } |
413 | } | 412 | } |
414 | totc += bc; | ||
415 | fave[bt]++; | 413 | fave[bt]++; |
416 | s->selector[nSelectors] = bt; | 414 | s->selector[nSelectors] = bt; |
417 | nSelectors++; | 415 | nSelectors++; |
@@ -501,14 +499,14 @@ void sendMTFValues(EState* s) | |||
501 | for (i = 0; i < 16; i++) { | 499 | for (i = 0; i < 16; i++) { |
502 | if (sizeof(long) <= 4) { | 500 | if (sizeof(long) <= 4) { |
503 | inUse16 = inUse16*2 + | 501 | inUse16 = inUse16*2 + |
504 | ((*(uint32_t*)&(s->inUse[i * 16 + 0]) | 502 | ((*(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 0]) |
505 | | *(uint32_t*)&(s->inUse[i * 16 + 4]) | 503 | | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 4]) |
506 | | *(uint32_t*)&(s->inUse[i * 16 + 8]) | 504 | | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 8]) |
507 | | *(uint32_t*)&(s->inUse[i * 16 + 12])) != 0); | 505 | | *(bb__aliased_uint32_t*)&(s->inUse[i * 16 + 12])) != 0); |
508 | } else { /* Our CPU can do better */ | 506 | } else { /* Our CPU can do better */ |
509 | inUse16 = inUse16*2 + | 507 | inUse16 = inUse16*2 + |
510 | ((*(uint64_t*)&(s->inUse[i * 16 + 0]) | 508 | ((*(bb__aliased_uint64_t*)&(s->inUse[i * 16 + 0]) |
511 | | *(uint64_t*)&(s->inUse[i * 16 + 8])) != 0); | 509 | | *(bb__aliased_uint64_t*)&(s->inUse[i * 16 + 8])) != 0); |
512 | } | 510 | } |
513 | } | 511 | } |
514 | 512 | ||
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index dc252bb82..6396fe40d 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -42,6 +42,12 @@ | |||
42 | #include "libbb.h" | 42 | #include "libbb.h" |
43 | #include "bb_archive.h" | 43 | #include "bb_archive.h" |
44 | 44 | ||
45 | #if 0 | ||
46 | # define dbg(...) bb_error_msg(__VA_ARGS__) | ||
47 | #else | ||
48 | # define dbg(...) ((void)0) | ||
49 | #endif | ||
50 | |||
45 | /* Constants for Huffman coding */ | 51 | /* Constants for Huffman coding */ |
46 | #define MAX_GROUPS 6 | 52 | #define MAX_GROUPS 6 |
47 | #define GROUP_SIZE 50 /* 64 would have been more efficient */ | 53 | #define GROUP_SIZE 50 /* 64 would have been more efficient */ |
@@ -52,13 +58,13 @@ | |||
52 | 58 | ||
53 | /* Status return values */ | 59 | /* Status return values */ |
54 | #define RETVAL_OK 0 | 60 | #define RETVAL_OK 0 |
55 | #define RETVAL_LAST_BLOCK (-1) | 61 | #define RETVAL_LAST_BLOCK (dbg("%d", __LINE__), -1) |
56 | #define RETVAL_NOT_BZIP_DATA (-2) | 62 | #define RETVAL_NOT_BZIP_DATA (dbg("%d", __LINE__), -2) |
57 | #define RETVAL_UNEXPECTED_INPUT_EOF (-3) | 63 | #define RETVAL_UNEXPECTED_INPUT_EOF (dbg("%d", __LINE__), -3) |
58 | #define RETVAL_SHORT_WRITE (-4) | 64 | #define RETVAL_SHORT_WRITE (dbg("%d", __LINE__), -4) |
59 | #define RETVAL_DATA_ERROR (-5) | 65 | #define RETVAL_DATA_ERROR (dbg("%d", __LINE__), -5) |
60 | #define RETVAL_OUT_OF_MEMORY (-6) | 66 | #define RETVAL_OUT_OF_MEMORY (dbg("%d", __LINE__), -6) |
61 | #define RETVAL_OBSOLETE_INPUT (-7) | 67 | #define RETVAL_OBSOLETE_INPUT (dbg("%d", __LINE__), -7) |
62 | 68 | ||
63 | /* Other housekeeping constants */ | 69 | /* Other housekeeping constants */ |
64 | #define IOBUF_SIZE 4096 | 70 | #define IOBUF_SIZE 4096 |
@@ -440,7 +446,11 @@ static int get_next_block(bunzip_data *bd) | |||
440 | literal used is the one at the head of the mtfSymbol array.) */ | 446 | literal used is the one at the head of the mtfSymbol array.) */ |
441 | if (runPos != 0) { | 447 | if (runPos != 0) { |
442 | uint8_t tmp_byte; | 448 | uint8_t tmp_byte; |
443 | if (dbufCount + runCnt >= dbufSize) return RETVAL_DATA_ERROR; | 449 | if (dbufCount + runCnt > dbufSize) { |
450 | dbg("dbufCount:%d+runCnt:%d %d > dbufSize:%d RETVAL_DATA_ERROR", | ||
451 | dbufCount, runCnt, dbufCount + runCnt, dbufSize); | ||
452 | return RETVAL_DATA_ERROR; | ||
453 | } | ||
444 | tmp_byte = symToByte[mtfSymbol[0]]; | 454 | tmp_byte = symToByte[mtfSymbol[0]]; |
445 | byteCount[tmp_byte] += runCnt; | 455 | byteCount[tmp_byte] += runCnt; |
446 | while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte; | 456 | while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte; |
@@ -808,7 +818,6 @@ static char *const bunzip_errors[] = { | |||
808 | /* Dumb little test thing, decompress stdin to stdout */ | 818 | /* Dumb little test thing, decompress stdin to stdout */ |
809 | int main(int argc, char **argv) | 819 | int main(int argc, char **argv) |
810 | { | 820 | { |
811 | int i; | ||
812 | char c; | 821 | char c; |
813 | 822 | ||
814 | int i = unpack_bz2_stream(0, 1); | 823 | int i = unpack_bz2_stream(0, 1); |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 4e6b138c3..7c6f38ec3 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -336,7 +336,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
336 | } | 336 | } |
337 | 337 | ||
338 | /* Find minimum and maximum length, bound *m by those */ | 338 | /* Find minimum and maximum length, bound *m by those */ |
339 | for (j = 1; (c[j] == 0) && (j <= BMAX); j++) | 339 | for (j = 1; (j <= BMAX) && (c[j] == 0); j++) |
340 | continue; | 340 | continue; |
341 | k = j; /* minimum code length */ | 341 | k = j; /* minimum code length */ |
342 | for (i = BMAX; (c[i] == 0) && i; i--) | 342 | for (i = BMAX; (c[i] == 0) && i; i--) |
diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c index 23c412496..c66bb3ee7 100644 --- a/archival/libarchive/get_header_ar.c +++ b/archival/libarchive/get_header_ar.c | |||
@@ -8,11 +8,19 @@ | |||
8 | #include "bb_archive.h" | 8 | #include "bb_archive.h" |
9 | #include "ar.h" | 9 | #include "ar.h" |
10 | 10 | ||
11 | static unsigned read_num(const char *str, int base) | 11 | /* WARNING: Clobbers str[len], so fields must be read in reverse order! */ |
12 | static unsigned read_num(char *str, int base, int len) | ||
12 | { | 13 | { |
14 | int err; | ||
15 | |||
16 | /* ar fields are fixed length text strings (padded with spaces). | ||
17 | * Ensure bb_strtou doesn't read past the field in case the full | ||
18 | * width is used. */ | ||
19 | str[len] = 0; | ||
20 | |||
13 | /* This code works because | 21 | /* This code works because |
14 | * on misformatted numbers bb_strtou returns all-ones */ | 22 | * on misformatted numbers bb_strtou returns all-ones */ |
15 | int err = bb_strtou(str, NULL, base); | 23 | err = bb_strtou(str, NULL, base); |
16 | if (err == -1) | 24 | if (err == -1) |
17 | bb_error_msg_and_die("invalid ar header"); | 25 | bb_error_msg_and_die("invalid ar header"); |
18 | return err; | 26 | return err; |
@@ -51,11 +59,13 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
51 | if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') | 59 | if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') |
52 | bb_error_msg_and_die("invalid ar header"); | 60 | bb_error_msg_and_die("invalid ar header"); |
53 | 61 | ||
54 | /* FIXME: more thorough routine would be in order here | 62 | /* |
55 | * (we have something like that in tar) | 63 | * Note that the fields MUST be read in reverse order as |
56 | * but for now we are lax. */ | 64 | * read_num() clobbers the next byte after the field! |
57 | ar.formatted.magic[0] = '\0'; /* else 4G-2 file will have size="4294967294`\n..." */ | 65 | * Order is: name, date, uid, gid, mode, size, magic. |
58 | typed->size = size = read_num(ar.formatted.size, 10); | 66 | */ |
67 | typed->size = size = read_num(ar.formatted.size, 10, | ||
68 | sizeof(ar.formatted.size)); | ||
59 | 69 | ||
60 | /* special filenames have '/' as the first character */ | 70 | /* special filenames have '/' as the first character */ |
61 | if (ar.formatted.name[0] == '/') { | 71 | if (ar.formatted.name[0] == '/') { |
@@ -87,10 +97,10 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
87 | * long filename pseudo file. Thus we decode the rest | 97 | * long filename pseudo file. Thus we decode the rest |
88 | * after dealing with long filename pseudo file. | 98 | * after dealing with long filename pseudo file. |
89 | */ | 99 | */ |
90 | typed->mode = read_num(ar.formatted.mode, 8); | 100 | typed->mode = read_num(ar.formatted.mode, 8, sizeof(ar.formatted.mode)); |
91 | typed->mtime = read_num(ar.formatted.date, 10); | 101 | typed->gid = read_num(ar.formatted.gid, 10, sizeof(ar.formatted.gid)); |
92 | typed->uid = read_num(ar.formatted.uid, 10); | 102 | typed->uid = read_num(ar.formatted.uid, 10, sizeof(ar.formatted.uid)); |
93 | typed->gid = read_num(ar.formatted.gid, 10); | 103 | typed->mtime = read_num(ar.formatted.date, 10, sizeof(ar.formatted.date)); |
94 | 104 | ||
95 | #if ENABLE_FEATURE_AR_LONG_FILENAMES | 105 | #if ENABLE_FEATURE_AR_LONG_FILENAMES |
96 | if (ar.formatted.name[0] == '/') { | 106 | if (ar.formatted.name[0] == '/') { |
@@ -98,7 +108,8 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
98 | 108 | ||
99 | /* The number after the '/' indicates the offset in the ar data section | 109 | /* The number after the '/' indicates the offset in the ar data section |
100 | * (saved in ar_long_names) that conatains the real filename */ | 110 | * (saved in ar_long_names) that conatains the real filename */ |
101 | long_offset = read_num(&ar.formatted.name[1], 10); | 111 | long_offset = read_num(&ar.formatted.name[1], 10, |
112 | sizeof(ar.formatted.name) - 1); | ||
102 | if (long_offset >= ar_long_name_size) { | 113 | if (long_offset >= ar_long_name_size) { |
103 | bb_error_msg_and_die("can't resolve long filename"); | 114 | bb_error_msg_and_die("can't resolve long filename"); |
104 | } | 115 | } |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index bc09756ba..32f842095 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -198,13 +198,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
198 | * the message and we don't check whether we indeed | 198 | * the message and we don't check whether we indeed |
199 | * saw zero block directly before this. */ | 199 | * saw zero block directly before this. */ |
200 | if (i == 0) { | 200 | if (i == 0) { |
201 | xfunc_error_retval = 0; | 201 | bb_error_msg("short read"); |
202 | short_read: | 202 | /* this merely signals end of archive, not exit(1): */ |
203 | bb_error_msg_and_die("short read"); | 203 | return EXIT_FAILURE; |
204 | } | 204 | } |
205 | if (i != 512) { | 205 | if (i != 512) { |
206 | IF_FEATURE_TAR_AUTODETECT(goto autodetect;) | 206 | IF_FEATURE_TAR_AUTODETECT(goto autodetect;) |
207 | goto short_read; | 207 | bb_error_msg_and_die("short read"); |
208 | } | 208 | } |
209 | 209 | ||
210 | #else | 210 | #else |
@@ -221,10 +221,10 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
221 | */ | 221 | */ |
222 | while (full_read(archive_handle->src_fd, &tar, 512) == 512) | 222 | while (full_read(archive_handle->src_fd, &tar, 512) == 512) |
223 | continue; | 223 | continue; |
224 | return EXIT_FAILURE; | 224 | return EXIT_FAILURE; /* "end of archive" */ |
225 | } | 225 | } |
226 | archive_handle->tar__end = 1; | 226 | archive_handle->tar__end = 1; |
227 | return EXIT_SUCCESS; | 227 | return EXIT_SUCCESS; /* "decoded one header" */ |
228 | } | 228 | } |
229 | archive_handle->tar__end = 0; | 229 | archive_handle->tar__end = 0; |
230 | 230 | ||
@@ -471,5 +471,5 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
471 | free(file_header->tar__uname); | 471 | free(file_header->tar__uname); |
472 | free(file_header->tar__gname); | 472 | free(file_header->tar__gname); |
473 | #endif | 473 | #endif |
474 | return EXIT_SUCCESS; | 474 | return EXIT_SUCCESS; /* "decoded one header" */ |
475 | } | 475 | } |
diff --git a/archival/libarchive/lzo1x_9x.c b/archival/libarchive/lzo1x_9x.c index 897132987..2b490ae83 100644 --- a/archival/libarchive/lzo1x_9x.c +++ b/archival/libarchive/lzo1x_9x.c | |||
@@ -94,7 +94,7 @@ typedef struct { | |||
94 | ( ((0x9f5f * ((((b[p]<<5)^b[p+1])<<5) ^ b[p+2])) >> 5) & (SWD_HSIZE-1) ) | 94 | ( ((0x9f5f * ((((b[p]<<5)^b[p+1])<<5) ^ b[p+2])) >> 5) & (SWD_HSIZE-1) ) |
95 | 95 | ||
96 | #if defined(LZO_UNALIGNED_OK_2) | 96 | #if defined(LZO_UNALIGNED_OK_2) |
97 | # define HEAD2(b,p) (* (uint16_t *) &(b[p])) | 97 | # define HEAD2(b,p) (* (bb__aliased_uint16_t *) &(b[p])) |
98 | #else | 98 | #else |
99 | # define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) | 99 | # define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) |
100 | #endif | 100 | #endif |
@@ -466,7 +466,6 @@ static int find_match(lzo1x_999_t *c, lzo_swd_p s, | |||
466 | } | 466 | } |
467 | 467 | ||
468 | s->m_len = 1; | 468 | s->m_len = 1; |
469 | s->m_len = 1; | ||
470 | #ifdef SWD_BEST_OFF | 469 | #ifdef SWD_BEST_OFF |
471 | if (s->use_best_off) | 470 | if (s->use_best_off) |
472 | memset(s->best_pos, 0, sizeof(s->best_pos)); | 471 | memset(s->best_pos, 0, sizeof(s->best_pos)); |
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 841e9dce9..c4e02f0f7 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -81,16 +81,17 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) | |||
81 | // FIXME: error check? | 81 | // FIXME: error check? |
82 | #if BB_MMU | 82 | #if BB_MMU |
83 | { | 83 | { |
84 | IF_DESKTOP(long long) int r; | ||
84 | transformer_aux_data_t aux; | 85 | transformer_aux_data_t aux; |
85 | init_transformer_aux_data(&aux); | 86 | init_transformer_aux_data(&aux); |
86 | aux.check_signature = check_signature; | 87 | aux.check_signature = check_signature; |
87 | transformer(&aux, fd, fd_pipe.wr); | 88 | r = transformer(&aux, fd, fd_pipe.wr); |
88 | if (ENABLE_FEATURE_CLEAN_UP) { | 89 | if (ENABLE_FEATURE_CLEAN_UP) { |
89 | close(fd_pipe.wr); /* send EOF */ | 90 | close(fd_pipe.wr); /* send EOF */ |
90 | close(fd); | 91 | close(fd); |
91 | } | 92 | } |
92 | /* must be _exit! bug was actually seen here */ | 93 | /* must be _exit! bug was actually seen here */ |
93 | _exit(EXIT_SUCCESS); | 94 | _exit(/*error if:*/ r < 0); |
94 | } | 95 | } |
95 | #else | 96 | #else |
96 | { | 97 | { |
diff --git a/archival/lzop.c b/archival/lzop.c index 9b42e5fd3..5062d9300 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -25,6 +25,26 @@ | |||
25 | "Minimalized" for busybox by Alain Knaff | 25 | "Minimalized" for busybox by Alain Knaff |
26 | */ | 26 | */ |
27 | 27 | ||
28 | //config:config LZOP | ||
29 | //config: bool "lzop" | ||
30 | //config: default y | ||
31 | //config: help | ||
32 | //config: Lzop compression/decompresion. | ||
33 | //config: | ||
34 | //config:config LZOP_COMPR_HIGH | ||
35 | //config: bool "lzop compression levels 7,8,9 (not very useful)" | ||
36 | //config: default n | ||
37 | //config: depends on LZOP | ||
38 | //config: help | ||
39 | //config: High levels (7,8,9) of lzop compression. These levels | ||
40 | //config: are actually slower than gzip at equivalent compression ratios | ||
41 | //config: and take up 3.2K of code. | ||
42 | |||
43 | //applet:IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP)) | ||
44 | //applet:IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) | ||
45 | //applet:IF_LZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) | ||
46 | //kbuild:lib-$(CONFIG_LZOP) += lzop.o | ||
47 | |||
28 | //usage:#define lzop_trivial_usage | 48 | //usage:#define lzop_trivial_usage |
29 | //usage: "[-cfvd123456789CF] [FILE]..." | 49 | //usage: "[-cfvd123456789CF] [FILE]..." |
30 | //usage:#define lzop_full_usage "\n\n" | 50 | //usage:#define lzop_full_usage "\n\n" |
diff --git a/archival/rpm.c b/archival/rpm.c index 86ba4dca4..885eddd64 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -7,6 +7,15 @@ | |||
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 | 9 | ||
10 | //config:config RPM | ||
11 | //config: bool "rpm" | ||
12 | //config: default y | ||
13 | //config: help | ||
14 | //config: Mini RPM applet - queries and extracts RPM packages. | ||
15 | |||
16 | //applet:IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP)) | ||
17 | //kbuild:lib-$(CONFIG_RPM) += rpm.o | ||
18 | |||
10 | //usage:#define rpm_trivial_usage | 19 | //usage:#define rpm_trivial_usage |
11 | //usage: "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm" | 20 | //usage: "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm" |
12 | //usage:#define rpm_full_usage "\n\n" | 21 | //usage:#define rpm_full_usage "\n\n" |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index f3dfa5159..61adde795 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -7,6 +7,15 @@ | |||
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 | 9 | ||
10 | //config:config RPM2CPIO | ||
11 | //config: bool "rpm2cpio" | ||
12 | //config: default y | ||
13 | //config: help | ||
14 | //config: Converts a RPM file into a CPIO archive. | ||
15 | |||
16 | //applet:IF_RPM2CPIO(APPLET(rpm2cpio, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
17 | //kbuild:lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o | ||
18 | |||
10 | //usage:#define rpm2cpio_trivial_usage | 19 | //usage:#define rpm2cpio_trivial_usage |
11 | //usage: "package.rpm" | 20 | //usage: "package.rpm" |
12 | //usage:#define rpm2cpio_full_usage "\n\n" | 21 | //usage:#define rpm2cpio_full_usage "\n\n" |
diff --git a/archival/tar.c b/archival/tar.c index 3129781d2..2909eca1b 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -22,7 +22,6 @@ | |||
22 | * | 22 | * |
23 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 23 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
24 | */ | 24 | */ |
25 | |||
26 | /* TODO: security with -C DESTDIR option can be enhanced. | 25 | /* TODO: security with -C DESTDIR option can be enhanced. |
27 | * Consider tar file created via: | 26 | * Consider tar file created via: |
28 | * $ tar cvf bug.tar anything.txt | 27 | * $ tar cvf bug.tar anything.txt |
@@ -42,6 +41,109 @@ | |||
42 | * This doesn't feel right, and IIRC GNU tar doesn't do that. | 41 | * This doesn't feel right, and IIRC GNU tar doesn't do that. |
43 | */ | 42 | */ |
44 | 43 | ||
44 | //config:config TAR | ||
45 | //config: bool "tar" | ||
46 | //config: default y | ||
47 | //config: help | ||
48 | //config: tar is an archiving program. It's commonly used with gzip to | ||
49 | //config: create compressed archives. It's probably the most widely used | ||
50 | //config: UNIX archive program. | ||
51 | //config: | ||
52 | //config:config FEATURE_TAR_CREATE | ||
53 | //config: bool "Enable archive creation" | ||
54 | //config: default y | ||
55 | //config: depends on TAR | ||
56 | //config: help | ||
57 | //config: If you enable this option you'll be able to create | ||
58 | //config: tar archives using the `-c' option. | ||
59 | //config: | ||
60 | //config:config FEATURE_TAR_AUTODETECT | ||
61 | //config: bool "Autodetect compressed tarballs" | ||
62 | //config: default y | ||
63 | //config: depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ) | ||
64 | //config: help | ||
65 | //config: With this option tar can automatically detect compressed | ||
66 | //config: tarballs. Currently it works only on files (not pipes etc). | ||
67 | //config: | ||
68 | //config:config FEATURE_TAR_FROM | ||
69 | //config: bool "Enable -X (exclude from) and -T (include from) options)" | ||
70 | //config: default y | ||
71 | //config: depends on TAR | ||
72 | //config: help | ||
73 | //config: If you enable this option you'll be able to specify | ||
74 | //config: a list of files to include or exclude from an archive. | ||
75 | //config: | ||
76 | //config:config FEATURE_TAR_OLDGNU_COMPATIBILITY | ||
77 | //config: bool "Support for old tar header format" | ||
78 | //config: default y | ||
79 | //config: depends on TAR || DPKG | ||
80 | //config: help | ||
81 | //config: This option is required to unpack archives created in | ||
82 | //config: the old GNU format; help to kill this old format by | ||
83 | //config: repacking your ancient archives with the new format. | ||
84 | //config: | ||
85 | //config:config FEATURE_TAR_OLDSUN_COMPATIBILITY | ||
86 | //config: bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" | ||
87 | //config: default y | ||
88 | //config: depends on TAR || DPKG | ||
89 | //config: help | ||
90 | //config: This option is required to unpack archives created by some old | ||
91 | //config: version of Sun's tar (it was calculating checksum using signed | ||
92 | //config: arithmetic). It is said to be fixed in newer Sun tar, but "old" | ||
93 | //config: tarballs still exist. | ||
94 | //config: | ||
95 | //config:config FEATURE_TAR_GNU_EXTENSIONS | ||
96 | //config: bool "Support for GNU tar extensions (long filenames)" | ||
97 | //config: default y | ||
98 | //config: depends on TAR || DPKG | ||
99 | //config: help | ||
100 | //config: With this option busybox supports GNU long filenames and | ||
101 | //config: linknames. | ||
102 | //config: | ||
103 | //config:config FEATURE_TAR_LONG_OPTIONS | ||
104 | //config: bool "Enable long options" | ||
105 | //config: default y | ||
106 | //config: depends on TAR && LONG_OPTS | ||
107 | //config: help | ||
108 | //config: Enable use of long options, increases size by about 400 Bytes | ||
109 | //config: | ||
110 | //config:config FEATURE_TAR_TO_COMMAND | ||
111 | //config: bool "Support for writing to an external program" | ||
112 | //config: default y | ||
113 | //config: depends on TAR && FEATURE_TAR_LONG_OPTIONS | ||
114 | //config: help | ||
115 | //config: If you enable this option you'll be able to instruct tar to send | ||
116 | //config: the contents of each extracted file to the standard input of an | ||
117 | //config: external program. | ||
118 | //config: | ||
119 | //config:config FEATURE_TAR_UNAME_GNAME | ||
120 | //config: bool "Enable use of user and group names" | ||
121 | //config: default y | ||
122 | //config: depends on TAR | ||
123 | //config: help | ||
124 | //config: Enables use of user and group names in tar. This affects contents | ||
125 | //config: listings (-t) and preserving permissions when unpacking (-p). | ||
126 | //config: +200 bytes. | ||
127 | //config: | ||
128 | //config:config FEATURE_TAR_NOPRESERVE_TIME | ||
129 | //config: bool "Enable -m (do not preserve time) option" | ||
130 | //config: default y | ||
131 | //config: depends on TAR | ||
132 | //config: help | ||
133 | //config: With this option busybox supports GNU tar -m | ||
134 | //config: (do not preserve time) option. | ||
135 | //config: | ||
136 | //config:config FEATURE_TAR_SELINUX | ||
137 | //config: bool "Support for extracting SELinux labels" | ||
138 | //config: default n | ||
139 | //config: depends on TAR && SELINUX | ||
140 | //config: help | ||
141 | //config: With this option busybox supports restoring SELinux labels | ||
142 | //config: when extracting files from tar archives. | ||
143 | |||
144 | //applet:IF_TAR(APPLET(tar, BB_DIR_BIN, BB_SUID_DROP)) | ||
145 | //kbuild:lib-$(CONFIG_TAR) += tar.o | ||
146 | |||
45 | #include <fnmatch.h> | 147 | #include <fnmatch.h> |
46 | #include "libbb.h" | 148 | #include "libbb.h" |
47 | #include "bb_archive.h" | 149 | #include "bb_archive.h" |
@@ -1096,8 +1198,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1096 | /*tar_handle->offset = 0; - already is */ | 1198 | /*tar_handle->offset = 0; - already is */ |
1097 | } | 1199 | } |
1098 | 1200 | ||
1201 | /* Zero processed headers (== empty file) is not a valid tarball. | ||
1202 | * We (ab)use bb_got_signal as exitcode here, | ||
1203 | * because check_errors_in_children() uses _it_ as error indicator. | ||
1204 | */ | ||
1205 | bb_got_signal = EXIT_FAILURE; | ||
1206 | |||
1099 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) | 1207 | while (get_header_tar(tar_handle) == EXIT_SUCCESS) |
1100 | continue; | 1208 | bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ |
1101 | 1209 | ||
1102 | /* Check that every file that should have been extracted was */ | 1210 | /* Check that every file that should have been extracted was */ |
1103 | while (tar_handle->accept) { | 1211 | while (tar_handle->accept) { |
@@ -1113,8 +1221,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1113 | close(tar_handle->src_fd); | 1221 | close(tar_handle->src_fd); |
1114 | 1222 | ||
1115 | if (SEAMLESS_COMPRESSION || OPT_COMPRESS) { | 1223 | if (SEAMLESS_COMPRESSION || OPT_COMPRESS) { |
1224 | /* Set bb_got_signal to 1 if a child died with !0 exitcode */ | ||
1116 | check_errors_in_children(0); | 1225 | check_errors_in_children(0); |
1117 | return bb_got_signal; | ||
1118 | } | 1226 | } |
1119 | return EXIT_SUCCESS; | 1227 | |
1228 | return bb_got_signal; | ||
1120 | } | 1229 | } |
diff --git a/archival/unzip.c b/archival/unzip.c index 673e5fe08..fcfc9a448 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -9,16 +9,27 @@ | |||
9 | * | 9 | * |
10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 10 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
11 | */ | 11 | */ |
12 | |||
13 | /* For reference see | 12 | /* For reference see |
14 | * http://www.pkware.com/company/standards/appnote/ | 13 | * http://www.pkware.com/company/standards/appnote/ |
15 | * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip | 14 | * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip |
16 | */ | 15 | * |
17 | 16 | * TODO | |
18 | /* TODO | ||
19 | * Zip64 + other methods | 17 | * Zip64 + other methods |
20 | */ | 18 | */ |
21 | 19 | ||
20 | //config:config UNZIP | ||
21 | //config: bool "unzip" | ||
22 | //config: default y | ||
23 | //config: help | ||
24 | //config: unzip will list or extract files from a ZIP archive, | ||
25 | //config: commonly found on DOS/WIN systems. The default behavior | ||
26 | //config: (with no options) is to extract the archive into the | ||
27 | //config: current directory. Use the `-d' option to extract to a | ||
28 | //config: directory of your choice. | ||
29 | |||
30 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
31 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | ||
32 | |||
22 | //usage:#define unzip_trivial_usage | 33 | //usage:#define unzip_trivial_usage |
23 | //usage: "[-lnopq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]" | 34 | //usage: "[-lnopq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]" |
24 | //usage:#define unzip_full_usage "\n\n" | 35 | //usage:#define unzip_full_usage "\n\n" |
diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c index 6b923d2d4..bf8d690da 100644 --- a/console-tools/dumpkmap.c +++ b/console-tools/dumpkmap.c | |||
@@ -36,47 +36,56 @@ int dumpkmap_main(int argc UNUSED_PARAM, char **argv) | |||
36 | { | 36 | { |
37 | struct kbentry ke; | 37 | struct kbentry ke; |
38 | int i, j, fd; | 38 | int i, j, fd; |
39 | RESERVE_CONFIG_BUFFER(flags, MAX_NR_KEYMAPS); | 39 | #define flags bb_common_bufsiz1 |
40 | 40 | ||
41 | /* When user accidentally runs "dumpkmap FILE" | 41 | /* When user accidentally runs "dumpkmap FILE" |
42 | * instead of "dumpkmap >FILE", we'd dump binary stuff to tty. | 42 | * instead of "dumpkmap >FILE", we'd dump binary stuff to tty. |
43 | * Let's prevent it: */ | 43 | * Let's prevent it: |
44 | */ | ||
44 | if (argv[1]) | 45 | if (argv[1]) |
45 | bb_show_usage(); | 46 | bb_show_usage(); |
46 | /* bb_warn_ignoring_args(argv[1]);*/ | 47 | /* bb_warn_ignoring_args(argv[1]);*/ |
47 | 48 | ||
48 | fd = get_console_fd_or_die(); | 49 | fd = get_console_fd_or_die(); |
49 | 50 | ||
51 | #if 0 | ||
50 | write(STDOUT_FILENO, "bkeymap", 7); | 52 | write(STDOUT_FILENO, "bkeymap", 7); |
51 | |||
52 | /* Here we want to set everything to 0 except for indexes: | 53 | /* Here we want to set everything to 0 except for indexes: |
53 | * [0-2] [4-6] [8-10] [12] */ | 54 | * [0-2] [4-6] [8-10] [12] |
54 | memset(flags, 0x00, MAX_NR_KEYMAPS); | 55 | */ |
56 | /*memset(flags, 0x00, MAX_NR_KEYMAPS); - already is */ | ||
55 | memset(flags, 0x01, 13); | 57 | memset(flags, 0x01, 13); |
56 | flags[3] = flags[7] = flags[11] = 0; | 58 | flags[3] = flags[7] = flags[11] = 0; |
57 | |||
58 | /* dump flags */ | 59 | /* dump flags */ |
59 | write(STDOUT_FILENO, flags, MAX_NR_KEYMAPS); | 60 | write(STDOUT_FILENO, flags, MAX_NR_KEYMAPS); |
61 | #define flags7 flags | ||
62 | #else | ||
63 | /* Same effect */ | ||
64 | /* 0 1 2 3 4 5 6 7 8 9 a b c=12 */ | ||
65 | memcpy(flags, "bkeymap\1\1\1\0\1\1\1\0\1\1\1\0\1", | ||
66 | /* Can use sizeof, or sizeof-1. sizeof is even, using that */ | ||
67 | /****/ sizeof("bkeymap\1\1\1\0\1\1\1\0\1\1\1\0\1") | ||
68 | ); | ||
69 | write(STDOUT_FILENO, flags, 7 + MAX_NR_KEYMAPS); | ||
70 | #define flags7 (flags + 7) | ||
71 | #endif | ||
60 | 72 | ||
61 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | 73 | for (i = 0; i < 13; i++) { |
62 | if (flags[i] == 1) { | 74 | if (flags7[i]) { |
63 | for (j = 0; j < NR_KEYS; j++) { | 75 | for (j = 0; j < NR_KEYS; j++) { |
64 | ke.kb_index = j; | 76 | ke.kb_index = j; |
65 | ke.kb_table = i; | 77 | ke.kb_table = i; |
66 | if (!ioctl_or_perror(fd, KDGKBENT, &ke, | 78 | if (!ioctl_or_perror(fd, KDGKBENT, &ke, |
67 | "ioctl failed with %s, %s, %p", | 79 | "ioctl(KDGKBENT{%d,%d}) failed", |
68 | (char *)&ke.kb_index, | 80 | j, i) |
69 | (char *)&ke.kb_table, | ||
70 | &ke.kb_value) | ||
71 | ) { | 81 | ) { |
72 | write(STDOUT_FILENO, (void*)&ke.kb_value, 2); | 82 | write(STDOUT_FILENO, &ke.kb_value, 2); |
73 | } | 83 | } |
74 | } | 84 | } |
75 | } | 85 | } |
76 | } | 86 | } |
77 | if (ENABLE_FEATURE_CLEAN_UP) { | 87 | if (ENABLE_FEATURE_CLEAN_UP) { |
78 | close(fd); | 88 | close(fd); |
79 | RELEASE_CONFIG_BUFFER(flags); | ||
80 | } | 89 | } |
81 | return EXIT_SUCCESS; | 90 | return EXIT_SUCCESS; |
82 | } | 91 | } |
diff --git a/console-tools/loadkmap.c b/console-tools/loadkmap.c index bcffe16b1..66ec3b043 100644 --- a/console-tools/loadkmap.c +++ b/console-tools/loadkmap.c | |||
@@ -48,6 +48,7 @@ int loadkmap_main(int argc UNUSED_PARAM, char **argv) | |||
48 | if (argv[1]) | 48 | if (argv[1]) |
49 | bb_show_usage(); | 49 | bb_show_usage(); |
50 | /* bb_warn_ignoring_args(argv[1]); */ | 50 | /* bb_warn_ignoring_args(argv[1]); */ |
51 | |||
51 | fd = get_console_fd_or_die(); | 52 | fd = get_console_fd_or_die(); |
52 | /* or maybe: | 53 | /* or maybe: |
53 | opt = getopt32(argv, "C:", &tty_name); | 54 | opt = getopt32(argv, "C:", &tty_name); |
@@ -61,14 +62,24 @@ int loadkmap_main(int argc UNUSED_PARAM, char **argv) | |||
61 | xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS); | 62 | xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS); |
62 | 63 | ||
63 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | 64 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { |
64 | if (flags[i] == 1) { | 65 | if (flags[i] != 1) |
65 | xread(STDIN_FILENO, ibuff, NR_KEYS * sizeof(uint16_t)); | 66 | continue; |
66 | for (j = 0; j < NR_KEYS; j++) { | 67 | xread(STDIN_FILENO, ibuff, NR_KEYS * sizeof(uint16_t)); |
67 | ke.kb_index = j; | 68 | for (j = 0; j < NR_KEYS; j++) { |
68 | ke.kb_table = i; | 69 | ke.kb_index = j; |
69 | ke.kb_value = ibuff[j]; | 70 | ke.kb_table = i; |
70 | ioctl(fd, KDSKBENT, &ke); | 71 | ke.kb_value = ibuff[j]; |
71 | } | 72 | /* |
73 | * Note: table[idx:0] can contain special value | ||
74 | * K_ALLOCATED (marks allocated tables in kernel). | ||
75 | * dumpkmap saves the value as-is; but attempts | ||
76 | * to load it here fail, since it isn't a valid | ||
77 | * key value: it is K(KT_SPEC,126) == 2<<8 + 126, | ||
78 | * whereas last valid KT_SPEC is | ||
79 | * K_BARENUMLOCK == K(KT_SPEC,19). | ||
80 | * So far we just ignore these errors: | ||
81 | */ | ||
82 | ioctl(fd, KDSKBENT, &ke); | ||
72 | } | 83 | } |
73 | } | 84 | } |
74 | 85 | ||
diff --git a/coreutils/cal.c b/coreutils/cal.c index 0d388aa1c..12c46b14f 100644 --- a/coreutils/cal.c +++ b/coreutils/cal.c | |||
@@ -165,7 +165,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
165 | char lineout[30]; | 165 | char lineout[30]; |
166 | 166 | ||
167 | day_array(month, year, dp); | 167 | day_array(month, year, dp); |
168 | len = sprintf(lineout, "%s %d", month_names[month - 1], year); | 168 | len = sprintf(lineout, "%s %u", month_names[month - 1], year); |
169 | printf("%*s%s\n%s\n", | 169 | printf("%*s%s\n%s\n", |
170 | ((7*julian + WEEK_LEN) - len) / 2, "", | 170 | ((7*julian + WEEK_LEN) - len) / 2, "", |
171 | lineout, day_headings); | 171 | lineout, day_headings); |
diff --git a/coreutils/expand.c b/coreutils/expand.c index 25bbffc66..8d376ff4e 100644 --- a/coreutils/expand.c +++ b/coreutils/expand.c | |||
@@ -78,11 +78,7 @@ static void expand(FILE *file, unsigned tab_size, unsigned opt) | |||
78 | unsigned len; | 78 | unsigned len; |
79 | *ptr = '\0'; | 79 | *ptr = '\0'; |
80 | # if ENABLE_UNICODE_SUPPORT | 80 | # if ENABLE_UNICODE_SUPPORT |
81 | { | 81 | len = unicode_strwidth(ptr_strbeg); |
82 | uni_stat_t uni_stat; | ||
83 | printable_string(&uni_stat, ptr_strbeg); | ||
84 | len = uni_stat.unicode_width; | ||
85 | } | ||
86 | # else | 82 | # else |
87 | len = ptr - ptr_strbeg; | 83 | len = ptr - ptr_strbeg; |
88 | # endif | 84 | # endif |
@@ -138,12 +134,9 @@ static void unexpand(FILE *file, unsigned tab_size, unsigned opt) | |||
138 | printf("%*s%.*s", len, "", n, ptr); | 134 | printf("%*s%.*s", len, "", n, ptr); |
139 | # if ENABLE_UNICODE_SUPPORT | 135 | # if ENABLE_UNICODE_SUPPORT |
140 | { | 136 | { |
141 | char c; | 137 | char c = ptr[n]; |
142 | uni_stat_t uni_stat; | ||
143 | c = ptr[n]; | ||
144 | ptr[n] = '\0'; | 138 | ptr[n] = '\0'; |
145 | printable_string(&uni_stat, ptr); | 139 | len = unicode_strwidth(ptr); |
146 | len = uni_stat.unicode_width; | ||
147 | ptr[n] = c; | 140 | ptr[n] = c; |
148 | } | 141 | } |
149 | # else | 142 | # else |
diff --git a/coreutils/sum.c b/coreutils/sum.c index 75f6ef60a..deb068e10 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c | |||
@@ -70,9 +70,9 @@ static unsigned sum_file(const char *file, unsigned type) | |||
70 | if (type >= SUM_SYSV) { | 70 | if (type >= SUM_SYSV) { |
71 | r = (s & 0xffff) + ((s & 0xffffffff) >> 16); | 71 | r = (s & 0xffff) + ((s & 0xffffffff) >> 16); |
72 | s = (r & 0xffff) + (r >> 16); | 72 | s = (r & 0xffff) + (r >> 16); |
73 | printf("%d %llu %s\n", s, (total_bytes + 511) / 512, file); | 73 | printf("%u %llu %s\n", s, (total_bytes + 511) / 512, file); |
74 | } else | 74 | } else |
75 | printf("%05d %5llu %s\n", s, (total_bytes + 1023) / 1024, file); | 75 | printf("%05u %5llu %s\n", s, (total_bytes + 1023) / 1024, file); |
76 | return 1; | 76 | return 1; |
77 | #undef buf | 77 | #undef buf |
78 | } | 78 | } |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 07c71ca4b..eab502beb 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -105,6 +105,7 @@ int tail_main(int argc, char **argv) | |||
105 | 105 | ||
106 | int *fds; | 106 | int *fds; |
107 | const char *fmt; | 107 | const char *fmt; |
108 | int prev_fd; | ||
108 | 109 | ||
109 | INIT_G(); | 110 | INIT_G(); |
110 | 111 | ||
@@ -309,6 +310,7 @@ int tail_main(int argc, char **argv) | |||
309 | xwrite(STDOUT_FILENO, tailbuf, taillen); | 310 | xwrite(STDOUT_FILENO, tailbuf, taillen); |
310 | } | 311 | } |
311 | } while (++i < nfiles); | 312 | } while (++i < nfiles); |
313 | prev_fd = fds[i-1]; | ||
312 | 314 | ||
313 | tailbuf = xrealloc(tailbuf, BUFSIZ); | 315 | tailbuf = xrealloc(tailbuf, BUFSIZ); |
314 | 316 | ||
@@ -365,9 +367,10 @@ int tail_main(int argc, char **argv) | |||
365 | nread = tail_read(fd, tailbuf, BUFSIZ); | 367 | nread = tail_read(fd, tailbuf, BUFSIZ); |
366 | if (nread <= 0) | 368 | if (nread <= 0) |
367 | break; | 369 | break; |
368 | if (fmt) { | 370 | if (fmt && (fd != prev_fd)) { |
369 | tail_xprint_header(fmt, filename); | 371 | tail_xprint_header(fmt, filename); |
370 | fmt = NULL; | 372 | fmt = NULL; |
373 | prev_fd = fd; | ||
371 | } | 374 | } |
372 | xwrite(STDOUT_FILENO, tailbuf, nread); | 375 | xwrite(STDOUT_FILENO, tailbuf, nread); |
373 | } | 376 | } |
diff --git a/coreutils/touch.c b/coreutils/touch.c index 1216ca202..293a96890 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c | |||
@@ -26,6 +26,14 @@ | |||
26 | //config: touch is used to create or change the access and/or | 26 | //config: touch is used to create or change the access and/or |
27 | //config: modification timestamp of specified files. | 27 | //config: modification timestamp of specified files. |
28 | //config: | 28 | //config: |
29 | //config:config FEATURE_TOUCH_NODEREF | ||
30 | //config: bool "Add support for -h" | ||
31 | //config: default y | ||
32 | //config: depends on TOUCH | ||
33 | //config: help | ||
34 | //config: Enable touch to have the -h option. | ||
35 | //config: This requires libc support for lutimes() function. | ||
36 | //config: | ||
29 | //config:config FEATURE_TOUCH_SUSV3 | 37 | //config:config FEATURE_TOUCH_SUSV3 |
30 | //config: bool "Add support for SUSV3 features (-d -t -r)" | 38 | //config: bool "Add support for SUSV3 features (-d -t -r)" |
31 | //config: default y | 39 | //config: default y |
@@ -42,6 +50,9 @@ | |||
42 | //usage:#define touch_full_usage "\n\n" | 50 | //usage:#define touch_full_usage "\n\n" |
43 | //usage: "Update the last-modified date on the given FILE[s]\n" | 51 | //usage: "Update the last-modified date on the given FILE[s]\n" |
44 | //usage: "\n -c Don't create files" | 52 | //usage: "\n -c Don't create files" |
53 | //usage: IF_FEATURE_TOUCH_NODEREF( | ||
54 | //usage: "\n -h Don't follow links" | ||
55 | //usage: ) | ||
45 | //usage: IF_FEATURE_TOUCH_SUSV3( | 56 | //usage: IF_FEATURE_TOUCH_SUSV3( |
46 | //usage: "\n -d DT Date/time to use" | 57 | //usage: "\n -d DT Date/time to use" |
47 | //usage: "\n -t DT Date/time to use" | 58 | //usage: "\n -t DT Date/time to use" |
@@ -65,6 +76,7 @@ | |||
65 | * parse STRING and use it instead of current time | 76 | * parse STRING and use it instead of current time |
66 | * -f (ignored, BSD compat) | 77 | * -f (ignored, BSD compat) |
67 | * -m change only the modification time | 78 | * -m change only the modification time |
79 | * -h, --no-dereference | ||
68 | * -r, --reference=FILE | 80 | * -r, --reference=FILE |
69 | * use this file's times instead of current time | 81 | * use this file's times instead of current time |
70 | * -t STAMP | 82 | * -t STAMP |
@@ -79,6 +91,13 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
79 | int fd; | 91 | int fd; |
80 | int status = EXIT_SUCCESS; | 92 | int status = EXIT_SUCCESS; |
81 | int opts; | 93 | int opts; |
94 | enum { | ||
95 | OPT_c = (1 << 0), | ||
96 | OPT_r = (1 << 1) * ENABLE_FEATURE_TOUCH_SUSV3, | ||
97 | OPT_d = (1 << 2) * ENABLE_FEATURE_TOUCH_SUSV3, | ||
98 | OPT_t = (1 << 3) * ENABLE_FEATURE_TOUCH_SUSV3, | ||
99 | OPT_h = (1 << 4) * ENABLE_FEATURE_TOUCH_NODEREF, | ||
100 | }; | ||
82 | #if ENABLE_FEATURE_TOUCH_SUSV3 | 101 | #if ENABLE_FEATURE_TOUCH_SUSV3 |
83 | # if ENABLE_LONG_OPTS | 102 | # if ENABLE_LONG_OPTS |
84 | static const char touch_longopts[] ALIGN1 = | 103 | static const char touch_longopts[] ALIGN1 = |
@@ -86,6 +105,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
86 | "no-create\0" No_argument "c" | 105 | "no-create\0" No_argument "c" |
87 | "reference\0" Required_argument "r" | 106 | "reference\0" Required_argument "r" |
88 | "date\0" Required_argument "d" | 107 | "date\0" Required_argument "d" |
108 | IF_FEATURE_TOUCH_NODEREF("no-dereference\0" No_argument "h") | ||
89 | ; | 109 | ; |
90 | # endif | 110 | # endif |
91 | char *reference_file = NULL; | 111 | char *reference_file = NULL; |
@@ -105,13 +125,13 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
105 | * accepted data format differs a bit between -d and -t. | 125 | * accepted data format differs a bit between -d and -t. |
106 | * We accept the same formats for both */ | 126 | * We accept the same formats for both */ |
107 | opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:") | 127 | opts = getopt32(argv, "c" IF_FEATURE_TOUCH_SUSV3("r:d:t:") |
128 | IF_FEATURE_TOUCH_NODEREF("h") | ||
108 | /*ignored:*/ "fma" | 129 | /*ignored:*/ "fma" |
109 | IF_FEATURE_TOUCH_SUSV3(, &reference_file) | 130 | IF_FEATURE_TOUCH_SUSV3(, &reference_file) |
110 | IF_FEATURE_TOUCH_SUSV3(, &date_str) | 131 | IF_FEATURE_TOUCH_SUSV3(, &date_str) |
111 | IF_FEATURE_TOUCH_SUSV3(, &date_str) | 132 | IF_FEATURE_TOUCH_SUSV3(, &date_str) |
112 | ); | 133 | ); |
113 | 134 | ||
114 | opts &= 1; /* only -c bit is left */ | ||
115 | argv += optind; | 135 | argv += optind; |
116 | if (!*argv) { | 136 | if (!*argv) { |
117 | bb_show_usage(); | 137 | bb_show_usage(); |
@@ -121,6 +141,10 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
121 | struct stat stbuf; | 141 | struct stat stbuf; |
122 | xstat(reference_file, &stbuf); | 142 | xstat(reference_file, &stbuf); |
123 | timebuf[1].tv_sec = timebuf[0].tv_sec = stbuf.st_mtime; | 143 | timebuf[1].tv_sec = timebuf[0].tv_sec = stbuf.st_mtime; |
144 | /* Can use .st_mtim.tv_nsec | ||
145 | * (or is it .st_mtimensec?? see date.c) | ||
146 | * to set microseconds too. | ||
147 | */ | ||
124 | } | 148 | } |
125 | 149 | ||
126 | if (date_str) { | 150 | if (date_str) { |
@@ -141,9 +165,16 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
141 | } | 165 | } |
142 | 166 | ||
143 | do { | 167 | do { |
144 | if (utimes(*argv, (reference_file || date_str) ? timebuf : NULL) != 0) { | 168 | int result; |
145 | if (errno == ENOENT) { /* no such file */ | 169 | result = ( |
146 | if (opts) { /* creation is disabled, so ignore */ | 170 | #if ENABLE_FEATURE_TOUCH_NODEREF |
171 | (opts & OPT_h) ? lutimes : | ||
172 | #endif | ||
173 | utimes)(*argv, (reference_file || date_str) ? timebuf : NULL); | ||
174 | if (result != 0) { | ||
175 | if (errno == ENOENT) { /* no such file? */ | ||
176 | if (opts & OPT_c) { | ||
177 | /* Creation is disabled, so ignore */ | ||
147 | continue; | 178 | continue; |
148 | } | 179 | } |
149 | /* Try to create the file */ | 180 | /* Try to create the file */ |
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 2c2b032be..527fae227 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -59,7 +59,7 @@ | |||
59 | struct globals { | 59 | struct globals { |
60 | char **names; | 60 | char **names; |
61 | int cur; | 61 | int cur; |
62 | char *cmd[1]; | 62 | char *cmd[2 /* using 1 provokes compiler warning */]; |
63 | } FIX_ALIASING; | 63 | } FIX_ALIASING; |
64 | #define G (*(struct globals*)&bb_common_bufsiz1) | 64 | #define G (*(struct globals*)&bb_common_bufsiz1) |
65 | #define names (G.names) | 65 | #define names (G.names) |
diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt index 21d732674..9fc799646 100644 --- a/docs/keep_data_small.txt +++ b/docs/keep_data_small.txt | |||
@@ -138,13 +138,6 @@ less readable, use #defines: | |||
138 | #define sector (G.sector) | 138 | #define sector (G.sector) |
139 | 139 | ||
140 | 140 | ||
141 | Word of caution | ||
142 | |||
143 | If applet doesn't use much of global data, converting it to use | ||
144 | one of above methods is not worth the resulting code obfuscation. | ||
145 | If you have less than ~300 bytes of global data - don't bother. | ||
146 | |||
147 | |||
148 | Finding non-shared duplicated strings | 141 | Finding non-shared duplicated strings |
149 | 142 | ||
150 | strings busybox | sort | uniq -c | sort -nr | 143 | strings busybox | sort | uniq -c | sort -nr |
@@ -224,6 +217,14 @@ Result (non-static busybox built against glibc): | |||
224 | 217 | ||
225 | Keeping code small | 218 | Keeping code small |
226 | 219 | ||
220 | Use scripts/bloat-o-meter to check whether introduced changes | ||
221 | didn't generate unnecessary bloat. This script needs unstripped binaries | ||
222 | to generate a detailed report. To automate this, just use | ||
223 | "make bloatcheck". It requires busybox_old binary to be present, | ||
224 | use "make baseline" to generate it from unmodified source, or | ||
225 | copy busybox_unstripped to busybox_old before modifying sources | ||
226 | and rebuilding. | ||
227 | |||
227 | Set CONFIG_EXTRA_CFLAGS="-fno-inline-functions-called-once", | 228 | Set CONFIG_EXTRA_CFLAGS="-fno-inline-functions-called-once", |
228 | produce "make bloatcheck", see the biggest auto-inlined functions. | 229 | produce "make bloatcheck", see the biggest auto-inlined functions. |
229 | Now, set CONFIG_EXTRA_CFLAGS back to "", but add NOINLINE | 230 | Now, set CONFIG_EXTRA_CFLAGS back to "", but add NOINLINE |
diff --git a/docs/tcp.txt b/docs/tcp.txt index 766766387..2000f3110 100644 --- a/docs/tcp.txt +++ b/docs/tcp.txt | |||
@@ -18,8 +18,11 @@ What will happen if we close the socket? | |||
18 | received after close() is called, its TCP SHOULD send a RST | 18 | received after close() is called, its TCP SHOULD send a RST |
19 | to show that data was lost." | 19 | to show that data was lost." |
20 | 20 | ||
21 | IOW: if we just close(sock) now, kernel can reset the TCP connection, | 21 | IOW: if we just close(sock) now, kernel can reset the TCP connection |
22 | discarding some not-yet sent data. | 22 | (send RST packet). |
23 | |||
24 | This is problematic for two reasons: it discards some not-yet sent | ||
25 | data, and it may be reported as error, not EOF, on peer's side. | ||
23 | 26 | ||
24 | What can be done about it? | 27 | What can be done about it? |
25 | 28 | ||
@@ -46,14 +49,14 @@ This makes kernel send FIN after all data is written: | |||
46 | 49 | ||
47 | However, experiments on Linux 3.9.4 show that kernel can return from | 50 | However, experiments on Linux 3.9.4 show that kernel can return from |
48 | shutdown() and from close() before all data is sent, | 51 | shutdown() and from close() before all data is sent, |
49 | and if peer sends any data to us after this, kernel stll responds with | 52 | and if peer sends any data to us after this, kernel still responds with |
50 | RST before all our data is sent. | 53 | RST before all our data is sent. |
51 | 54 | ||
52 | In practice the protocol in use often does not allow peer to send | 55 | In practice the protocol in use often does not allow peer to send |
53 | such data to us, in which case this solution is acceptable. | 56 | such data to us, in which case this solution is acceptable. |
54 | 57 | ||
55 | If you know that peer is going to close its end after it sees our FIN | 58 | Solution #3: if you know that peer is going to close its end after it sees |
56 | (as EOF), it might be a good idea to perform a read after shutdown(). | 59 | our FIN (as EOF), it might be a good idea to perform a read after shutdown(). |
57 | When read finishes with 0-sized result, we conclude that peer received all | 60 | When read finishes with 0-sized result, we conclude that peer received all |
58 | the data, saw EOF, and closed its end. | 61 | the data, saw EOF, and closed its end. |
59 | 62 | ||
@@ -61,6 +64,14 @@ However, this incurs small performance penalty (we run for a longer time) | |||
61 | and requires safeguards (nonblocking reads, timeouts etc) against | 64 | and requires safeguards (nonblocking reads, timeouts etc) against |
62 | malicious peers which don't close the connection. | 65 | malicious peers which don't close the connection. |
63 | 66 | ||
67 | Solutions #1 and #2 can be combined: | ||
68 | |||
69 | /* ...set up struct linger... then: */ | ||
70 | setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); | ||
71 | shutdown(sock, SHUT_WR); | ||
72 | /* At this point, kernel sent FIN packet, not RST, to the peer, */ | ||
73 | /* even if there is buffered read data from the peer. */ | ||
74 | close(sock); | ||
64 | 75 | ||
65 | Defeating Nagle. | 76 | Defeating Nagle. |
66 | 77 | ||
diff --git a/e2fsprogs/old_e2fsprogs/blkid/blkidP.h b/e2fsprogs/old_e2fsprogs/blkid/blkidP.h index d6b2b42cc..bbadc8eb5 100644 --- a/e2fsprogs/old_e2fsprogs/blkid/blkidP.h +++ b/e2fsprogs/old_e2fsprogs/blkid/blkidP.h | |||
@@ -179,8 +179,4 @@ extern int blkid_set_tag(blkid_dev dev, const char *name, | |||
179 | extern blkid_dev blkid_new_dev(void); | 179 | extern blkid_dev blkid_new_dev(void); |
180 | extern void blkid_free_dev(blkid_dev dev); | 180 | extern void blkid_free_dev(blkid_dev dev); |
181 | 181 | ||
182 | #ifdef __cplusplus | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | #endif | 182 | #endif |
diff --git a/e2fsprogs/old_e2fsprogs/blkid/cache.c b/e2fsprogs/old_e2fsprogs/blkid/cache.c index d1d29146b..251e49900 100644 --- a/e2fsprogs/old_e2fsprogs/blkid/cache.c +++ b/e2fsprogs/old_e2fsprogs/blkid/cache.c | |||
@@ -115,7 +115,7 @@ int main(int argc, char** argv) | |||
115 | argv[0], ret); | 115 | argv[0], ret); |
116 | exit(1); | 116 | exit(1); |
117 | } | 117 | } |
118 | if ((ret = blkid_probe_all(cache) < 0)) | 118 | if ((ret = blkid_probe_all(cache)) < 0) |
119 | fprintf(stderr, "error probing devices\n"); | 119 | fprintf(stderr, "error probing devices\n"); |
120 | 120 | ||
121 | blkid_put_cache(cache); | 121 | blkid_put_cache(cache); |
diff --git a/e2fsprogs/old_e2fsprogs/blkid/dev.c b/e2fsprogs/old_e2fsprogs/blkid/dev.c index bb0cc914a..260e49c65 100644 --- a/e2fsprogs/old_e2fsprogs/blkid/dev.c +++ b/e2fsprogs/old_e2fsprogs/blkid/dev.c | |||
@@ -153,7 +153,7 @@ extern int optind; | |||
153 | void usage(char *prog) | 153 | void usage(char *prog) |
154 | { | 154 | { |
155 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); | 155 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); |
156 | fprintf(stderr, "\tList all devices and exit\n", prog); | 156 | fprintf(stderr, "\tList all devices and exit\n"); |
157 | exit(1); | 157 | exit(1); |
158 | } | 158 | } |
159 | 159 | ||
@@ -176,7 +176,7 @@ int main(int argc, char **argv) | |||
176 | case 'm': | 176 | case 'm': |
177 | blkid_debug_mask = strtoul (optarg, &tmp, 0); | 177 | blkid_debug_mask = strtoul (optarg, &tmp, 0); |
178 | if (*tmp) { | 178 | if (*tmp) { |
179 | fprintf(stderr, "Invalid debug mask: %d\n", | 179 | fprintf(stderr, "Invalid debug mask: %s\n", |
180 | optarg); | 180 | optarg); |
181 | exit(1); | 181 | exit(1); |
182 | } | 182 | } |
diff --git a/e2fsprogs/old_e2fsprogs/blkid/read.c b/e2fsprogs/old_e2fsprogs/blkid/read.c index f795a5d14..feeda518b 100644 --- a/e2fsprogs/old_e2fsprogs/blkid/read.c +++ b/e2fsprogs/old_e2fsprogs/blkid/read.c | |||
@@ -385,7 +385,7 @@ void blkid_read_cache(blkid_cache cache) | |||
385 | continue; | 385 | continue; |
386 | end = strlen(buf) - 1; | 386 | end = strlen(buf) - 1; |
387 | /* Continue reading next line if it ends with a backslash */ | 387 | /* Continue reading next line if it ends with a backslash */ |
388 | while (buf[end] == '\\' && end < sizeof(buf) - 2 && | 388 | while (end < sizeof(buf) - 2 && buf[end] == '\\' && |
389 | fgets(buf + end, sizeof(buf) - end, file)) { | 389 | fgets(buf + end, sizeof(buf) - end, file)) { |
390 | end = strlen(buf) - 1; | 390 | end = strlen(buf) - 1; |
391 | lineno++; | 391 | lineno++; |
diff --git a/e2fsprogs/old_e2fsprogs/blkid/tag.c b/e2fsprogs/old_e2fsprogs/blkid/tag.c index 8337b46b6..7424edeb8 100644 --- a/e2fsprogs/old_e2fsprogs/blkid/tag.c +++ b/e2fsprogs/old_e2fsprogs/blkid/tag.c | |||
@@ -356,7 +356,7 @@ void usage(char *prog) | |||
356 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " | 356 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " |
357 | "[type value]\n", | 357 | "[type value]\n", |
358 | prog); | 358 | prog); |
359 | fprintf(stderr, "\tList all tags for a device and exit\n", prog); | 359 | fprintf(stderr, "\tList all tags for a device and exit\n"); |
360 | exit(1); | 360 | exit(1); |
361 | } | 361 | } |
362 | 362 | ||
@@ -382,7 +382,7 @@ int main(int argc, char **argv) | |||
382 | case 'm': | 382 | case 'm': |
383 | blkid_debug_mask = strtoul (optarg, &tmp, 0); | 383 | blkid_debug_mask = strtoul (optarg, &tmp, 0); |
384 | if (*tmp) { | 384 | if (*tmp) { |
385 | fprintf(stderr, "Invalid debug mask: %d\n", | 385 | fprintf(stderr, "Invalid debug mask: %s\n", |
386 | optarg); | 386 | optarg); |
387 | exit(1); | 387 | exit(1); |
388 | } | 388 | } |
@@ -407,7 +407,7 @@ int main(int argc, char **argv) | |||
407 | 407 | ||
408 | dev = blkid_get_dev(cache, devname, flags); | 408 | dev = blkid_get_dev(cache, devname, flags); |
409 | if (!dev) { | 409 | if (!dev) { |
410 | fprintf(stderr, "%s: cannot find device in blkid cache\n"); | 410 | fprintf(stderr, "%s: cannot find device in blkid cache\n", devname); |
411 | exit(1); | 411 | exit(1); |
412 | } | 412 | } |
413 | if (search_type) { | 413 | if (search_type) { |
diff --git a/e2fsprogs/old_e2fsprogs/e2fsck.c b/e2fsprogs/old_e2fsprogs/e2fsck.c index 373e8ce91..8400a92ce 100644 --- a/e2fsprogs/old_e2fsprogs/e2fsck.c +++ b/e2fsprogs/old_e2fsprogs/e2fsck.c | |||
@@ -1050,7 +1050,7 @@ static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret) | |||
1050 | refcount->size = size; | 1050 | refcount->size = size; |
1051 | bytes = (size_t) (size * sizeof(struct ea_refcount_el)); | 1051 | bytes = (size_t) (size * sizeof(struct ea_refcount_el)); |
1052 | #ifdef DEBUG | 1052 | #ifdef DEBUG |
1053 | printf("Refcount allocated %d entries, %d bytes.\n", | 1053 | printf("Refcount allocated %d entries, %lu bytes.\n", |
1054 | refcount->size, bytes); | 1054 | refcount->size, bytes); |
1055 | #endif | 1055 | #endif |
1056 | retval = ext2fs_get_mem(bytes, &refcount->list); | 1056 | retval = ext2fs_get_mem(bytes, &refcount->list); |
@@ -3424,7 +3424,7 @@ static void e2fsck_pass1(e2fsck_t ctx) | |||
3424 | continue; | 3424 | continue; |
3425 | } | 3425 | } |
3426 | if ((inode->i_links_count || inode->i_blocks || | 3426 | if ((inode->i_links_count || inode->i_blocks || |
3427 | inode->i_blocks || inode->i_block[0]) && | 3427 | inode->i_block[0]) && |
3428 | fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, | 3428 | fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, |
3429 | &pctx)) { | 3429 | &pctx)) { |
3430 | memset(inode, 0, inode_size); | 3430 | memset(inode, 0, inode_size); |
@@ -12195,11 +12195,7 @@ static void swap_filesys(e2fsck_t ctx) | |||
12195 | void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, | 12195 | void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, |
12196 | const char *description) | 12196 | const char *description) |
12197 | { | 12197 | { |
12198 | void *ret; | 12198 | return xzalloc(size); |
12199 | char buf[256]; | ||
12200 | |||
12201 | ret = xzalloc(size); | ||
12202 | return ret; | ||
12203 | } | 12199 | } |
12204 | 12200 | ||
12205 | static char *string_copy(const char *str, int len) | 12201 | static char *string_copy(const char *str, int len) |
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c b/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c index da2d15137..240335b32 100644 --- a/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c +++ b/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c | |||
@@ -83,7 +83,7 @@ static int calc_reserved_gdt_blocks(ext2_filsys fs) | |||
83 | if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb)) | 83 | if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb)) |
84 | rsv_gdb = EXT2_ADDR_PER_BLOCK(sb); | 84 | rsv_gdb = EXT2_ADDR_PER_BLOCK(sb); |
85 | #ifdef RES_GDT_DEBUG | 85 | #ifdef RES_GDT_DEBUG |
86 | printf("max_blocks %lu, rsv_groups = %lu, rsv_gdb = %lu\n", | 86 | printf("max_blocks %lu, rsv_groups = %lu, rsv_gdb = %u\n", |
87 | max_blocks, rsv_groups, rsv_gdb); | 87 | max_blocks, rsv_groups, rsv_gdb); |
88 | #endif | 88 | #endif |
89 | 89 | ||
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c b/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c index 474f07340..3c95829f0 100644 --- a/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c +++ b/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c | |||
@@ -544,7 +544,7 @@ static errcode_t unix_read_blk(io_channel channel, unsigned long block, | |||
544 | /* If it's in the cache, use it! */ | 544 | /* If it's in the cache, use it! */ |
545 | if ((cache = find_cached_block(data, block, &reuse[0]))) { | 545 | if ((cache = find_cached_block(data, block, &reuse[0]))) { |
546 | #ifdef DEBUG | 546 | #ifdef DEBUG |
547 | printf("Using cached block %d\n", block); | 547 | printf("Using cached block %lu\n", block); |
548 | #endif | 548 | #endif |
549 | memcpy(cp, cache->buf, channel->block_size); | 549 | memcpy(cp, cache->buf, channel->block_size); |
550 | count--; | 550 | count--; |
@@ -560,7 +560,7 @@ static errcode_t unix_read_blk(io_channel channel, unsigned long block, | |||
560 | if (find_cached_block(data, block+i, &reuse[i])) | 560 | if (find_cached_block(data, block+i, &reuse[i])) |
561 | break; | 561 | break; |
562 | #ifdef DEBUG | 562 | #ifdef DEBUG |
563 | printf("Reading %d blocks starting at %d\n", i, block); | 563 | printf("Reading %d blocks starting at %lu\n", i, block); |
564 | #endif | 564 | #endif |
565 | if ((retval = raw_read_blk(channel, data, block, i, cp))) | 565 | if ((retval = raw_read_blk(channel, data, block, i, cp))) |
566 | return retval; | 566 | return retval; |
diff --git a/e2fsprogs/old_e2fsprogs/fsck.c b/e2fsprogs/old_e2fsprogs/fsck.c index 3a0743bb1..91cce970c 100644 --- a/e2fsprogs/old_e2fsprogs/fsck.c +++ b/e2fsprogs/old_e2fsprogs/fsck.c | |||
@@ -1239,7 +1239,6 @@ static void PRS(int argc, char **argv) | |||
1239 | progress_fd = 0; | 1239 | progress_fd = 0; |
1240 | else { | 1240 | else { |
1241 | goto next_arg; | 1241 | goto next_arg; |
1242 | i++; | ||
1243 | } | 1242 | } |
1244 | } | 1243 | } |
1245 | break; | 1244 | break; |
diff --git a/e2fsprogs/old_e2fsprogs/mke2fs.c b/e2fsprogs/old_e2fsprogs/mke2fs.c index 35d717a55..ebcb46cf2 100644 --- a/e2fsprogs/old_e2fsprogs/mke2fs.c +++ b/e2fsprogs/old_e2fsprogs/mke2fs.c | |||
@@ -239,7 +239,7 @@ static void test_disk(ext2_filsys fs, badblocks_list *bb_list) | |||
239 | errcode_t retval; | 239 | errcode_t retval; |
240 | char buf[1024]; | 240 | char buf[1024]; |
241 | 241 | ||
242 | sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize, | 242 | sprintf(buf, "badblocks -b %u %s%s%s %d", fs->blocksize, |
243 | quiet ? "" : "-s ", (cflag > 1) ? "-w " : "", | 243 | quiet ? "" : "-s ", (cflag > 1) ? "-w " : "", |
244 | fs->device_name, fs->super->s_blocks_count); | 244 | fs->device_name, fs->super->s_blocks_count); |
245 | mke2fs_verbose("Running command: %s\n", buf); | 245 | mke2fs_verbose("Running command: %s\n", buf); |
@@ -385,7 +385,7 @@ static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num, | |||
385 | struct progress_struct *progress, | 385 | struct progress_struct *progress, |
386 | blk_t *ret_blk, int *ret_count) | 386 | blk_t *ret_blk, int *ret_count) |
387 | { | 387 | { |
388 | int j, count, next_update, next_update_incr; | 388 | int j, count, next_update; |
389 | static char *buf; | 389 | static char *buf; |
390 | errcode_t retval; | 390 | errcode_t retval; |
391 | 391 | ||
@@ -403,9 +403,7 @@ static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num, | |||
403 | } | 403 | } |
404 | /* OK, do the write loop */ | 404 | /* OK, do the write loop */ |
405 | next_update = 0; | 405 | next_update = 0; |
406 | next_update_incr = num / 100; | 406 | |
407 | if (next_update_incr < 1) | ||
408 | next_update_incr = 1; | ||
409 | for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { | 407 | for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { |
410 | count = num - j; | 408 | count = num - j; |
411 | if (count > STRIDE_LENGTH) | 409 | if (count > STRIDE_LENGTH) |
diff --git a/e2fsprogs/old_e2fsprogs/tune2fs.c b/e2fsprogs/old_e2fsprogs/tune2fs.c index 3c3f4afa5..bbe30e5a0 100644 --- a/e2fsprogs/old_e2fsprogs/tune2fs.c +++ b/e2fsprogs/old_e2fsprogs/tune2fs.c | |||
@@ -607,7 +607,7 @@ int tune2fs_main(int argc, char **argv) | |||
607 | if (e_flag) { | 607 | if (e_flag) { |
608 | sb->s_errors = errors; | 608 | sb->s_errors = errors; |
609 | ext2fs_mark_super_dirty(fs); | 609 | ext2fs_mark_super_dirty(fs); |
610 | printf("Setting error behavior to %d\n", errors); | 610 | printf("Setting error behavior to %u\n", errors); |
611 | } | 611 | } |
612 | if (g_flag) { | 612 | if (g_flag) { |
613 | sb->s_def_resgid = resgid; | 613 | sb->s_def_resgid = resgid; |
diff --git a/e2fsprogs/old_e2fsprogs/util.c b/e2fsprogs/old_e2fsprogs/util.c index a61abc2c6..3e7ee8e75 100644 --- a/e2fsprogs/old_e2fsprogs/util.c +++ b/e2fsprogs/old_e2fsprogs/util.c | |||
@@ -117,7 +117,7 @@ void parse_journal_opts(char **journal_device, int *journal_flags, | |||
117 | } | 117 | } |
118 | if (strcmp(token, "device") == 0) { | 118 | if (strcmp(token, "device") == 0) { |
119 | *journal_device = blkid_get_devname(NULL, arg, NULL); | 119 | *journal_device = blkid_get_devname(NULL, arg, NULL); |
120 | if (!journal_device) { | 120 | if (!*journal_device) { |
121 | journal_usage++; | 121 | journal_usage++; |
122 | continue; | 122 | continue; |
123 | } | 123 | } |
@@ -239,7 +239,7 @@ void make_journal_blocks(ext2_filsys fs, int journal_size, int journal_flags, in | |||
239 | return; | 239 | return; |
240 | } | 240 | } |
241 | if (!quiet) | 241 | if (!quiet) |
242 | printf("Creating journal (%ld blocks): ", journal_blocks); | 242 | printf("Creating journal (%lu blocks): ", journal_blocks); |
243 | fflush(stdout); | 243 | fflush(stdout); |
244 | retval = ext2fs_add_journal_inode(fs, journal_blocks, | 244 | retval = ext2fs_add_journal_inode(fs, journal_blocks, |
245 | journal_flags); | 245 | journal_flags); |
diff --git a/editors/Config.src b/editors/Config.src index af1e1de5e..c6e9d92af 100644 --- a/editors/Config.src +++ b/editors/Config.src | |||
@@ -7,66 +7,6 @@ menu "Editors" | |||
7 | 7 | ||
8 | INSERT | 8 | INSERT |
9 | 9 | ||
10 | config AWK | ||
11 | bool "awk" | ||
12 | default y | ||
13 | help | ||
14 | Awk is used as a pattern scanning and processing language. This is | ||
15 | the BusyBox implementation of that programming language. | ||
16 | |||
17 | config FEATURE_AWK_LIBM | ||
18 | bool "Enable math functions (requires libm)" | ||
19 | default y | ||
20 | depends on AWK | ||
21 | help | ||
22 | Enable math functions of the Awk programming language. | ||
23 | NOTE: This will require libm to be present for linking. | ||
24 | |||
25 | config CMP | ||
26 | bool "cmp" | ||
27 | default y | ||
28 | help | ||
29 | cmp is used to compare two files and returns the result | ||
30 | to standard output. | ||
31 | |||
32 | config DIFF | ||
33 | bool "diff" | ||
34 | default y | ||
35 | help | ||
36 | diff compares two files or directories and outputs the | ||
37 | differences between them in a form that can be given to | ||
38 | the patch command. | ||
39 | |||
40 | config FEATURE_DIFF_LONG_OPTIONS | ||
41 | bool "Enable long options" | ||
42 | default y | ||
43 | depends on DIFF && LONG_OPTS | ||
44 | help | ||
45 | Enable use of long options. | ||
46 | |||
47 | config FEATURE_DIFF_DIR | ||
48 | bool "Enable directory support" | ||
49 | default y | ||
50 | depends on DIFF | ||
51 | help | ||
52 | This option enables support for directory and subdirectory | ||
53 | comparison. | ||
54 | |||
55 | config ED | ||
56 | bool "ed" | ||
57 | default y | ||
58 | help | ||
59 | The original 1970's Unix text editor, from the days of teletypes. | ||
60 | Small, simple, evil. Part of SUSv3. If you're not already using | ||
61 | this, you don't need it. | ||
62 | |||
63 | config SED | ||
64 | bool "sed" | ||
65 | default y | ||
66 | help | ||
67 | sed is used to perform text transformations on a file | ||
68 | or input from a pipeline. | ||
69 | |||
70 | config FEATURE_ALLOW_EXEC | 10 | config FEATURE_ALLOW_EXEC |
71 | bool "Allow vi and awk to execute shell commands" | 11 | bool "Allow vi and awk to execute shell commands" |
72 | default y | 12 | default y |
diff --git a/editors/Kbuild.src b/editors/Kbuild.src index 8888cba12..6b4fb7470 100644 --- a/editors/Kbuild.src +++ b/editors/Kbuild.src | |||
@@ -7,8 +7,3 @@ | |||
7 | lib-y:= | 7 | lib-y:= |
8 | 8 | ||
9 | INSERT | 9 | INSERT |
10 | lib-$(CONFIG_AWK) += awk.o | ||
11 | lib-$(CONFIG_CMP) += cmp.o | ||
12 | lib-$(CONFIG_DIFF) += diff.o | ||
13 | lib-$(CONFIG_ED) += ed.o | ||
14 | lib-$(CONFIG_SED) += sed.o | ||
diff --git a/editors/awk.c b/editors/awk.c index 77784dfc1..d0e3781e7 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -7,12 +7,45 @@ | |||
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 | 9 | ||
10 | //config:config AWK | ||
11 | //config: bool "awk" | ||
12 | //config: default y | ||
13 | //config: help | ||
14 | //config: Awk is used as a pattern scanning and processing language. This is | ||
15 | //config: the BusyBox implementation of that programming language. | ||
16 | //config: | ||
17 | //config:config FEATURE_AWK_LIBM | ||
18 | //config: bool "Enable math functions (requires libm)" | ||
19 | //config: default y | ||
20 | //config: depends on AWK | ||
21 | //config: help | ||
22 | //config: Enable math functions of the Awk programming language. | ||
23 | //config: NOTE: This will require libm to be present for linking. | ||
24 | //config: | ||
25 | //config:config FEATURE_AWK_GNU_EXTENSIONS | ||
26 | //config: bool "Enable a few GNU extensions" | ||
27 | //config: default y | ||
28 | //config: depends on AWK | ||
29 | //config: help | ||
30 | //config: Enable a few features from gawk: | ||
31 | //config: * command line option -e AWK_PROGRAM | ||
32 | //config: * simultaneous use of -f and -e on the command line. | ||
33 | //config: This enables the use of awk library files. | ||
34 | //config: Ex: awk -f mylib.awk -e '{print myfunction($1);}' ... | ||
35 | |||
36 | //applet:IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk)) | ||
37 | |||
38 | //kbuild:lib-$(CONFIG_AWK) += awk.o | ||
39 | |||
10 | //usage:#define awk_trivial_usage | 40 | //usage:#define awk_trivial_usage |
11 | //usage: "[OPTIONS] [AWK_PROGRAM] [FILE]..." | 41 | //usage: "[OPTIONS] [AWK_PROGRAM] [FILE]..." |
12 | //usage:#define awk_full_usage "\n\n" | 42 | //usage:#define awk_full_usage "\n\n" |
13 | //usage: " -v VAR=VAL Set variable" | 43 | //usage: " -v VAR=VAL Set variable" |
14 | //usage: "\n -F SEP Use SEP as field separator" | 44 | //usage: "\n -F SEP Use SEP as field separator" |
15 | //usage: "\n -f FILE Read program from FILE" | 45 | //usage: "\n -f FILE Read program from FILE" |
46 | //usage: IF_FEATURE_AWK_GNU_EXTENSIONS( | ||
47 | //usage: "\n -e AWK_PROGRAM" | ||
48 | //usage: ) | ||
16 | 49 | ||
17 | #include "libbb.h" | 50 | #include "libbb.h" |
18 | #include "xregex.h" | 51 | #include "xregex.h" |
@@ -38,6 +71,25 @@ | |||
38 | #endif | 71 | #endif |
39 | 72 | ||
40 | 73 | ||
74 | #define OPTSTR_AWK \ | ||
75 | "F:v:f:" \ | ||
76 | IF_FEATURE_AWK_GNU_EXTENSIONS("e:") \ | ||
77 | "W:" | ||
78 | #define OPTCOMPLSTR_AWK \ | ||
79 | "v::f::" \ | ||
80 | IF_FEATURE_AWK_GNU_EXTENSIONS("e::") | ||
81 | enum { | ||
82 | OPTBIT_F, /* define field separator */ | ||
83 | OPTBIT_v, /* define variable */ | ||
84 | OPTBIT_f, /* pull in awk program from file */ | ||
85 | IF_FEATURE_AWK_GNU_EXTENSIONS(OPTBIT_e,) /* -e AWK_PROGRAM */ | ||
86 | OPTBIT_W, /* -W ignored */ | ||
87 | OPT_F = 1 << OPTBIT_F, | ||
88 | OPT_v = 1 << OPTBIT_v, | ||
89 | OPT_f = 1 << OPTBIT_f, | ||
90 | OPT_e = IF_FEATURE_AWK_GNU_EXTENSIONS((1 << OPTBIT_e)) + 0, | ||
91 | OPT_W = 1 << OPTBIT_W | ||
92 | }; | ||
41 | 93 | ||
42 | #define MAXVARFMT 240 | 94 | #define MAXVARFMT 240 |
43 | #define MINNVBLOCK 64 | 95 | #define MINNVBLOCK 64 |
@@ -2784,8 +2836,16 @@ static var *evaluate(node *op, var *res) | |||
2784 | break; | 2836 | break; |
2785 | 2837 | ||
2786 | case F_le: | 2838 | case F_le: |
2787 | if (!op1) | 2839 | debug_printf_eval("length: L.s:'%s'\n", L.s); |
2840 | if (!op1) { | ||
2788 | L.s = getvar_s(intvar[F0]); | 2841 | L.s = getvar_s(intvar[F0]); |
2842 | debug_printf_eval("length: L.s='%s'\n", L.s); | ||
2843 | } | ||
2844 | else if (L.v->type & VF_ARRAY) { | ||
2845 | R_d = L.v->x.array->nel; | ||
2846 | debug_printf_eval("length: array_len:%d\n", L.v->x.array->nel); | ||
2847 | break; | ||
2848 | } | ||
2789 | R_d = strlen(L.s); | 2849 | R_d = strlen(L.s); |
2790 | break; | 2850 | break; |
2791 | 2851 | ||
@@ -3079,6 +3139,9 @@ int awk_main(int argc, char **argv) | |||
3079 | char *opt_F; | 3139 | char *opt_F; |
3080 | llist_t *list_v = NULL; | 3140 | llist_t *list_v = NULL; |
3081 | llist_t *list_f = NULL; | 3141 | llist_t *list_f = NULL; |
3142 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS | ||
3143 | llist_t *list_e = NULL; | ||
3144 | #endif | ||
3082 | int i, j; | 3145 | int i, j; |
3083 | var *v; | 3146 | var *v; |
3084 | var tv; | 3147 | var tv; |
@@ -3137,47 +3200,51 @@ int awk_main(int argc, char **argv) | |||
3137 | *s1 = '='; | 3200 | *s1 = '='; |
3138 | } | 3201 | } |
3139 | } | 3202 | } |
3140 | opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ | 3203 | opt_complementary = OPTCOMPLSTR_AWK; |
3141 | opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL); | 3204 | opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL); |
3142 | argv += optind; | 3205 | argv += optind; |
3143 | argc -= optind; | 3206 | argc -= optind; |
3144 | if (opt & 0x1) { /* -F */ | 3207 | if (opt & OPT_W) |
3208 | bb_error_msg("warning: option -W is ignored"); | ||
3209 | if (opt & OPT_F) { | ||
3145 | unescape_string_in_place(opt_F); | 3210 | unescape_string_in_place(opt_F); |
3146 | setvar_s(intvar[FS], opt_F); | 3211 | setvar_s(intvar[FS], opt_F); |
3147 | } | 3212 | } |
3148 | while (list_v) { /* -v */ | 3213 | while (list_v) { |
3149 | if (!is_assignment(llist_pop(&list_v))) | 3214 | if (!is_assignment(llist_pop(&list_v))) |
3150 | bb_show_usage(); | 3215 | bb_show_usage(); |
3151 | } | 3216 | } |
3152 | if (list_f) { /* -f */ | 3217 | while (list_f) { |
3153 | do { | 3218 | char *s = NULL; |
3154 | char *s = NULL; | 3219 | FILE *from_file; |
3155 | FILE *from_file; | 3220 | |
3156 | 3221 | g_progname = llist_pop(&list_f); | |
3157 | g_progname = llist_pop(&list_f); | 3222 | from_file = xfopen_stdin(g_progname); |
3158 | from_file = xfopen_stdin(g_progname); | 3223 | /* one byte is reserved for some trick in next_token */ |
3159 | /* one byte is reserved for some trick in next_token */ | 3224 | for (i = j = 1; j > 0; i += j) { |
3160 | for (i = j = 1; j > 0; i += j) { | 3225 | s = xrealloc(s, i + 4096); |
3161 | s = xrealloc(s, i + 4096); | 3226 | j = fread(s + i, 1, 4094, from_file); |
3162 | j = fread(s + i, 1, 4094, from_file); | 3227 | } |
3163 | } | 3228 | s[i] = '\0'; |
3164 | s[i] = '\0'; | 3229 | fclose(from_file); |
3165 | fclose(from_file); | 3230 | parse_program(s + 1); |
3166 | parse_program(s + 1); | 3231 | free(s); |
3167 | free(s); | 3232 | } |
3168 | } while (list_f); | 3233 | g_progname = "cmd. line"; |
3169 | argc++; | 3234 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS |
3170 | } else { // no -f: take program from 1st parameter | 3235 | while (list_e) { |
3171 | if (!argc) | 3236 | parse_program(llist_pop(&list_e)); |
3237 | } | ||
3238 | #endif | ||
3239 | if (!(opt & (OPT_f | OPT_e))) { | ||
3240 | if (!*argv) | ||
3172 | bb_show_usage(); | 3241 | bb_show_usage(); |
3173 | g_progname = "cmd. line"; | ||
3174 | parse_program(*argv++); | 3242 | parse_program(*argv++); |
3243 | argc--; | ||
3175 | } | 3244 | } |
3176 | if (opt & 0x8) // -W | ||
3177 | bb_error_msg("warning: option -W is ignored"); | ||
3178 | 3245 | ||
3179 | /* fill in ARGV array */ | 3246 | /* fill in ARGV array */ |
3180 | setvar_i(intvar[ARGC], argc); | 3247 | setvar_i(intvar[ARGC], argc + 1); |
3181 | setari_u(intvar[ARGV], 0, "awk"); | 3248 | setari_u(intvar[ARGV], 0, "awk"); |
3182 | i = 0; | 3249 | i = 0; |
3183 | while (*argv) | 3250 | while (*argv) |
diff --git a/editors/cmp.c b/editors/cmp.c index fbe6b9753..a4af6f480 100644 --- a/editors/cmp.c +++ b/editors/cmp.c | |||
@@ -10,6 +10,17 @@ | |||
10 | /* BB_AUDIT SUSv3 (virtually) compliant -- uses nicer GNU format for -l. */ | 10 | /* BB_AUDIT SUSv3 (virtually) compliant -- uses nicer GNU format for -l. */ |
11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cmp.html */ | 11 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cmp.html */ |
12 | 12 | ||
13 | //config:config CMP | ||
14 | //config: bool "cmp" | ||
15 | //config: default y | ||
16 | //config: help | ||
17 | //config: cmp is used to compare two files and returns the result | ||
18 | //config: to standard output. | ||
19 | |||
20 | //kbuild:lib-$(CONFIG_CMP) += cmp.o | ||
21 | |||
22 | //applet:IF_CMP(APPLET(cmp, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
23 | |||
13 | //usage:#define cmp_trivial_usage | 24 | //usage:#define cmp_trivial_usage |
14 | //usage: "[-l] [-s] FILE1 [FILE2" IF_DESKTOP(" [SKIP1 [SKIP2]]") "]" | 25 | //usage: "[-l] [-s] FILE1 [FILE2" IF_DESKTOP(" [SKIP1 [SKIP2]]") "]" |
15 | //usage:#define cmp_full_usage "\n\n" | 26 | //usage:#define cmp_full_usage "\n\n" |
diff --git a/editors/diff.c b/editors/diff.c index b08ded3a1..a78a0ee28 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -76,6 +76,33 @@ | |||
76 | * 6n words for files of length n. | 76 | * 6n words for files of length n. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | //config:config DIFF | ||
80 | //config: bool "diff" | ||
81 | //config: default y | ||
82 | //config: help | ||
83 | //config: diff compares two files or directories and outputs the | ||
84 | //config: differences between them in a form that can be given to | ||
85 | //config: the patch command. | ||
86 | //config: | ||
87 | //config:config FEATURE_DIFF_LONG_OPTIONS | ||
88 | //config: bool "Enable long options" | ||
89 | //config: default y | ||
90 | //config: depends on DIFF && LONG_OPTS | ||
91 | //config: help | ||
92 | //config: Enable use of long options. | ||
93 | //config: | ||
94 | //config:config FEATURE_DIFF_DIR | ||
95 | //config: bool "Enable directory support" | ||
96 | //config: default y | ||
97 | //config: depends on DIFF | ||
98 | //config: help | ||
99 | //config: This option enables support for directory and subdirectory | ||
100 | //config: comparison. | ||
101 | |||
102 | //kbuild:lib-$(CONFIG_DIFF) += diff.o | ||
103 | |||
104 | //applet:IF_DIFF(APPLET(diff, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
105 | |||
79 | //usage:#define diff_trivial_usage | 106 | //usage:#define diff_trivial_usage |
80 | //usage: "[-abBdiNqrTstw] [-L LABEL] [-S FILE] [-U LINES] FILE1 FILE2" | 107 | //usage: "[-abBdiNqrTstw] [-L LABEL] [-S FILE] [-U LINES] FILE1 FILE2" |
81 | //usage:#define diff_full_usage "\n\n" | 108 | //usage:#define diff_full_usage "\n\n" |
diff --git a/editors/ed.c b/editors/ed.c index dbb51306c..3087fb0b9 100644 --- a/editors/ed.c +++ b/editors/ed.c | |||
@@ -7,6 +7,18 @@ | |||
7 | * The "ed" built-in command (much simplified) | 7 | * The "ed" built-in command (much simplified) |
8 | */ | 8 | */ |
9 | 9 | ||
10 | //config:config ED | ||
11 | //config: bool "ed" | ||
12 | //config: default y | ||
13 | //config: help | ||
14 | //config: The original 1970's Unix text editor, from the days of teletypes. | ||
15 | //config: Small, simple, evil. Part of SUSv3. If you're not already using | ||
16 | //config: this, you don't need it. | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_ED) += ed.o | ||
19 | |||
20 | //applet:IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP)) | ||
21 | |||
10 | //usage:#define ed_trivial_usage "" | 22 | //usage:#define ed_trivial_usage "" |
11 | //usage:#define ed_full_usage "" | 23 | //usage:#define ed_full_usage "" |
12 | 24 | ||
diff --git a/editors/patch_bbox.c b/editors/patch_bbox.c index 78aa5fde8..aae7b7987 100644 --- a/editors/patch_bbox.c +++ b/editors/patch_bbox.c | |||
@@ -188,8 +188,8 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
188 | unsigned src_last_line = 1; | 188 | unsigned src_last_line = 1; |
189 | unsigned dst_last_line = 1; | 189 | unsigned dst_last_line = 1; |
190 | 190 | ||
191 | if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) | 191 | if ((sscanf(patch_line, "@@ -%u,%u +%u,%u", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) |
192 | && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) | 192 | && (sscanf(patch_line, "@@ -%u +%u,%u", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) |
193 | ) { | 193 | ) { |
194 | /* No more hunks for this file */ | 194 | /* No more hunks for this file */ |
195 | break; | 195 | break; |
diff --git a/editors/sed.c b/editors/sed.c index 3a0d917aa..e18e48ab5 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -23,9 +23,6 @@ | |||
23 | * resulting sed_cmd_t structures are appended to a linked list | 23 | * resulting sed_cmd_t structures are appended to a linked list |
24 | * (G.sed_cmd_head/G.sed_cmd_tail). | 24 | * (G.sed_cmd_head/G.sed_cmd_tail). |
25 | * | 25 | * |
26 | * add_input_file() adds a FILE* to the list of input files. We need to | ||
27 | * know all input sources ahead of time to find the last line for the $ match. | ||
28 | * | ||
29 | * process_files() does actual sedding, reading data lines from each input FILE* | 26 | * process_files() does actual sedding, reading data lines from each input FILE* |
30 | * (which could be stdin) and applying the sed command list (sed_cmd_head) to | 27 | * (which could be stdin) and applying the sed command list (sed_cmd_head) to |
31 | * each of the resulting lines. | 28 | * each of the resulting lines. |
@@ -58,16 +55,27 @@ | |||
58 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html | 55 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html |
59 | */ | 56 | */ |
60 | 57 | ||
58 | //config:config SED | ||
59 | //config: bool "sed" | ||
60 | //config: default y | ||
61 | //config: help | ||
62 | //config: sed is used to perform text transformations on a file | ||
63 | //config: or input from a pipeline. | ||
64 | |||
65 | //kbuild:lib-$(CONFIG_SED) += sed.o | ||
66 | |||
67 | //applet:IF_SED(APPLET(sed, BB_DIR_BIN, BB_SUID_DROP)) | ||
68 | |||
61 | //usage:#define sed_trivial_usage | 69 | //usage:#define sed_trivial_usage |
62 | //usage: "[-inr] [-f FILE]... [-e CMD]... [FILE]...\n" | 70 | //usage: "[-inrE] [-f FILE]... [-e CMD]... [FILE]...\n" |
63 | //usage: "or: sed [-inr] CMD [FILE]..." | 71 | //usage: "or: sed [-inrE] CMD [FILE]..." |
64 | //usage:#define sed_full_usage "\n\n" | 72 | //usage:#define sed_full_usage "\n\n" |
65 | //usage: " -e CMD Add CMD to sed commands to be executed" | 73 | //usage: " -e CMD Add CMD to sed commands to be executed" |
66 | //usage: "\n -f FILE Add FILE contents to sed commands to be executed" | 74 | //usage: "\n -f FILE Add FILE contents to sed commands to be executed" |
67 | //usage: "\n -i[SFX] Edit files in-place (otherwise sends to stdout)" | 75 | //usage: "\n -i[SFX] Edit files in-place (otherwise sends to stdout)" |
68 | //usage: "\n Optionally back files up, appending SFX" | 76 | //usage: "\n Optionally back files up, appending SFX" |
69 | //usage: "\n -n Suppress automatic printing of pattern space" | 77 | //usage: "\n -n Suppress automatic printing of pattern space" |
70 | //usage: "\n -r Use extended regex syntax" | 78 | //usage: "\n -r,-E Use extended regex syntax" |
71 | //usage: "\n" | 79 | //usage: "\n" |
72 | //usage: "\nIf no -e or -f, the first non-option argument is the sed command string." | 80 | //usage: "\nIf no -e or -f, the first non-option argument is the sed command string." |
73 | //usage: "\nRemaining arguments are input files (stdin if none)." | 81 | //usage: "\nRemaining arguments are input files (stdin if none)." |
@@ -124,12 +132,15 @@ static const char semicolon_whitespace[] ALIGN1 = "; \n\r\t\v"; | |||
124 | struct globals { | 132 | struct globals { |
125 | /* options */ | 133 | /* options */ |
126 | int be_quiet, regex_type; | 134 | int be_quiet, regex_type; |
135 | |||
127 | FILE *nonstdout; | 136 | FILE *nonstdout; |
128 | char *outname, *hold_space; | 137 | char *outname, *hold_space; |
138 | smallint exitcode; | ||
129 | 139 | ||
130 | /* List of input files */ | 140 | /* list of input files */ |
131 | int input_file_count, current_input_file; | 141 | int current_input_file, last_input_file; |
132 | FILE **input_file_list; | 142 | char **input_file_list; |
143 | FILE *current_fp; | ||
133 | 144 | ||
134 | regmatch_t regmatch[10]; | 145 | regmatch_t regmatch[10]; |
135 | regex_t *previous_regex_ptr; | 146 | regex_t *previous_regex_ptr; |
@@ -137,7 +148,7 @@ struct globals { | |||
137 | /* linked list of sed commands */ | 148 | /* linked list of sed commands */ |
138 | sed_cmd_t *sed_cmd_head, **sed_cmd_tail; | 149 | sed_cmd_t *sed_cmd_head, **sed_cmd_tail; |
139 | 150 | ||
140 | /* Linked list of append lines */ | 151 | /* linked list of append lines */ |
141 | llist_t *append_head; | 152 | llist_t *append_head; |
142 | 153 | ||
143 | char *add_cmd_line; | 154 | char *add_cmd_line; |
@@ -189,8 +200,8 @@ static void sed_free_and_close_stuff(void) | |||
189 | 200 | ||
190 | free(G.hold_space); | 201 | free(G.hold_space); |
191 | 202 | ||
192 | while (G.current_input_file < G.input_file_count) | 203 | if (G.current_fp) |
193 | fclose(G.input_file_list[G.current_input_file++]); | 204 | fclose(G.current_fp); |
194 | } | 205 | } |
195 | #else | 206 | #else |
196 | void sed_free_and_close_stuff(void); | 207 | void sed_free_and_close_stuff(void); |
@@ -370,7 +381,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | |||
370 | 381 | ||
371 | /* | 382 | /* |
372 | * A substitution command should look something like this: | 383 | * A substitution command should look something like this: |
373 | * s/match/replace/ #gIpw | 384 | * s/match/replace/ #giIpw |
374 | * || | ||| | 385 | * || | ||| |
375 | * mandatory optional | 386 | * mandatory optional |
376 | */ | 387 | */ |
@@ -418,6 +429,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | |||
418 | break; | 429 | break; |
419 | } | 430 | } |
420 | /* Ignore case (gnu exension) */ | 431 | /* Ignore case (gnu exension) */ |
432 | case 'i': | ||
421 | case 'I': | 433 | case 'I': |
422 | cflags |= REG_ICASE; | 434 | cflags |= REG_ICASE; |
423 | break; | 435 | break; |
@@ -848,46 +860,100 @@ static sed_cmd_t *branch_to(char *label) | |||
848 | 860 | ||
849 | static void append(char *s) | 861 | static void append(char *s) |
850 | { | 862 | { |
851 | llist_add_to_end(&G.append_head, xstrdup(s)); | 863 | llist_add_to_end(&G.append_head, s); |
852 | } | 864 | } |
853 | 865 | ||
854 | static void flush_append(void) | 866 | /* Output line of text. */ |
867 | /* Note: | ||
868 | * The tricks with NO_EOL_CHAR and last_puts_char are there to emulate gnu sed. | ||
869 | * Without them, we had this: | ||
870 | * echo -n thingy >z1 | ||
871 | * echo -n again >z2 | ||
872 | * >znull | ||
873 | * sed "s/i/z/" z1 z2 znull | hexdump -vC | ||
874 | * output: | ||
875 | * gnu sed 4.1.5: | ||
876 | * 00000000 74 68 7a 6e 67 79 0a 61 67 61 7a 6e |thzngy.agazn| | ||
877 | * bbox: | ||
878 | * 00000000 74 68 7a 6e 67 79 61 67 61 7a 6e |thzngyagazn| | ||
879 | */ | ||
880 | enum { | ||
881 | NO_EOL_CHAR = 1, | ||
882 | LAST_IS_NUL = 2, | ||
883 | }; | ||
884 | static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char last_gets_char) | ||
885 | { | ||
886 | char lpc = *last_puts_char; | ||
887 | |||
888 | /* Need to insert a '\n' between two files because first file's | ||
889 | * last line wasn't terminated? */ | ||
890 | if (lpc != '\n' && lpc != '\0') { | ||
891 | fputc('\n', file); | ||
892 | lpc = '\n'; | ||
893 | } | ||
894 | fputs(s, file); | ||
895 | |||
896 | /* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */ | ||
897 | if (s[0]) | ||
898 | lpc = 'x'; | ||
899 | |||
900 | /* had trailing '\0' and it was last char of file? */ | ||
901 | if (last_gets_char == LAST_IS_NUL) { | ||
902 | fputc('\0', file); | ||
903 | lpc = 'x'; /* */ | ||
904 | } else | ||
905 | /* had trailing '\n' or '\0'? */ | ||
906 | if (last_gets_char != NO_EOL_CHAR) { | ||
907 | fputc(last_gets_char, file); | ||
908 | lpc = last_gets_char; | ||
909 | } | ||
910 | |||
911 | if (ferror(file)) { | ||
912 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ | ||
913 | bb_error_msg_and_die(bb_msg_write_error); | ||
914 | } | ||
915 | *last_puts_char = lpc; | ||
916 | } | ||
917 | |||
918 | static void flush_append(char *last_puts_char, char last_gets_char) | ||
855 | { | 919 | { |
856 | char *data; | 920 | char *data; |
857 | 921 | ||
858 | /* Output appended lines. */ | 922 | /* Output appended lines. */ |
859 | while ((data = (char *)llist_pop(&G.append_head))) { | 923 | while ((data = (char *)llist_pop(&G.append_head))) { |
860 | fprintf(G.nonstdout, "%s\n", data); | 924 | puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char); |
861 | free(data); | 925 | free(data); |
862 | } | 926 | } |
863 | } | 927 | } |
864 | 928 | ||
865 | static void add_input_file(FILE *file) | ||
866 | { | ||
867 | G.input_file_list = xrealloc_vector(G.input_file_list, 2, G.input_file_count); | ||
868 | G.input_file_list[G.input_file_count++] = file; | ||
869 | } | ||
870 | |||
871 | /* Get next line of input from G.input_file_list, flushing append buffer and | 929 | /* Get next line of input from G.input_file_list, flushing append buffer and |
872 | * noting if we ran out of files without a newline on the last line we read. | 930 | * noting if we ran out of files without a newline on the last line we read. |
873 | */ | 931 | */ |
874 | enum { | 932 | static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets_char) |
875 | NO_EOL_CHAR = 1, | ||
876 | LAST_IS_NUL = 2, | ||
877 | }; | ||
878 | static char *get_next_line(char *gets_char) | ||
879 | { | 933 | { |
880 | char *temp = NULL; | 934 | char *temp = NULL; |
881 | int len; | 935 | int len; |
882 | char gc; | 936 | char gc; |
883 | 937 | ||
884 | flush_append(); | 938 | flush_append(last_puts_char, last_gets_char); |
885 | 939 | ||
886 | /* will be returned if last line in the file | 940 | /* will be returned if last line in the file |
887 | * doesn't end with either '\n' or '\0' */ | 941 | * doesn't end with either '\n' or '\0' */ |
888 | gc = NO_EOL_CHAR; | 942 | gc = NO_EOL_CHAR; |
889 | while (G.current_input_file < G.input_file_count) { | 943 | for (; G.current_input_file <= G.last_input_file; G.current_input_file++) { |
890 | FILE *fp = G.input_file_list[G.current_input_file]; | 944 | FILE *fp = G.current_fp; |
945 | if (!fp) { | ||
946 | const char *path = G.input_file_list[G.current_input_file]; | ||
947 | fp = stdin; | ||
948 | if (path != bb_msg_standard_input) { | ||
949 | fp = fopen_or_warn(path, "r"); | ||
950 | if (!fp) { | ||
951 | G.exitcode = EXIT_FAILURE; | ||
952 | continue; | ||
953 | } | ||
954 | } | ||
955 | G.current_fp = fp; | ||
956 | } | ||
891 | /* Read line up to a newline or NUL byte, inclusive, | 957 | /* Read line up to a newline or NUL byte, inclusive, |
892 | * return malloc'ed char[]. length of the chunk read | 958 | * return malloc'ed char[]. length of the chunk read |
893 | * is stored in len. NULL if EOF/error */ | 959 | * is stored in len. NULL if EOF/error */ |
@@ -918,61 +984,13 @@ static char *get_next_line(char *gets_char) | |||
918 | * (note: *no* newline after "b bang"!) */ | 984 | * (note: *no* newline after "b bang"!) */ |
919 | } | 985 | } |
920 | /* Close this file and advance to next one */ | 986 | /* Close this file and advance to next one */ |
921 | fclose(fp); | 987 | fclose_if_not_stdin(fp); |
922 | G.current_input_file++; | 988 | G.current_fp = NULL; |
923 | } | 989 | } |
924 | *gets_char = gc; | 990 | *gets_char = gc; |
925 | return temp; | 991 | return temp; |
926 | } | 992 | } |
927 | 993 | ||
928 | /* Output line of text. */ | ||
929 | /* Note: | ||
930 | * The tricks with NO_EOL_CHAR and last_puts_char are there to emulate gnu sed. | ||
931 | * Without them, we had this: | ||
932 | * echo -n thingy >z1 | ||
933 | * echo -n again >z2 | ||
934 | * >znull | ||
935 | * sed "s/i/z/" z1 z2 znull | hexdump -vC | ||
936 | * output: | ||
937 | * gnu sed 4.1.5: | ||
938 | * 00000000 74 68 7a 6e 67 79 0a 61 67 61 7a 6e |thzngy.agazn| | ||
939 | * bbox: | ||
940 | * 00000000 74 68 7a 6e 67 79 61 67 61 7a 6e |thzngyagazn| | ||
941 | */ | ||
942 | static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char last_gets_char) | ||
943 | { | ||
944 | char lpc = *last_puts_char; | ||
945 | |||
946 | /* Need to insert a '\n' between two files because first file's | ||
947 | * last line wasn't terminated? */ | ||
948 | if (lpc != '\n' && lpc != '\0') { | ||
949 | fputc('\n', file); | ||
950 | lpc = '\n'; | ||
951 | } | ||
952 | fputs(s, file); | ||
953 | |||
954 | /* 'x' - just something which is not '\n', '\0' or NO_EOL_CHAR */ | ||
955 | if (s[0]) | ||
956 | lpc = 'x'; | ||
957 | |||
958 | /* had trailing '\0' and it was last char of file? */ | ||
959 | if (last_gets_char == LAST_IS_NUL) { | ||
960 | fputc('\0', file); | ||
961 | lpc = 'x'; /* */ | ||
962 | } else | ||
963 | /* had trailing '\n' or '\0'? */ | ||
964 | if (last_gets_char != NO_EOL_CHAR) { | ||
965 | fputc(last_gets_char, file); | ||
966 | lpc = last_gets_char; | ||
967 | } | ||
968 | |||
969 | if (ferror(file)) { | ||
970 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ | ||
971 | bb_error_msg_and_die(bb_msg_write_error); | ||
972 | } | ||
973 | *last_puts_char = lpc; | ||
974 | } | ||
975 | |||
976 | #define sed_puts(s, n) (puts_maybe_newline(s, G.nonstdout, &last_puts_char, n)) | 994 | #define sed_puts(s, n) (puts_maybe_newline(s, G.nonstdout, &last_puts_char, n)) |
977 | 995 | ||
978 | static int beg_match(sed_cmd_t *sed_cmd, const char *pattern_space) | 996 | static int beg_match(sed_cmd_t *sed_cmd, const char *pattern_space) |
@@ -995,7 +1013,7 @@ static void process_files(void) | |||
995 | int substituted; | 1013 | int substituted; |
996 | 1014 | ||
997 | /* Prime the pump */ | 1015 | /* Prime the pump */ |
998 | next_line = get_next_line(&next_gets_char); | 1016 | next_line = get_next_line(&next_gets_char, &last_puts_char, '\n' /*last_gets_char*/); |
999 | 1017 | ||
1000 | /* Go through every line in each file */ | 1018 | /* Go through every line in each file */ |
1001 | again: | 1019 | again: |
@@ -1009,7 +1027,7 @@ static void process_files(void) | |||
1009 | 1027 | ||
1010 | /* Read one line in advance so we can act on the last line, | 1028 | /* Read one line in advance so we can act on the last line, |
1011 | * the '$' address */ | 1029 | * the '$' address */ |
1012 | next_line = get_next_line(&next_gets_char); | 1030 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); |
1013 | linenum++; | 1031 | linenum++; |
1014 | 1032 | ||
1015 | /* For every line, go through all the commands */ | 1033 | /* For every line, go through all the commands */ |
@@ -1181,7 +1199,7 @@ static void process_files(void) | |||
1181 | 1199 | ||
1182 | /* Append line to linked list to be printed later */ | 1200 | /* Append line to linked list to be printed later */ |
1183 | case 'a': | 1201 | case 'a': |
1184 | append(sed_cmd->string); | 1202 | append(xstrdup(sed_cmd->string)); |
1185 | break; | 1203 | break; |
1186 | 1204 | ||
1187 | /* Insert text before this line */ | 1205 | /* Insert text before this line */ |
@@ -1203,11 +1221,10 @@ static void process_files(void) | |||
1203 | rfile = fopen_for_read(sed_cmd->string); | 1221 | rfile = fopen_for_read(sed_cmd->string); |
1204 | if (rfile) { | 1222 | if (rfile) { |
1205 | char *line; | 1223 | char *line; |
1206 | |||
1207 | while ((line = xmalloc_fgetline(rfile)) | 1224 | while ((line = xmalloc_fgetline(rfile)) |
1208 | != NULL) | 1225 | != NULL) |
1209 | append(line); | 1226 | append(line); |
1210 | xprint_and_close_file(rfile); | 1227 | fclose(rfile); |
1211 | } | 1228 | } |
1212 | 1229 | ||
1213 | break; | 1230 | break; |
@@ -1228,7 +1245,7 @@ static void process_files(void) | |||
1228 | free(pattern_space); | 1245 | free(pattern_space); |
1229 | pattern_space = next_line; | 1246 | pattern_space = next_line; |
1230 | last_gets_char = next_gets_char; | 1247 | last_gets_char = next_gets_char; |
1231 | next_line = get_next_line(&next_gets_char); | 1248 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); |
1232 | substituted = 0; | 1249 | substituted = 0; |
1233 | linenum++; | 1250 | linenum++; |
1234 | break; | 1251 | break; |
@@ -1264,7 +1281,7 @@ static void process_files(void) | |||
1264 | pattern_space[len] = '\n'; | 1281 | pattern_space[len] = '\n'; |
1265 | strcpy(pattern_space + len+1, next_line); | 1282 | strcpy(pattern_space + len+1, next_line); |
1266 | last_gets_char = next_gets_char; | 1283 | last_gets_char = next_gets_char; |
1267 | next_line = get_next_line(&next_gets_char); | 1284 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); |
1268 | linenum++; | 1285 | linenum++; |
1269 | break; | 1286 | break; |
1270 | } | 1287 | } |
@@ -1368,7 +1385,7 @@ static void process_files(void) | |||
1368 | 1385 | ||
1369 | /* Delete and such jump here. */ | 1386 | /* Delete and such jump here. */ |
1370 | discard_line: | 1387 | discard_line: |
1371 | flush_append(); | 1388 | flush_append(&last_puts_char, last_gets_char); |
1372 | free(pattern_space); | 1389 | free(pattern_space); |
1373 | 1390 | ||
1374 | goto again; | 1391 | goto again; |
@@ -1413,8 +1430,6 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1413 | "file\0" Required_argument "f"; | 1430 | "file\0" Required_argument "f"; |
1414 | #endif | 1431 | #endif |
1415 | 1432 | ||
1416 | int status = EXIT_SUCCESS; | ||
1417 | |||
1418 | INIT_G(); | 1433 | INIT_G(); |
1419 | 1434 | ||
1420 | /* destroy command strings on exit */ | 1435 | /* destroy command strings on exit */ |
@@ -1435,15 +1450,21 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1435 | IF_LONG_OPTS(applet_long_options = sed_longopts); | 1450 | IF_LONG_OPTS(applet_long_options = sed_longopts); |
1436 | 1451 | ||
1437 | /* -i must be first, to match OPT_in_place definition */ | 1452 | /* -i must be first, to match OPT_in_place definition */ |
1438 | opt = getopt32(argv, "i::rne:f:", &opt_i, &opt_e, &opt_f, | 1453 | /* -E is a synonym of -r: |
1454 | * GNU sed 4.2.1 mentions it in neither --help | ||
1455 | * nor manpage, but does recognize it. | ||
1456 | */ | ||
1457 | opt = getopt32(argv, "i::rEne:f:", &opt_i, &opt_e, &opt_f, | ||
1439 | &G.be_quiet); /* counter for -n */ | 1458 | &G.be_quiet); /* counter for -n */ |
1440 | //argc -= optind; | 1459 | //argc -= optind; |
1441 | argv += optind; | 1460 | argv += optind; |
1442 | if (opt & OPT_in_place) { // -i | 1461 | if (opt & OPT_in_place) { // -i |
1443 | atexit(cleanup_outname); | 1462 | atexit(cleanup_outname); |
1444 | } | 1463 | } |
1445 | if (opt & 0x2) G.regex_type |= REG_EXTENDED; // -r | 1464 | if (opt & (2|4)) |
1446 | //if (opt & 0x4) G.be_quiet++; // -n | 1465 | G.regex_type |= REG_EXTENDED; // -r or -E |
1466 | //if (opt & 8) | ||
1467 | // G.be_quiet++; // -n (implemented with a counter instead) | ||
1447 | while (opt_e) { // -e | 1468 | while (opt_e) { // -e |
1448 | add_cmd_block(llist_pop(&opt_e)); | 1469 | add_cmd_block(llist_pop(&opt_e)); |
1449 | } | 1470 | } |
@@ -1458,7 +1479,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1458 | fclose(cmdfile); | 1479 | fclose(cmdfile); |
1459 | } | 1480 | } |
1460 | /* if we didn't get a pattern from -e or -f, use argv[0] */ | 1481 | /* if we didn't get a pattern from -e or -f, use argv[0] */ |
1461 | if (!(opt & 0x18)) { | 1482 | if (!(opt & 0x30)) { |
1462 | if (!*argv) | 1483 | if (!*argv) |
1463 | bb_show_usage(); | 1484 | bb_show_usage(); |
1464 | add_cmd_block(*argv++); | 1485 | add_cmd_block(*argv++); |
@@ -1472,42 +1493,38 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1472 | /* argv[0..(argc-1)] should be names of file to process. If no | 1493 | /* argv[0..(argc-1)] should be names of file to process. If no |
1473 | * files were specified or '-' was specified, take input from stdin. | 1494 | * files were specified or '-' was specified, take input from stdin. |
1474 | * Otherwise, we process all the files specified. */ | 1495 | * Otherwise, we process all the files specified. */ |
1475 | if (argv[0] == NULL) { | 1496 | G.input_file_list = argv; |
1497 | if (!argv[0]) { | ||
1476 | if (opt & OPT_in_place) | 1498 | if (opt & OPT_in_place) |
1477 | bb_error_msg_and_die(bb_msg_requires_arg, "-i"); | 1499 | bb_error_msg_and_die(bb_msg_requires_arg, "-i"); |
1478 | add_input_file(stdin); | 1500 | argv[0] = (char*)bb_msg_standard_input; |
1501 | /* G.last_input_file = 0; - already is */ | ||
1479 | } else { | 1502 | } else { |
1480 | int i; | 1503 | goto start; |
1481 | 1504 | ||
1482 | for (i = 0; argv[i]; i++) { | 1505 | for (; *argv; argv++) { |
1483 | struct stat statbuf; | 1506 | struct stat statbuf; |
1484 | int nonstdoutfd; | 1507 | int nonstdoutfd; |
1485 | FILE *file; | ||
1486 | sed_cmd_t *sed_cmd; | 1508 | sed_cmd_t *sed_cmd; |
1487 | 1509 | ||
1488 | if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { | 1510 | G.last_input_file++; |
1489 | add_input_file(stdin); | 1511 | start: |
1490 | process_files(); | ||
1491 | continue; | ||
1492 | } | ||
1493 | file = fopen_or_warn(argv[i], "r"); | ||
1494 | if (!file) { | ||
1495 | status = EXIT_FAILURE; | ||
1496 | continue; | ||
1497 | } | ||
1498 | add_input_file(file); | ||
1499 | if (!(opt & OPT_in_place)) { | 1512 | if (!(opt & OPT_in_place)) { |
1513 | if (LONE_DASH(*argv)) { | ||
1514 | *argv = (char*)bb_msg_standard_input; | ||
1515 | process_files(); | ||
1516 | } | ||
1500 | continue; | 1517 | continue; |
1501 | } | 1518 | } |
1502 | 1519 | ||
1503 | /* -i: process each FILE separately: */ | 1520 | /* -i: process each FILE separately: */ |
1504 | 1521 | ||
1505 | G.outname = xasprintf("%sXXXXXX", argv[i]); | 1522 | G.outname = xasprintf("%sXXXXXX", *argv); |
1506 | nonstdoutfd = xmkstemp(G.outname); | 1523 | nonstdoutfd = xmkstemp(G.outname); |
1507 | G.nonstdout = xfdopen_for_write(nonstdoutfd); | 1524 | G.nonstdout = xfdopen_for_write(nonstdoutfd); |
1508 | 1525 | ||
1509 | /* Set permissions/owner of output file */ | 1526 | /* Set permissions/owner of output file */ |
1510 | fstat(fileno(file), &statbuf); | 1527 | stat(*argv, &statbuf); |
1511 | /* chmod'ing AFTER chown would preserve suid/sgid bits, | 1528 | /* chmod'ing AFTER chown would preserve suid/sgid bits, |
1512 | * but GNU sed 4.2.1 does not preserve them either */ | 1529 | * but GNU sed 4.2.1 does not preserve them either */ |
1513 | fchmod(nonstdoutfd, statbuf.st_mode); | 1530 | fchmod(nonstdoutfd, statbuf.st_mode); |
@@ -1518,12 +1535,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1518 | G.nonstdout = stdout; | 1535 | G.nonstdout = stdout; |
1519 | 1536 | ||
1520 | if (opt_i) { | 1537 | if (opt_i) { |
1521 | char *backupname = xasprintf("%s%s", argv[i], opt_i); | 1538 | char *backupname = xasprintf("%s%s", *argv, opt_i); |
1522 | xrename(argv[i], backupname); | 1539 | xrename(*argv, backupname); |
1523 | free(backupname); | 1540 | free(backupname); |
1524 | } | 1541 | } |
1525 | /* else unlink(argv[i]); - rename below does this */ | 1542 | /* else unlink(*argv); - rename below does this */ |
1526 | xrename(G.outname, argv[i]); //TODO: rollback backup on error? | 1543 | xrename(G.outname, *argv); //TODO: rollback backup on error? |
1527 | free(G.outname); | 1544 | free(G.outname); |
1528 | G.outname = NULL; | 1545 | G.outname = NULL; |
1529 | 1546 | ||
@@ -1533,12 +1550,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |||
1533 | } | 1550 | } |
1534 | } | 1551 | } |
1535 | /* Here, to handle "sed 'cmds' nonexistent_file" case we did: | 1552 | /* Here, to handle "sed 'cmds' nonexistent_file" case we did: |
1536 | * if (G.current_input_file >= G.input_file_count) | 1553 | * if (G.current_input_file[G.current_input_file] == NULL) |
1537 | * return status; | 1554 | * return G.exitcode; |
1538 | * but it's not needed since process_files() works correctly | 1555 | * but it's not needed since process_files() works correctly |
1539 | * in this case too. */ | 1556 | * in this case too. */ |
1540 | } | 1557 | } |
1558 | |||
1541 | process_files(); | 1559 | process_files(); |
1542 | 1560 | ||
1543 | return status; | 1561 | return G.exitcode; |
1544 | } | 1562 | } |
diff --git a/include/applets.src.h b/include/applets.src.h index aa319bbc9..7dbd4c7f3 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
@@ -79,16 +79,13 @@ IF_ACPID(APPLET(acpid, BB_DIR_SBIN, BB_SUID_DROP)) | |||
79 | IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 79 | IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
80 | IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 80 | IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
81 | IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) | 81 | IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) |
82 | IF_AR(APPLET(ar, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
83 | IF_ARP(APPLET(arp, BB_DIR_SBIN, BB_SUID_DROP)) | 82 | IF_ARP(APPLET(arp, BB_DIR_SBIN, BB_SUID_DROP)) |
84 | IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 83 | IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
85 | IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk)) | ||
86 | IF_BASENAME(APPLET_NOFORK(basename, basename, BB_DIR_USR_BIN, BB_SUID_DROP, basename)) | 84 | IF_BASENAME(APPLET_NOFORK(basename, basename, BB_DIR_USR_BIN, BB_SUID_DROP, basename)) |
87 | IF_BBCONFIG(APPLET(bbconfig, BB_DIR_BIN, BB_SUID_DROP)) | 85 | IF_BBCONFIG(APPLET(bbconfig, BB_DIR_BIN, BB_SUID_DROP)) |
88 | IF_BEEP(APPLET(beep, BB_DIR_USR_BIN, BB_SUID_DROP)) | 86 | IF_BEEP(APPLET(beep, BB_DIR_USR_BIN, BB_SUID_DROP)) |
89 | IF_BLKID(APPLET(blkid, BB_DIR_SBIN, BB_SUID_DROP)) | 87 | IF_BLKID(APPLET(blkid, BB_DIR_SBIN, BB_SUID_DROP)) |
90 | IF_BRCTL(APPLET(brctl, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 88 | IF_BRCTL(APPLET(brctl, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
91 | IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
92 | IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) | 89 | IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) |
93 | IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) | 90 | IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) |
94 | IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) | 91 | IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) |
@@ -105,10 +102,8 @@ IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) | |||
105 | IF_CHVT(APPLET(chvt, BB_DIR_USR_BIN, BB_SUID_DROP)) | 102 | IF_CHVT(APPLET(chvt, BB_DIR_USR_BIN, BB_SUID_DROP)) |
106 | IF_CKSUM(APPLET_NOEXEC(cksum, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) | 103 | IF_CKSUM(APPLET_NOEXEC(cksum, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) |
107 | IF_CLEAR(APPLET(clear, BB_DIR_USR_BIN, BB_SUID_DROP)) | 104 | IF_CLEAR(APPLET(clear, BB_DIR_USR_BIN, BB_SUID_DROP)) |
108 | IF_CMP(APPLET(cmp, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
109 | IF_COMM(APPLET(comm, BB_DIR_USR_BIN, BB_SUID_DROP)) | 105 | IF_COMM(APPLET(comm, BB_DIR_USR_BIN, BB_SUID_DROP)) |
110 | IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) | 106 | IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) |
111 | IF_CPIO(APPLET(cpio, BB_DIR_BIN, BB_SUID_DROP)) | ||
112 | IF_CROND(APPLET(crond, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 107 | IF_CROND(APPLET(crond, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
113 | /* Needs to be run by root or be suid root - needs to change /var/spool/cron* files: */ | 108 | /* Needs to be run by root or be suid root - needs to change /var/spool/cron* files: */ |
114 | IF_CRONTAB(APPLET(crontab, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) | 109 | IF_CRONTAB(APPLET(crontab, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) |
@@ -123,21 +118,17 @@ IF_DEVFSD(APPLET(devfsd, BB_DIR_SBIN, BB_SUID_DROP)) | |||
123 | IF_DEVMEM(APPLET(devmem, BB_DIR_SBIN, BB_SUID_DROP)) | 118 | IF_DEVMEM(APPLET(devmem, BB_DIR_SBIN, BB_SUID_DROP)) |
124 | IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) | 119 | IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) |
125 | IF_DHCPRELAY(APPLET(dhcprelay, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 120 | IF_DHCPRELAY(APPLET(dhcprelay, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
126 | IF_DIFF(APPLET(diff, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
127 | IF_DIRNAME(APPLET_NOFORK(dirname, dirname, BB_DIR_USR_BIN, BB_SUID_DROP, dirname)) | 121 | IF_DIRNAME(APPLET_NOFORK(dirname, dirname, BB_DIR_USR_BIN, BB_SUID_DROP, dirname)) |
128 | IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP)) | 122 | IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP)) |
129 | IF_DNSD(APPLET(dnsd, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 123 | IF_DNSD(APPLET(dnsd, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
130 | IF_HOSTNAME(APPLET_ODDNAME(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) | 124 | IF_HOSTNAME(APPLET_ODDNAME(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) |
131 | IF_DOS2UNIX(APPLET_NOEXEC(dos2unix, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, dos2unix)) | 125 | IF_DOS2UNIX(APPLET_NOEXEC(dos2unix, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, dos2unix)) |
132 | IF_DPKG(APPLET(dpkg, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
133 | IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb)) | ||
134 | IF_DU(APPLET(du, BB_DIR_USR_BIN, BB_SUID_DROP)) | 126 | IF_DU(APPLET(du, BB_DIR_USR_BIN, BB_SUID_DROP)) |
135 | IF_DUMPKMAP(APPLET(dumpkmap, BB_DIR_BIN, BB_SUID_DROP)) | 127 | IF_DUMPKMAP(APPLET(dumpkmap, BB_DIR_BIN, BB_SUID_DROP)) |
136 | IF_DUMPLEASES(APPLET(dumpleases, BB_DIR_USR_BIN, BB_SUID_DROP)) | 128 | IF_DUMPLEASES(APPLET(dumpleases, BB_DIR_USR_BIN, BB_SUID_DROP)) |
137 | //IF_E2FSCK(APPLET(e2fsck, BB_DIR_SBIN, BB_SUID_DROP)) | 129 | //IF_E2FSCK(APPLET(e2fsck, BB_DIR_SBIN, BB_SUID_DROP)) |
138 | //IF_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, BB_DIR_SBIN, BB_SUID_DROP, e2label)) | 130 | //IF_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, BB_DIR_SBIN, BB_SUID_DROP, e2label)) |
139 | IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) | 131 | IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) |
140 | IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP)) | ||
141 | IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) | 132 | IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) |
142 | IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) | 133 | IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) |
143 | IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) | 134 | IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) |
@@ -176,8 +167,6 @@ IF_GETENFORCE(APPLET(getenforce, BB_DIR_USR_SBIN, BB_SUID_DROP)) | |||
176 | IF_GETOPT(APPLET(getopt, BB_DIR_BIN, BB_SUID_DROP)) | 167 | IF_GETOPT(APPLET(getopt, BB_DIR_BIN, BB_SUID_DROP)) |
177 | IF_GETSEBOOL(APPLET(getsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 168 | IF_GETSEBOOL(APPLET(getsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
178 | IF_GETTY(APPLET(getty, BB_DIR_SBIN, BB_SUID_DROP)) | 169 | IF_GETTY(APPLET(getty, BB_DIR_SBIN, BB_SUID_DROP)) |
179 | IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) | ||
180 | IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP)) | ||
181 | IF_HD(APPLET_NOEXEC(hd, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hd)) | 170 | IF_HD(APPLET_NOEXEC(hd, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hd)) |
182 | IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) | 171 | IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) |
183 | IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) | 172 | IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) |
@@ -236,10 +225,6 @@ IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls)) | |||
236 | IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP)) | 225 | IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP)) |
237 | IF_LSPCI(APPLET(lspci, BB_DIR_USR_BIN, BB_SUID_DROP)) | 226 | IF_LSPCI(APPLET(lspci, BB_DIR_USR_BIN, BB_SUID_DROP)) |
238 | IF_LSUSB(APPLET(lsusb, BB_DIR_USR_BIN, BB_SUID_DROP)) | 227 | IF_LSUSB(APPLET(lsusb, BB_DIR_USR_BIN, BB_SUID_DROP)) |
239 | IF_UNLZMA(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) | ||
240 | IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) | ||
241 | IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP)) | ||
242 | IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) | ||
243 | IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) | 228 | IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) |
244 | IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) | 229 | IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) |
245 | IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP)) | 230 | IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP)) |
@@ -303,12 +288,9 @@ IF_RENICE(APPLET(renice, BB_DIR_USR_BIN, BB_SUID_DROP)) | |||
303 | IF_RESET(APPLET(reset, BB_DIR_USR_BIN, BB_SUID_DROP)) | 288 | IF_RESET(APPLET(reset, BB_DIR_USR_BIN, BB_SUID_DROP)) |
304 | IF_RESIZE(APPLET(resize, BB_DIR_USR_BIN, BB_SUID_DROP)) | 289 | IF_RESIZE(APPLET(resize, BB_DIR_USR_BIN, BB_SUID_DROP)) |
305 | IF_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, BB_DIR_SBIN, BB_SUID_DROP, restorecon)) | 290 | IF_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, BB_DIR_SBIN, BB_SUID_DROP, restorecon)) |
306 | IF_RFKILL(APPLET(rfkill, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
307 | IF_RM(APPLET_NOFORK(rm, rm, BB_DIR_BIN, BB_SUID_DROP, rm)) | 291 | IF_RM(APPLET_NOFORK(rm, rm, BB_DIR_BIN, BB_SUID_DROP, rm)) |
308 | IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir)) | 292 | IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir)) |
309 | IF_ROUTE(APPLET(route, BB_DIR_SBIN, BB_SUID_DROP)) | 293 | IF_ROUTE(APPLET(route, BB_DIR_SBIN, BB_SUID_DROP)) |
310 | IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP)) | ||
311 | IF_RPM2CPIO(APPLET(rpm2cpio, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
312 | IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 294 | IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
313 | IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) | 295 | IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) |
314 | IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) | 296 | IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) |
@@ -318,7 +300,6 @@ IF_RUNSVDIR(APPLET(runsvdir, BB_DIR_USR_BIN, BB_SUID_DROP)) | |||
318 | IF_RX(APPLET(rx, BB_DIR_USR_BIN, BB_SUID_DROP)) | 300 | IF_RX(APPLET(rx, BB_DIR_USR_BIN, BB_SUID_DROP)) |
319 | IF_SCRIPT(APPLET(script, BB_DIR_USR_BIN, BB_SUID_DROP)) | 301 | IF_SCRIPT(APPLET(script, BB_DIR_USR_BIN, BB_SUID_DROP)) |
320 | IF_SCRIPTREPLAY(APPLET(scriptreplay, BB_DIR_BIN, BB_SUID_DROP)) | 302 | IF_SCRIPTREPLAY(APPLET(scriptreplay, BB_DIR_BIN, BB_SUID_DROP)) |
321 | IF_SED(APPLET(sed, BB_DIR_BIN, BB_SUID_DROP)) | ||
322 | IF_SELINUXENABLED(APPLET(selinuxenabled, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 303 | IF_SELINUXENABLED(APPLET(selinuxenabled, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
323 | IF_SENDMAIL(APPLET(sendmail, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 304 | IF_SENDMAIL(APPLET(sendmail, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
324 | IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) | 305 | IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) |
@@ -362,7 +343,6 @@ IF_BB_SYSCTL(APPLET(sysctl, BB_DIR_SBIN, BB_SUID_DROP)) | |||
362 | IF_SYSLOGD(APPLET(syslogd, BB_DIR_SBIN, BB_SUID_DROP)) | 343 | IF_SYSLOGD(APPLET(syslogd, BB_DIR_SBIN, BB_SUID_DROP)) |
363 | IF_TAC(APPLET_NOEXEC(tac, tac, BB_DIR_USR_BIN, BB_SUID_DROP, tac)) | 344 | IF_TAC(APPLET_NOEXEC(tac, tac, BB_DIR_USR_BIN, BB_SUID_DROP, tac)) |
364 | IF_TAIL(APPLET(tail, BB_DIR_USR_BIN, BB_SUID_DROP)) | 345 | IF_TAIL(APPLET(tail, BB_DIR_USR_BIN, BB_SUID_DROP)) |
365 | IF_TAR(APPLET(tar, BB_DIR_BIN, BB_SUID_DROP)) | ||
366 | IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) | 346 | IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) |
367 | /* IF_TC(APPLET(tc, BB_DIR_SBIN, BB_SUID_DROP)) */ | 347 | /* IF_TC(APPLET(tc, BB_DIR_SBIN, BB_SUID_DROP)) */ |
368 | IF_TCPSVD(APPLET_ODDNAME(tcpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, tcpsvd)) | 348 | IF_TCPSVD(APPLET_ODDNAME(tcpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, tcpsvd)) |
@@ -391,14 +371,9 @@ IF_UDHCPD(APPLET(udhcpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) | |||
391 | IF_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, udpsvd)) | 371 | IF_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, udpsvd)) |
392 | IF_UMOUNT(APPLET(umount, BB_DIR_BIN, BB_SUID_DROP)) | 372 | IF_UMOUNT(APPLET(umount, BB_DIR_BIN, BB_SUID_DROP)) |
393 | IF_UNAME(APPLET(uname, BB_DIR_BIN, BB_SUID_DROP)) | 373 | IF_UNAME(APPLET(uname, BB_DIR_BIN, BB_SUID_DROP)) |
394 | IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP)) | ||
395 | IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, BB_DIR_USR_BIN, BB_SUID_DROP, unexpand)) | 374 | IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, BB_DIR_USR_BIN, BB_SUID_DROP, unexpand)) |
396 | IF_UNIQ(APPLET(uniq, BB_DIR_USR_BIN, BB_SUID_DROP)) | 375 | IF_UNIQ(APPLET(uniq, BB_DIR_USR_BIN, BB_SUID_DROP)) |
397 | IF_UNIX2DOS(APPLET_NOEXEC(unix2dos, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, unix2dos)) | 376 | IF_UNIX2DOS(APPLET_NOEXEC(unix2dos, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, unix2dos)) |
398 | IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
399 | IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
400 | IF_LZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) | ||
401 | IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
402 | IF_UPTIME(APPLET(uptime, BB_DIR_USR_BIN, BB_SUID_DROP)) | 377 | IF_UPTIME(APPLET(uptime, BB_DIR_USR_BIN, BB_SUID_DROP)) |
403 | IF_USLEEP(APPLET_NOFORK(usleep, usleep, BB_DIR_BIN, BB_SUID_DROP, usleep)) | 378 | IF_USLEEP(APPLET_NOFORK(usleep, usleep, BB_DIR_BIN, BB_SUID_DROP, usleep)) |
404 | IF_UUDECODE(APPLET(uudecode, BB_DIR_USR_BIN, BB_SUID_DROP)) | 379 | IF_UUDECODE(APPLET(uudecode, BB_DIR_USR_BIN, BB_SUID_DROP)) |
@@ -407,18 +382,13 @@ IF_VCONFIG(APPLET(vconfig, BB_DIR_SBIN, BB_SUID_DROP)) | |||
407 | /* Needs to be run by root or be suid root - needs to change uid and gid: */ | 382 | /* Needs to be run by root or be suid root - needs to change uid and gid: */ |
408 | IF_VLOCK(APPLET(vlock, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) | 383 | IF_VLOCK(APPLET(vlock, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) |
409 | IF_VOLNAME(APPLET(volname, BB_DIR_USR_BIN, BB_SUID_DROP)) | 384 | IF_VOLNAME(APPLET(volname, BB_DIR_USR_BIN, BB_SUID_DROP)) |
410 | /* Needs to be run by root or be suid root - needs to write to /dev/TTY: */ | ||
411 | IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) | ||
412 | IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) | 385 | IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) |
413 | IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) | 386 | IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) |
414 | IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) | 387 | IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) |
415 | IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) | 388 | IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) |
416 | IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) | 389 | IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) |
417 | IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) | 390 | IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) |
418 | IF_UNXZ(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) | ||
419 | IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) | ||
420 | IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) | 391 | IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) |
421 | IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) | ||
422 | IF_ZCIP(APPLET(zcip, BB_DIR_SBIN, BB_SUID_DROP)) | 392 | IF_ZCIP(APPLET(zcip, BB_DIR_SBIN, BB_SUID_DROP)) |
423 | 393 | ||
424 | #if !defined(PROTOTYPES) && !defined(NAME_MAIN_CNAME) && !defined(MAKE_USAGE) \ | 394 | #if !defined(PROTOTYPES) && !defined(NAME_MAIN_CNAME) && !defined(MAKE_USAGE) \ |
diff --git a/include/libbb.h b/include/libbb.h index 9adb037ca..e516f0ee3 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -32,12 +32,12 @@ | |||
32 | #include <stdarg.h> | 32 | #include <stdarg.h> |
33 | #include <stddef.h> | 33 | #include <stddef.h> |
34 | #include <string.h> | 34 | #include <string.h> |
35 | /* There are two incompatible basename's, let not use them! */ | 35 | /* There are two incompatible basename's, let's not use them! */ |
36 | /* See the dirname/basename man page for details */ | 36 | /* See the dirname/basename man page for details */ |
37 | #include <libgen.h> /* dirname,basename */ | 37 | #include <libgen.h> /* dirname,basename */ |
38 | #undef basename | 38 | #undef basename |
39 | #define basename dont_use_basename | 39 | #define basename dont_use_basename |
40 | #include <sys/poll.h> | 40 | #include <poll.h> |
41 | #include <sys/ioctl.h> | 41 | #include <sys/ioctl.h> |
42 | #include <sys/mman.h> | 42 | #include <sys/mman.h> |
43 | #include <sys/socket.h> | 43 | #include <sys/socket.h> |
@@ -474,6 +474,8 @@ void record_signo(int signo); /* not FAST_FUNC! */ | |||
474 | 474 | ||
475 | void xsetgid(gid_t gid) FAST_FUNC; | 475 | void xsetgid(gid_t gid) FAST_FUNC; |
476 | void xsetuid(uid_t uid) FAST_FUNC; | 476 | void xsetuid(uid_t uid) FAST_FUNC; |
477 | void xsetegid(gid_t egid) FAST_FUNC; | ||
478 | void xseteuid(uid_t euid) FAST_FUNC; | ||
477 | void xchdir(const char *path) FAST_FUNC; | 479 | void xchdir(const char *path) FAST_FUNC; |
478 | void xchroot(const char *path) FAST_FUNC; | 480 | void xchroot(const char *path) FAST_FUNC; |
479 | void xsetenv(const char *key, const char *value) FAST_FUNC; | 481 | void xsetenv(const char *key, const char *value) FAST_FUNC; |
@@ -482,11 +484,12 @@ void bb_unsetenv_and_free(char *key) FAST_FUNC; | |||
482 | void xunlink(const char *pathname) FAST_FUNC; | 484 | void xunlink(const char *pathname) FAST_FUNC; |
483 | void xstat(const char *pathname, struct stat *buf) FAST_FUNC; | 485 | void xstat(const char *pathname, struct stat *buf) FAST_FUNC; |
484 | void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC; | 486 | void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC; |
487 | int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC; | ||
488 | int open_or_warn(const char *pathname, int flags) FAST_FUNC; | ||
489 | int xopen3(const char *pathname, int flags, int mode) FAST_FUNC; | ||
485 | int xopen(const char *pathname, int flags) FAST_FUNC; | 490 | int xopen(const char *pathname, int flags) FAST_FUNC; |
486 | int xopen_nonblocking(const char *pathname) FAST_FUNC; | 491 | int xopen_nonblocking(const char *pathname) FAST_FUNC; |
487 | int xopen3(const char *pathname, int flags, int mode) FAST_FUNC; | 492 | int xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) FAST_FUNC; |
488 | int open_or_warn(const char *pathname, int flags) FAST_FUNC; | ||
489 | int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC; | ||
490 | int open_or_warn_stdin(const char *pathname) FAST_FUNC; | 493 | int open_or_warn_stdin(const char *pathname) FAST_FUNC; |
491 | int xopen_stdin(const char *pathname) FAST_FUNC; | 494 | int xopen_stdin(const char *pathname) FAST_FUNC; |
492 | void xrename(const char *oldpath, const char *newpath) FAST_FUNC; | 495 | void xrename(const char *oldpath, const char *newpath) FAST_FUNC; |
@@ -831,8 +834,8 @@ char *itoa(int n) FAST_FUNC; | |||
831 | char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC; | 834 | char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC; |
832 | char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC; | 835 | char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC; |
833 | /* Intelligent formatters of bignums */ | 836 | /* Intelligent formatters of bignums */ |
834 | void smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC; | 837 | char *smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC; |
835 | void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC; | 838 | char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC; |
836 | /* If block_size == 0, display size without fractional part, | 839 | /* If block_size == 0, display size without fractional part, |
837 | * else display (size * block_size) with one decimal digit. | 840 | * else display (size * block_size) with one decimal digit. |
838 | * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...), | 841 | * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...), |
@@ -1313,8 +1316,10 @@ int sd_listen_fds(void); | |||
1313 | #define SETUP_ENV_CLEARENV (1 << 1) | 1316 | #define SETUP_ENV_CLEARENV (1 << 1) |
1314 | #define SETUP_ENV_TO_TMP (1 << 2) | 1317 | #define SETUP_ENV_TO_TMP (1 << 2) |
1315 | #define SETUP_ENV_NO_CHDIR (1 << 4) | 1318 | #define SETUP_ENV_NO_CHDIR (1 << 4) |
1316 | extern void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; | 1319 | void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; |
1317 | extern int correct_password(const struct passwd *pw) FAST_FUNC; | 1320 | void nuke_str(char *str) FAST_FUNC; |
1321 | int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; | ||
1322 | int ask_and_check_password(const struct passwd *pw) FAST_FUNC; | ||
1318 | /* Returns a malloced string */ | 1323 | /* Returns a malloced string */ |
1319 | #if !ENABLE_USE_BB_CRYPT | 1324 | #if !ENABLE_USE_BB_CRYPT |
1320 | #define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt) | 1325 | #define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt) |
@@ -1793,6 +1798,11 @@ extern struct globals *const ptr_to_globals; | |||
1793 | (*(struct globals**)&ptr_to_globals) = (void*)(x); \ | 1798 | (*(struct globals**)&ptr_to_globals) = (void*)(x); \ |
1794 | barrier(); \ | 1799 | barrier(); \ |
1795 | } while (0) | 1800 | } while (0) |
1801 | #define FREE_PTR_TO_GLOBALS() do { \ | ||
1802 | if (ENABLE_FEATURE_CLEAN_UP) { \ | ||
1803 | free(ptr_to_globals); \ | ||
1804 | } \ | ||
1805 | } while (0) | ||
1796 | 1806 | ||
1797 | /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, | 1807 | /* You can change LIBBB_DEFAULT_LOGIN_SHELL, but don't use it, |
1798 | * use bb_default_login_shell and following defines. | 1808 | * use bb_default_login_shell and following defines. |
diff --git a/include/platform.h b/include/platform.h index f18d5b74e..66615b400 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -469,7 +469,7 @@ typedef unsigned smalluint; | |||
469 | # undef HAVE_UNLOCKED_LINE_OPS | 469 | # undef HAVE_UNLOCKED_LINE_OPS |
470 | #endif | 470 | #endif |
471 | 471 | ||
472 | #if defined(__FreeBSD__) | 472 | #if defined(__FreeBSD__) || defined(__APPLE__) |
473 | # undef HAVE_STRCHRNUL | 473 | # undef HAVE_STRCHRNUL |
474 | #endif | 474 | #endif |
475 | 475 | ||
diff --git a/init/bootchartd.c b/init/bootchartd.c index 9fd623357..c7388c99e 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c | |||
@@ -60,6 +60,12 @@ | |||
60 | # endif | 60 | # endif |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #if !ENABLE_TAR && !ENABLE_WERROR | ||
64 | # warning Note: bootchartd requires tar command, but you did not select it. | ||
65 | #elif !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_WERROR | ||
66 | # warning Note: bootchartd requires tar -z support, but you did not select it. | ||
67 | #endif | ||
68 | |||
63 | #define BC_VERSION_STR "0.8" | 69 | #define BC_VERSION_STR "0.8" |
64 | 70 | ||
65 | /* For debugging, set to 0: | 71 | /* For debugging, set to 0: |
diff --git a/init/init.c b/init/init.c index edb5be696..d29328c36 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -9,11 +9,6 @@ | |||
9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) | ||
13 | //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_INIT) += init.o | ||
16 | |||
17 | //config:config INIT | 12 | //config:config INIT |
18 | //config: bool "init" | 13 | //config: bool "init" |
19 | //config: default y | 14 | //config: default y |
@@ -108,6 +103,11 @@ | |||
108 | //config: Note that on Linux, init attempts to detect serial terminal and | 103 | //config: Note that on Linux, init attempts to detect serial terminal and |
109 | //config: sets TERM to "vt102" if one is found. | 104 | //config: sets TERM to "vt102" if one is found. |
110 | 105 | ||
106 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) | ||
107 | //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) | ||
108 | |||
109 | //kbuild:lib-$(CONFIG_INIT) += init.o | ||
110 | |||
111 | #define DEBUG_SEGV_HANDLER 0 | 111 | #define DEBUG_SEGV_HANDLER 0 |
112 | 112 | ||
113 | #include "libbb.h" | 113 | #include "libbb.h" |
@@ -222,8 +222,8 @@ static void message(int where, const char *fmt, ...) | |||
222 | msg[0] = '\r'; | 222 | msg[0] = '\r'; |
223 | va_start(arguments, fmt); | 223 | va_start(arguments, fmt); |
224 | l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); | 224 | l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); |
225 | if (l > sizeof(msg) - 1) | 225 | if (l > sizeof(msg) - 2) |
226 | l = sizeof(msg) - 1; | 226 | l = sizeof(msg) - 2; |
227 | va_end(arguments); | 227 | va_end(arguments); |
228 | 228 | ||
229 | #if ENABLE_FEATURE_INIT_SYSLOG | 229 | #if ENABLE_FEATURE_INIT_SYSLOG |
@@ -789,7 +789,7 @@ static void run_shutdown_and_kill_processes(void) | |||
789 | * and only one will be remembered and acted upon. | 789 | * and only one will be remembered and acted upon. |
790 | */ | 790 | */ |
791 | 791 | ||
792 | /* The SIGUSR[12]/SIGTERM handler */ | 792 | /* The SIGPWR/SIGUSR[12]/SIGTERM handler */ |
793 | static void halt_reboot_pwoff(int sig) NORETURN; | 793 | static void halt_reboot_pwoff(int sig) NORETURN; |
794 | static void halt_reboot_pwoff(int sig) | 794 | static void halt_reboot_pwoff(int sig) |
795 | { | 795 | { |
@@ -1103,8 +1103,8 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1103 | 1103 | ||
1104 | /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, | 1104 | /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, |
1105 | * then parse_inittab() simply adds in some default | 1105 | * then parse_inittab() simply adds in some default |
1106 | * actions(i.e., INIT_SCRIPT and a pair | 1106 | * actions (i.e., INIT_SCRIPT and a pair |
1107 | * of "askfirst" shells */ | 1107 | * of "askfirst" shells) */ |
1108 | parse_inittab(); | 1108 | parse_inittab(); |
1109 | } | 1109 | } |
1110 | 1110 | ||
@@ -1128,13 +1128,14 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1128 | strncpy(argv[0], "init", strlen(argv[0])); | 1128 | strncpy(argv[0], "init", strlen(argv[0])); |
1129 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ | 1129 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ |
1130 | while (*++argv) | 1130 | while (*++argv) |
1131 | memset(*argv, 0, strlen(*argv)); | 1131 | nuke_str(*argv); |
1132 | 1132 | ||
1133 | /* Set up signal handlers */ | 1133 | /* Set up signal handlers */ |
1134 | if (!DEBUG_INIT) { | 1134 | if (!DEBUG_INIT) { |
1135 | struct sigaction sa; | 1135 | struct sigaction sa; |
1136 | 1136 | ||
1137 | bb_signals(0 | 1137 | bb_signals(0 |
1138 | + (1 << SIGPWR) /* halt */ | ||
1138 | + (1 << SIGUSR1) /* halt */ | 1139 | + (1 << SIGUSR1) /* halt */ |
1139 | + (1 << SIGTERM) /* reboot */ | 1140 | + (1 << SIGTERM) /* reboot */ |
1140 | + (1 << SIGUSR2) /* poweroff */ | 1141 | + (1 << SIGUSR2) /* poweroff */ |
@@ -1230,7 +1231,14 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1230 | //usage:#define init_trivial_usage | 1231 | //usage:#define init_trivial_usage |
1231 | //usage: "" | 1232 | //usage: "" |
1232 | //usage:#define init_full_usage "\n\n" | 1233 | //usage:#define init_full_usage "\n\n" |
1233 | //usage: "Init is the parent of all processes" | 1234 | //usage: "Init is the first process started during boot. It never exits." |
1235 | //usage: IF_FEATURE_USE_INITTAB( | ||
1236 | //usage: "\n""It (re)spawns children according to /etc/inittab." | ||
1237 | //usage: ) | ||
1238 | //usage: IF_NOT_FEATURE_USE_INITTAB( | ||
1239 | //usage: "\n""This version of init doesn't use /etc/inittab," | ||
1240 | //usage: "\n""has fixed set of processed to run." | ||
1241 | //usage: ) | ||
1234 | //usage: | 1242 | //usage: |
1235 | //usage:#define init_notes_usage | 1243 | //usage:#define init_notes_usage |
1236 | //usage: "This version of init is designed to be run only by the kernel.\n" | 1244 | //usage: "This version of init is designed to be run only by the kernel.\n" |
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index db79ff62b..adaab92d6 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -146,7 +146,7 @@ lib-$(CONFIG_DELUSER) += update_passwd.o | |||
146 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o | 146 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o |
147 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o | 147 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o |
148 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o | 148 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o |
149 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o | 149 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o |
150 | lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o | 150 | lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o |
151 | lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o | 151 | lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o |
152 | lib-$(CONFIG_LOGIN) += pw_encrypt.o correct_password.o | 152 | lib-$(CONFIG_LOGIN) += pw_encrypt.o correct_password.o |
diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c index 4829b723a..8250cd446 100644 --- a/libbb/bb_pwd.c +++ b/libbb/bb_pwd.c | |||
@@ -110,3 +110,51 @@ unsigned long FAST_FUNC get_ug_id(const char *s, | |||
110 | return xname2id(s); | 110 | return xname2id(s); |
111 | return r; | 111 | return r; |
112 | } | 112 | } |
113 | |||
114 | /* Experimental "mallocing" API. | ||
115 | * The goal is nice: "we want to support a case when "guests" group is very large" | ||
116 | * but the code is butt-ugly. | ||
117 | */ | ||
118 | #if 0 | ||
119 | static char *find_latest(char last, char *cp) | ||
120 | { | ||
121 | if (!cp) | ||
122 | return last; | ||
123 | cp += strlen(cp) + 1; | ||
124 | if (last < cp) | ||
125 | last = cp; | ||
126 | return last; | ||
127 | } | ||
128 | |||
129 | struct group* FAST_FUNC xmalloc_getgrnam(const char *name) | ||
130 | { | ||
131 | struct { | ||
132 | struct group gr; | ||
133 | // May still be not enough! | ||
134 | char buf[64*1024 - sizeof(struct group) - 16]; | ||
135 | } *s; | ||
136 | struct group *grp; | ||
137 | int r; | ||
138 | char *last; | ||
139 | char **gr_mem; | ||
140 | |||
141 | s = xmalloc(sizeof(*s)); | ||
142 | r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp); | ||
143 | if (!grp) { | ||
144 | free(s); | ||
145 | return grp; | ||
146 | } | ||
147 | last = find_latest(s->buf, grp->gr_name); | ||
148 | last = find_latest(last, grp->gr_passwd); | ||
149 | gr_mem = grp->gr_mem; | ||
150 | while (*gr_mem) | ||
151 | last = find_latest(last, *gr_mem++); | ||
152 | gr_mem++; /* points past NULL */ | ||
153 | if (last < (char*)gr_mem) | ||
154 | last = (char*)gr_mem; | ||
155 | //FIXME: what if we get not only truncated, but also moved here? | ||
156 | // grp->gr_name pointer and friends are invalid now!!! | ||
157 | s = xrealloc(s, last - (char*)s); | ||
158 | return grp; | ||
159 | } | ||
160 | #endif | ||
diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 7cabd33d0..acadf3914 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c | |||
@@ -31,12 +31,15 @@ | |||
31 | #include "libbb.h" | 31 | #include "libbb.h" |
32 | 32 | ||
33 | /* Ask the user for a password. | 33 | /* Ask the user for a password. |
34 | * Return 1 without asking if PW has an empty password. | ||
35 | * Return -1 on EOF, error while reading input, or timeout. | ||
34 | * Return 1 if the user gives the correct password for entry PW, | 36 | * Return 1 if the user gives the correct password for entry PW, |
35 | * 0 if not. Return 1 without asking if PW has an empty password. | 37 | * 0 if not. |
36 | * | 38 | * |
37 | * NULL pw means "just fake it for login with bad username" */ | 39 | * NULL pw means "just fake it for login with bad username" |
38 | 40 | */ | |
39 | int FAST_FUNC correct_password(const struct passwd *pw) | 41 | int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, |
42 | int timeout, const char *prompt) | ||
40 | { | 43 | { |
41 | char *unencrypted, *encrypted; | 44 | char *unencrypted, *encrypted; |
42 | const char *correct; | 45 | const char *correct; |
@@ -65,13 +68,19 @@ int FAST_FUNC correct_password(const struct passwd *pw) | |||
65 | return 1; | 68 | return 1; |
66 | 69 | ||
67 | fake_it: | 70 | fake_it: |
68 | unencrypted = bb_ask_stdin("Password: "); | 71 | unencrypted = bb_ask(STDIN_FILENO, timeout, prompt); |
69 | if (!unencrypted) { | 72 | if (!unencrypted) { |
70 | return 0; | 73 | /* EOF (such as ^D) or error (such as ^C) or timeout */ |
74 | return -1; | ||
71 | } | 75 | } |
72 | encrypted = pw_encrypt(unencrypted, correct, 1); | 76 | encrypted = pw_encrypt(unencrypted, correct, 1); |
73 | r = (strcmp(encrypted, correct) == 0); | 77 | r = (strcmp(encrypted, correct) == 0); |
74 | free(encrypted); | 78 | free(encrypted); |
75 | memset(unencrypted, 0, strlen(unencrypted)); | 79 | nuke_str(unencrypted); |
76 | return r; | 80 | return r; |
77 | } | 81 | } |
82 | |||
83 | int FAST_FUNC ask_and_check_password(const struct passwd *pw) | ||
84 | { | ||
85 | return ask_and_check_password_extended(pw, 0, "Password: "); | ||
86 | } | ||
diff --git a/libbb/fclose_nonstdin.c b/libbb/fclose_nonstdin.c index 5ce9d5b48..1b1441347 100644 --- a/libbb/fclose_nonstdin.c +++ b/libbb/fclose_nonstdin.c | |||
@@ -18,7 +18,8 @@ int FAST_FUNC fclose_if_not_stdin(FILE *f) | |||
18 | { | 18 | { |
19 | /* Some more paranoid applets want ferror() check too */ | 19 | /* Some more paranoid applets want ferror() check too */ |
20 | int r = ferror(f); /* NB: does NOT set errno! */ | 20 | int r = ferror(f); /* NB: does NOT set errno! */ |
21 | if (r) errno = EIO; /* so we'll help it */ | 21 | if (r) |
22 | errno = EIO; /* so we'll help it */ | ||
22 | if (f != stdin) | 23 | if (f != stdin) |
23 | return (r | fclose(f)); /* fclose does set errno on error */ | 24 | return (r | fclose(f)); /* fclose does set errno on error */ |
24 | return r; | 25 | return r; |
diff --git a/libbb/human_readable.c b/libbb/human_readable.c index 8b22b0cb5..0b2eb777e 100644 --- a/libbb/human_readable.c +++ b/libbb/human_readable.c | |||
@@ -94,7 +94,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, | |||
94 | 94 | ||
95 | /* Convert unsigned long long value into compact 5-char representation. | 95 | /* Convert unsigned long long value into compact 5-char representation. |
96 | * String is not terminated (buf[5] is untouched) */ | 96 | * String is not terminated (buf[5] is untouched) */ |
97 | void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) | 97 | char* FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) |
98 | { | 98 | { |
99 | const char *fmt; | 99 | const char *fmt; |
100 | char c; | 100 | char c; |
@@ -145,12 +145,13 @@ void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *sca | |||
145 | buf[3] = "0123456789"[v]; | 145 | buf[3] = "0123456789"[v]; |
146 | buf[4] = scale[idx]; /* typically scale = " kmgt..." */ | 146 | buf[4] = scale[idx]; /* typically scale = " kmgt..." */ |
147 | } | 147 | } |
148 | return buf + 5; | ||
148 | } | 149 | } |
149 | 150 | ||
150 | /* Convert unsigned long long value into compact 4-char | 151 | /* Convert unsigned long long value into compact 4-char |
151 | * representation. Examples: "1234", "1.2k", " 27M", "123T" | 152 | * representation. Examples: "1234", "1.2k", " 27M", "123T" |
152 | * String is not terminated (buf[4] is untouched) */ | 153 | * String is not terminated (buf[4] is untouched) */ |
153 | void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) | 154 | char* FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) |
154 | { | 155 | { |
155 | const char *fmt; | 156 | const char *fmt; |
156 | char c; | 157 | char c; |
@@ -194,4 +195,5 @@ void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *sca | |||
194 | buf[2] = "0123456789"[v]; | 195 | buf[2] = "0123456789"[v]; |
195 | buf[3] = scale[idx]; /* typically scale = " kmgt..." */ | 196 | buf[3] = scale[idx]; /* typically scale = " kmgt..." */ |
196 | } | 197 | } |
198 | return buf + 4; | ||
197 | } | 199 | } |
diff --git a/libbb/in_ether.c b/libbb/in_ether.c index dadadbafe..1de383bde 100644 --- a/libbb/in_ether.c +++ b/libbb/in_ether.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Utility routines. | 3 | * Utility routines. |
4 | */ | 4 | */ |
5 | 5 | ||
6 | //kbuild:lib-$(CONFIG_ARP) += in_ether.o | ||
6 | //kbuild:lib-$(CONFIG_IFCONFIG) += in_ether.o | 7 | //kbuild:lib-$(CONFIG_IFCONFIG) += in_ether.o |
7 | //kbuild:lib-$(CONFIG_IFENSLAVE) += in_ether.o | 8 | //kbuild:lib-$(CONFIG_IFENSLAVE) += in_ether.o |
8 | 9 | ||
diff --git a/libbb/inet_common.c b/libbb/inet_common.c index 0f4fca1a2..b3e0802ee 100644 --- a/libbb/inet_common.c +++ b/libbb/inet_common.c | |||
@@ -175,8 +175,7 @@ int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6) | |||
175 | return -1; | 175 | return -1; |
176 | } | 176 | } |
177 | memcpy(sin6, ai->ai_addr, sizeof(*sin6)); | 177 | memcpy(sin6, ai->ai_addr, sizeof(*sin6)); |
178 | if (ai) | 178 | freeaddrinfo(ai); |
179 | freeaddrinfo(ai); | ||
180 | return 0; | 179 | return 0; |
181 | } | 180 | } |
182 | 181 | ||
diff --git a/libbb/nuke_str.c b/libbb/nuke_str.c new file mode 100644 index 000000000..56b808bc7 --- /dev/null +++ b/libbb/nuke_str.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2008 Denys Vlasenko | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | //kbuild:lib-y += nuke_str.o | ||
11 | |||
12 | #include "libbb.h" | ||
13 | |||
14 | void FAST_FUNC nuke_str(char *str) | ||
15 | { | ||
16 | if (str) { | ||
17 | while (*str) | ||
18 | *str++ = 0; | ||
19 | /* or: memset(str, 0, strlen(str)); - not as small as above */ | ||
20 | } | ||
21 | } | ||
diff --git a/libbb/pw_encrypt_md5.c b/libbb/pw_encrypt_md5.c index 889e09cab..1e52ecaea 100644 --- a/libbb/pw_encrypt_md5.c +++ b/libbb/pw_encrypt_md5.c | |||
@@ -86,7 +86,7 @@ md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned | |||
86 | 86 | ||
87 | /* Get the length of the salt including "$1$" */ | 87 | /* Get the length of the salt including "$1$" */ |
88 | sl = 3; | 88 | sl = 3; |
89 | while (salt[sl] && salt[sl] != '$' && sl < (3 + 8)) | 89 | while (sl < (3 + 8) && salt[sl] && salt[sl] != '$') |
90 | sl++; | 90 | sl++; |
91 | 91 | ||
92 | /* Hash. the password first, since that is what is most unknown */ | 92 | /* Hash. the password first, since that is what is most unknown */ |
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index a70683241..e4ac6a002 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c | |||
@@ -140,15 +140,6 @@ int FAST_FUNC xopen(const char *pathname, int flags) | |||
140 | return xopen3(pathname, flags, 0666); | 140 | return xopen3(pathname, flags, 0666); |
141 | } | 141 | } |
142 | 142 | ||
143 | /* Die if we can't open an existing file readonly with O_NONBLOCK | ||
144 | * and return the fd. | ||
145 | * Note that for ioctl O_RDONLY is sufficient. | ||
146 | */ | ||
147 | int FAST_FUNC xopen_nonblocking(const char *pathname) | ||
148 | { | ||
149 | return xopen(pathname, O_RDONLY | O_NONBLOCK); | ||
150 | } | ||
151 | |||
152 | // Warn if we can't open a file and return a fd. | 143 | // Warn if we can't open a file and return a fd. |
153 | int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) | 144 | int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) |
154 | { | 145 | { |
@@ -167,6 +158,32 @@ int FAST_FUNC open_or_warn(const char *pathname, int flags) | |||
167 | return open3_or_warn(pathname, flags, 0666); | 158 | return open3_or_warn(pathname, flags, 0666); |
168 | } | 159 | } |
169 | 160 | ||
161 | /* Die if we can't open an existing file readonly with O_NONBLOCK | ||
162 | * and return the fd. | ||
163 | * Note that for ioctl O_RDONLY is sufficient. | ||
164 | */ | ||
165 | int FAST_FUNC xopen_nonblocking(const char *pathname) | ||
166 | { | ||
167 | return xopen(pathname, O_RDONLY | O_NONBLOCK); | ||
168 | } | ||
169 | |||
170 | int FAST_FUNC xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) | ||
171 | { | ||
172 | int fd; | ||
173 | uid_t old_euid = geteuid(); | ||
174 | gid_t old_egid = getegid(); | ||
175 | |||
176 | xsetegid(g); | ||
177 | xseteuid(u); | ||
178 | |||
179 | fd = xopen(pathname, flags); | ||
180 | |||
181 | xseteuid(old_euid); | ||
182 | xsetegid(old_egid); | ||
183 | |||
184 | return fd; | ||
185 | } | ||
186 | |||
170 | void FAST_FUNC xunlink(const char *pathname) | 187 | void FAST_FUNC xunlink(const char *pathname) |
171 | { | 188 | { |
172 | if (unlink(pathname)) | 189 | if (unlink(pathname)) |
@@ -351,6 +368,16 @@ void FAST_FUNC xsetuid(uid_t uid) | |||
351 | if (setuid(uid)) bb_perror_msg_and_die("setuid"); | 368 | if (setuid(uid)) bb_perror_msg_and_die("setuid"); |
352 | } | 369 | } |
353 | 370 | ||
371 | void FAST_FUNC xsetegid(gid_t egid) | ||
372 | { | ||
373 | if (setegid(egid)) bb_perror_msg_and_die("setegid"); | ||
374 | } | ||
375 | |||
376 | void FAST_FUNC xseteuid(uid_t euid) | ||
377 | { | ||
378 | if (seteuid(euid)) bb_perror_msg_and_die("seteuid"); | ||
379 | } | ||
380 | |||
354 | // Die if we can't chdir to a new path. | 381 | // Die if we can't chdir to a new path. |
355 | void FAST_FUNC xchdir(const char *path) | 382 | void FAST_FUNC xchdir(const char *path) |
356 | { | 383 | { |
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index bc1d0e665..ea09f20b8 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -8,6 +8,12 @@ | |||
8 | 8 | ||
9 | #include "libbb.h" | 9 | #include "libbb.h" |
10 | 10 | ||
11 | /* some systems (eg Hurd) does not have MAXSYMLINKS definition, | ||
12 | * set it to some reasonable value if it isn't defined */ | ||
13 | #ifndef MAXSYMLINKS | ||
14 | # define MAXSYMLINKS 20 | ||
15 | #endif | ||
16 | |||
11 | /* | 17 | /* |
12 | * NOTE: This function returns a malloced char* that you will have to free | 18 | * NOTE: This function returns a malloced char* that you will have to free |
13 | * yourself. | 19 | * yourself. |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index dc0244476..ef390adf8 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -162,9 +162,9 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
162 | pw.pw_shell = (char *)get_shell_name(); | 162 | pw.pw_shell = (char *)get_shell_name(); |
163 | pw.pw_dir = NULL; | 163 | pw.pw_dir = NULL; |
164 | 164 | ||
165 | /* at most two non-option args */ | 165 | /* at least one and at most two non-option args */ |
166 | /* disable interactive passwd for system accounts */ | 166 | /* disable interactive passwd for system accounts */ |
167 | opt_complementary = "?2:SD:u+"; | 167 | opt_complementary = "-1:?2:SD:u+"; |
168 | if (sizeof(pw.pw_uid) == sizeof(int)) { | 168 | if (sizeof(pw.pw_uid) == sizeof(int)) { |
169 | opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid); | 169 | opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid); |
170 | } else { | 170 | } else { |
diff --git a/loginutils/login.c b/loginutils/login.c index 6ec8dc42e..a4b19ccfc 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -420,7 +420,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
420 | * Note that reads (in no-echo mode) trash tty attributes. | 420 | * Note that reads (in no-echo mode) trash tty attributes. |
421 | * If we get interrupted by SIGALRM, we need to restore attrs. | 421 | * If we get interrupted by SIGALRM, we need to restore attrs. |
422 | */ | 422 | */ |
423 | if (correct_password(pw)) | 423 | if (ask_and_check_password(pw) > 0) |
424 | break; | 424 | break; |
425 | #endif /* ENABLE_PAM */ | 425 | #endif /* ENABLE_PAM */ |
426 | auth_failed: | 426 | auth_failed: |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index a7006f054..150908932 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c | |||
@@ -17,11 +17,6 @@ | |||
17 | #include <syslog.h> | 17 | #include <syslog.h> |
18 | #include <sys/resource.h> /* setrlimit */ | 18 | #include <sys/resource.h> /* setrlimit */ |
19 | 19 | ||
20 | static void nuke_str(char *str) | ||
21 | { | ||
22 | if (str) memset(str, 0, strlen(str)); | ||
23 | } | ||
24 | |||
25 | static char* new_password(const struct passwd *pw, uid_t myuid, const char *algo) | 20 | static char* new_password(const struct passwd *pw, uid_t myuid, const char *algo) |
26 | { | 21 | { |
27 | char salt[MAX_PW_SALT_LEN]; | 22 | char salt[MAX_PW_SALT_LEN]; |
diff --git a/loginutils/su.c b/loginutils/su.c index 2ec05e125..c51f26f70 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -93,7 +93,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
93 | 93 | ||
94 | pw = xgetpwnam(opt_username); | 94 | pw = xgetpwnam(opt_username); |
95 | 95 | ||
96 | if (cur_uid == 0 || correct_password(pw)) { | 96 | if (cur_uid == 0 || ask_and_check_password(pw) > 0) { |
97 | if (ENABLE_FEATURE_SU_SYSLOG) | 97 | if (ENABLE_FEATURE_SU_SYSLOG) |
98 | syslog(LOG_NOTICE, "%c %s %s:%s", | 98 | syslog(LOG_NOTICE, "%c %s %s:%s", |
99 | '+', tty, old_user, opt_username); | 99 | '+', tty, old_user, opt_username); |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 65e638489..2a2909937 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -14,24 +14,12 @@ | |||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | #include <syslog.h> | 15 | #include <syslog.h> |
16 | 16 | ||
17 | //static void catchalarm(int UNUSED_PARAM junk) | ||
18 | //{ | ||
19 | // exit(EXIT_FAILURE); | ||
20 | //} | ||
21 | |||
22 | |||
23 | int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 17 | int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
24 | int sulogin_main(int argc UNUSED_PARAM, char **argv) | 18 | int sulogin_main(int argc UNUSED_PARAM, char **argv) |
25 | { | 19 | { |
26 | char *cp; | ||
27 | int timeout = 0; | 20 | int timeout = 0; |
28 | struct passwd *pwd; | 21 | struct passwd *pwd; |
29 | const char *shell; | 22 | const char *shell; |
30 | #if ENABLE_FEATURE_SHADOWPASSWDS | ||
31 | /* Using _r function to avoid pulling in static buffers */ | ||
32 | char buffer[256]; | ||
33 | struct spwd spw; | ||
34 | #endif | ||
35 | 23 | ||
36 | logmode = LOGMODE_BOTH; | 24 | logmode = LOGMODE_BOTH; |
37 | openlog(applet_name, 0, LOG_AUTH); | 25 | openlog(applet_name, 0, LOG_AUTH); |
@@ -62,43 +50,24 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
62 | goto auth_error; | 50 | goto auth_error; |
63 | } | 51 | } |
64 | 52 | ||
65 | #if ENABLE_FEATURE_SHADOWPASSWDS | ||
66 | { | ||
67 | /* getspnam_r may return 0 yet set result to NULL. | ||
68 | * At least glibc 2.4 does this. Be extra paranoid here. */ | ||
69 | struct spwd *result = NULL; | ||
70 | int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result); | ||
71 | if (r || !result) { | ||
72 | goto auth_error; | ||
73 | } | ||
74 | pwd->pw_passwd = result->sp_pwdp; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | while (1) { | 53 | while (1) { |
79 | char *encrypted; | ||
80 | int r; | 54 | int r; |
81 | 55 | ||
82 | /* cp points to a static buffer */ | 56 | r = ask_and_check_password_extended(pwd, timeout, |
83 | cp = bb_ask(STDIN_FILENO, timeout, | 57 | "Give root password for system maintenance\n" |
84 | "Give root password for system maintenance\n" | 58 | "(or type Control-D for normal startup):" |
85 | "(or type Control-D for normal startup):"); | 59 | ); |
86 | if (!cp) { | 60 | if (r < 0) { |
87 | /* ^D, ^C, timeout, or read error */ | 61 | /* ^D, ^C, timeout, or read error */ |
88 | bb_info_msg("Normal startup"); | 62 | bb_info_msg("Normal startup"); |
89 | return 0; | 63 | return 0; |
90 | } | 64 | } |
91 | encrypted = pw_encrypt(cp, pwd->pw_passwd, 1); | 65 | if (r > 0) { |
92 | r = strcmp(encrypted, pwd->pw_passwd); | ||
93 | free(encrypted); | ||
94 | if (r == 0) { | ||
95 | break; | 66 | break; |
96 | } | 67 | } |
97 | bb_do_delay(LOGIN_FAIL_DELAY); | 68 | bb_do_delay(LOGIN_FAIL_DELAY); |
98 | bb_info_msg("Login incorrect"); | 69 | bb_info_msg("Login incorrect"); |
99 | } | 70 | } |
100 | memset(cp, 0, strlen(cp)); | ||
101 | // signal(SIGALRM, SIG_DFL); | ||
102 | 71 | ||
103 | bb_info_msg("System Maintenance Mode"); | 72 | bb_info_msg("System Maintenance Mode"); |
104 | 73 | ||
diff --git a/loginutils/vlock.c b/loginutils/vlock.c index 75af9390e..44b14e6bc 100644 --- a/loginutils/vlock.c +++ b/loginutils/vlock.c | |||
@@ -104,7 +104,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv) | |||
104 | /* "s" if -a, else "": */ "s" + !option_mask32, | 104 | /* "s" if -a, else "": */ "s" + !option_mask32, |
105 | pw->pw_name | 105 | pw->pw_name |
106 | ); | 106 | ); |
107 | if (correct_password(pw)) { | 107 | if (ask_and_check_password(pw) > 0) { |
108 | break; | 108 | break; |
109 | } | 109 | } |
110 | bb_do_delay(LOGIN_FAIL_DELAY); | 110 | bb_do_delay(LOGIN_FAIL_DELAY); |
diff --git a/miscutils/Config.src b/miscutils/Config.src index b9fc196d8..1da9800bd 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src | |||
@@ -503,18 +503,6 @@ config READAHEAD | |||
503 | As readahead(2) blocks until each file has been read, it is best to | 503 | As readahead(2) blocks until each file has been read, it is best to |
504 | run this applet as a background job. | 504 | run this applet as a background job. |
505 | 505 | ||
506 | config RFKILL | ||
507 | bool "rfkill" | ||
508 | default n # doesn't build on Ubuntu 9.04 | ||
509 | select PLATFORM_LINUX | ||
510 | help | ||
511 | Enable/disable wireless devices. | ||
512 | |||
513 | rfkill list : list all wireless devices | ||
514 | rfkill list bluetooth : list all bluetooth devices | ||
515 | rfkill list 1 : list device corresponding to the given index | ||
516 | rfkill block|unblock wlan : block/unblock all wlan(wifi) devices | ||
517 | |||
518 | config RUNLEVEL | 506 | config RUNLEVEL |
519 | bool "runlevel" | 507 | bool "runlevel" |
520 | default y | 508 | default y |
@@ -591,13 +579,6 @@ config VOLNAME | |||
591 | help | 579 | help |
592 | Prints a CD-ROM volume name. | 580 | Prints a CD-ROM volume name. |
593 | 581 | ||
594 | config WALL | ||
595 | bool "wall" | ||
596 | default y | ||
597 | depends on FEATURE_UTMP | ||
598 | help | ||
599 | Write a message to all users that are logged in. | ||
600 | |||
601 | config WATCHDOG | 582 | config WATCHDOG |
602 | bool "watchdog" | 583 | bool "watchdog" |
603 | default y | 584 | default y |
diff --git a/miscutils/Kbuild.src b/miscutils/Kbuild.src index 8c498643b..9e164f16e 100644 --- a/miscutils/Kbuild.src +++ b/miscutils/Kbuild.src | |||
@@ -36,7 +36,6 @@ lib-$(CONFIG_MOUNTPOINT) += mountpoint.o | |||
36 | lib-$(CONFIG_MT) += mt.o | 36 | lib-$(CONFIG_MT) += mt.o |
37 | lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o | 37 | lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o |
38 | lib-$(CONFIG_READAHEAD) += readahead.o | 38 | lib-$(CONFIG_READAHEAD) += readahead.o |
39 | lib-$(CONFIG_RFKILL) += rfkill.o | ||
40 | lib-$(CONFIG_RUNLEVEL) += runlevel.o | 39 | lib-$(CONFIG_RUNLEVEL) += runlevel.o |
41 | lib-$(CONFIG_RX) += rx.o | 40 | lib-$(CONFIG_RX) += rx.o |
42 | lib-$(CONFIG_SETSID) += setsid.o | 41 | lib-$(CONFIG_SETSID) += setsid.o |
@@ -46,5 +45,4 @@ lib-$(CONFIG_TIME) += time.o | |||
46 | lib-$(CONFIG_TIMEOUT) += timeout.o | 45 | lib-$(CONFIG_TIMEOUT) += timeout.o |
47 | lib-$(CONFIG_TTYSIZE) += ttysize.o | 46 | lib-$(CONFIG_TTYSIZE) += ttysize.o |
48 | lib-$(CONFIG_VOLNAME) += volname.o | 47 | lib-$(CONFIG_VOLNAME) += volname.o |
49 | lib-$(CONFIG_WALL) += wall.o | ||
50 | lib-$(CONFIG_WATCHDOG) += watchdog.o | 48 | lib-$(CONFIG_WATCHDOG) += watchdog.o |
diff --git a/miscutils/chat.c b/miscutils/chat.c index ce994f870..bd2abc24a 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c | |||
@@ -296,7 +296,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
296 | full_write(record_fd, buf+buf_len, 1); | 296 | full_write(record_fd, buf+buf_len, 1); |
297 | } | 297 | } |
298 | // dump device input if ECHO ON | 298 | // dump device input if ECHO ON |
299 | if (echo > 0) { | 299 | if (echo) { |
300 | // if (buf[buf_len] < ' ') { | 300 | // if (buf[buf_len] < ' ') { |
301 | // full_write(STDERR_FILENO, "^", 1); | 301 | // full_write(STDERR_FILENO, "^", 1); |
302 | // buf[buf_len] += '@'; | 302 | // buf[buf_len] += '@'; |
diff --git a/miscutils/crontab.c b/miscutils/crontab.c index 4731d8da6..aad242fd8 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c | |||
@@ -55,28 +55,6 @@ static void edit_file(const struct passwd *pas, const char *file) | |||
55 | bb_perror_msg_and_die("can't execute '%s'", ptr); | 55 | bb_perror_msg_and_die("can't execute '%s'", ptr); |
56 | } | 56 | } |
57 | 57 | ||
58 | static int open_as_user(const struct passwd *pas, const char *file) | ||
59 | { | ||
60 | pid_t pid; | ||
61 | char c; | ||
62 | |||
63 | pid = xvfork(); | ||
64 | if (pid) { /* PARENT */ | ||
65 | if (wait4pid(pid) == 0) { | ||
66 | /* exitcode 0: child says it can read */ | ||
67 | return open(file, O_RDONLY); | ||
68 | } | ||
69 | return -1; | ||
70 | } | ||
71 | |||
72 | /* CHILD */ | ||
73 | /* initgroups, setgid, setuid */ | ||
74 | change_identity(pas); | ||
75 | /* We just try to read one byte. If it works, file is readable | ||
76 | * under this user. We signal that by exiting with 0. */ | ||
77 | _exit(safe_read(xopen(file, O_RDONLY), &c, 1) < 0); | ||
78 | } | ||
79 | |||
80 | int crontab_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 58 | int crontab_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
81 | int crontab_main(int argc UNUSED_PARAM, char **argv) | 59 | int crontab_main(int argc UNUSED_PARAM, char **argv) |
82 | { | 60 | { |
@@ -137,10 +115,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) | |||
137 | if (!argv[0]) | 115 | if (!argv[0]) |
138 | bb_show_usage(); | 116 | bb_show_usage(); |
139 | if (NOT_LONE_DASH(argv[0])) { | 117 | if (NOT_LONE_DASH(argv[0])) { |
140 | src_fd = open_as_user(pas, argv[0]); | 118 | src_fd = xopen_as_uid_gid(argv[0], O_RDONLY, pas->pw_uid, pas->pw_gid); |
141 | if (src_fd < 0) | ||
142 | bb_error_msg_and_die("user %s cannot read %s", | ||
143 | pas->pw_name, argv[0]); | ||
144 | } | 119 | } |
145 | } | 120 | } |
146 | 121 | ||
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 24c953bac..96ffe0738 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
@@ -1083,21 +1083,23 @@ static int get_uid_gid(int flag, const char *string) | |||
1083 | { | 1083 | { |
1084 | struct passwd *pw_ent; | 1084 | struct passwd *pw_ent; |
1085 | struct group *grp_ent; | 1085 | struct group *grp_ent; |
1086 | static const char *msg; | 1086 | const char *msg; |
1087 | 1087 | ||
1088 | if (ENABLE_DEVFSD_VERBOSE) | 1088 | if (isdigit(string[0]) || ((string[0] == '-') && isdigit(string[1]))) |
1089 | msg = "user"; | ||
1090 | |||
1091 | if (isdigit(string[0]) ||((string[0] == '-') && isdigit(string[1]))) | ||
1092 | return atoi(string); | 1089 | return atoi(string); |
1093 | 1090 | ||
1094 | if (flag == UID && (pw_ent = getpwnam(string)) != NULL) | 1091 | if (flag == UID && (pw_ent = getpwnam(string)) != NULL) |
1095 | return pw_ent->pw_uid; | 1092 | return pw_ent->pw_uid; |
1096 | 1093 | ||
1097 | if (flag == GID && (grp_ent = getgrnam(string)) != NULL) | 1094 | if (ENABLE_DEVFSD_VERBOSE) |
1098 | return grp_ent->gr_gid; | 1095 | msg = "user"; |
1099 | else if (ENABLE_DEVFSD_VERBOSE) | 1096 | |
1100 | msg = "group"; | 1097 | if (flag == GID) { |
1098 | if ((grp_ent = getgrnam(string)) != NULL) | ||
1099 | return grp_ent->gr_gid; | ||
1100 | if (ENABLE_DEVFSD_VERBOSE) | ||
1101 | msg = "group"; | ||
1102 | } | ||
1101 | 1103 | ||
1102 | if (ENABLE_DEVFSD_VERBOSE) | 1104 | if (ENABLE_DEVFSD_VERBOSE) |
1103 | msg_logger(LOG_ERR, "unknown %s: %s, defaulting to %cid=0", msg, string, msg[0]); | 1105 | msg_logger(LOG_ERR, "unknown %s: %s, defaulting to %cid=0", msg, string, msg[0]); |
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 69726ae72..f0e9c9d75 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -465,14 +465,14 @@ static void on_off(int value) | |||
465 | static void print_flag_on_off(int get_arg, const char *s, unsigned long arg) | 465 | static void print_flag_on_off(int get_arg, const char *s, unsigned long arg) |
466 | { | 466 | { |
467 | if (get_arg) { | 467 | if (get_arg) { |
468 | printf(" setting %s to %ld", s, arg); | 468 | printf(" setting %s to %lu", s, arg); |
469 | on_off(arg); | 469 | on_off(arg); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | static void print_value_on_off(const char *str, unsigned long argp) | 473 | static void print_value_on_off(const char *str, unsigned long argp) |
474 | { | 474 | { |
475 | printf(" %s\t= %2ld", str, argp); | 475 | printf(" %s\t= %2lu", str, argp); |
476 | on_off(argp != 0); | 476 | on_off(argp != 0); |
477 | } | 477 | } |
478 | 478 | ||
@@ -1509,7 +1509,7 @@ static void bus_state_value(unsigned value) | |||
1509 | else if (value == BUSSTATE_TRISTATE) | 1509 | else if (value == BUSSTATE_TRISTATE) |
1510 | printf(" (tristate)\n"); | 1510 | printf(" (tristate)\n"); |
1511 | else | 1511 | else |
1512 | printf(" (unknown: %d)\n", value); | 1512 | printf(" (unknown: %u)\n", value); |
1513 | } | 1513 | } |
1514 | #endif | 1514 | #endif |
1515 | 1515 | ||
@@ -1589,7 +1589,7 @@ static void interpret_xfermode(unsigned xfermode) | |||
1589 | static void print_flag(int flag, const char *s, unsigned long value) | 1589 | static void print_flag(int flag, const char *s, unsigned long value) |
1590 | { | 1590 | { |
1591 | if (flag) | 1591 | if (flag) |
1592 | printf(" setting %s to %ld\n", s, value); | 1592 | printf(" setting %s to %lu\n", s, value); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | static void process_dev(char *devname) | 1595 | static void process_dev(char *devname) |
diff --git a/miscutils/rfkill.c b/miscutils/rfkill.c index 467197371..7411b6fc3 100644 --- a/miscutils/rfkill.c +++ b/miscutils/rfkill.c | |||
@@ -7,6 +7,23 @@ | |||
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 | 9 | ||
10 | //config:config RFKILL | ||
11 | //config: bool "rfkill" | ||
12 | //config: default n # doesn't build on Ubuntu 9.04 | ||
13 | //config: select PLATFORM_LINUX | ||
14 | //config: help | ||
15 | //config: Enable/disable wireless devices. | ||
16 | //config: | ||
17 | //config: rfkill list : list all wireless devices | ||
18 | //config: rfkill list bluetooth : list all bluetooth devices | ||
19 | //config: rfkill list 1 : list device corresponding to the given index | ||
20 | //config: rfkill block|unblock wlan : block/unblock all wlan(wifi) devices | ||
21 | //config: | ||
22 | |||
23 | //applet:IF_RFKILL(APPLET(rfkill, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
24 | |||
25 | //kbuild:lib-$(CONFIG_RFKILL) += rfkill.o | ||
26 | |||
10 | //usage:#define rfkill_trivial_usage | 27 | //usage:#define rfkill_trivial_usage |
11 | //usage: "COMMAND [INDEX|TYPE]" | 28 | //usage: "COMMAND [INDEX|TYPE]" |
12 | //usage:#define rfkill_full_usage "\n\n" | 29 | //usage:#define rfkill_full_usage "\n\n" |
diff --git a/miscutils/wall.c b/miscutils/wall.c index 762f53b72..bb709ee39 100644 --- a/miscutils/wall.c +++ b/miscutils/wall.c | |||
@@ -6,6 +6,18 @@ | |||
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 | 8 | ||
9 | //config:config WALL | ||
10 | //config: bool "wall" | ||
11 | //config: default y | ||
12 | //config: depends on FEATURE_UTMP | ||
13 | //config: help | ||
14 | //config: Write a message to all users that are logged in. | ||
15 | |||
16 | /* Needs to be run by root or be suid root - needs to write to /dev/TTY: */ | ||
17 | //applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) | ||
18 | |||
19 | //kbuild:lib-$(CONFIG_WALL) += wall.o | ||
20 | |||
9 | //usage:#define wall_trivial_usage | 21 | //usage:#define wall_trivial_usage |
10 | //usage: "[FILE]" | 22 | //usage: "[FILE]" |
11 | //usage:#define wall_full_usage "\n\n" | 23 | //usage:#define wall_full_usage "\n\n" |
@@ -22,8 +34,15 @@ int wall_main(int argc UNUSED_PARAM, char **argv) | |||
22 | { | 34 | { |
23 | struct utmp *ut; | 35 | struct utmp *ut; |
24 | char *msg; | 36 | char *msg; |
25 | int fd = argv[1] ? xopen(argv[1], O_RDONLY) : STDIN_FILENO; | 37 | int fd; |
26 | 38 | ||
39 | fd = STDIN_FILENO; | ||
40 | if (argv[1]) { | ||
41 | /* The applet is setuid. | ||
42 | * Access to the file must be under user's uid/gid. | ||
43 | */ | ||
44 | fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); | ||
45 | } | ||
27 | msg = xmalloc_read(fd, NULL); | 46 | msg = xmalloc_read(fd, NULL); |
28 | if (ENABLE_FEATURE_CLEAN_UP && argv[1]) | 47 | if (ENABLE_FEATURE_CLEAN_UP && argv[1]) |
29 | close(fd); | 48 | close(fd); |
diff --git a/networking/Config.src b/networking/Config.src index e1ae0c9d5..ca0ddcdd9 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -970,16 +970,18 @@ config FEATURE_WGET_LONG_OPTIONS | |||
970 | Support long options for the wget applet. | 970 | Support long options for the wget applet. |
971 | 971 | ||
972 | config FEATURE_WGET_TIMEOUT | 972 | config FEATURE_WGET_TIMEOUT |
973 | bool "Enable read timeout option -T SEC" | 973 | bool "Enable timeout option -T SEC" |
974 | default y | 974 | default y |
975 | depends on WGET | 975 | depends on WGET |
976 | help | 976 | help |
977 | Supports network read timeout for wget, so that wget will give | 977 | Supports network read and connect timeouts for wget, |
978 | up and timeout when reading network data, through the -T command | 978 | so that wget will give up and timeout, through the -T |
979 | line option. Currently only network data read timeout is | 979 | command line option. |
980 | supported (i.e., timeout is not applied to the DNS nor TCP | 980 | |
981 | connection initialization). When FEATURE_WGET_LONG_OPTIONS is | 981 | Currently only connect and network data read timeout are |
982 | also enabled, the --timeout option will work in addition to -T. | 982 | supported (i.e., timeout is not applied to the DNS query). When |
983 | FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option | ||
984 | will work in addition to -T. | ||
983 | 985 | ||
984 | config ZCIP | 986 | config ZCIP |
985 | bool "zcip" | 987 | bool "zcip" |
diff --git a/networking/arp.c b/networking/arp.c index 40d244116..e79b1b6a1 100644 --- a/networking/arp.c +++ b/networking/arp.c | |||
@@ -459,12 +459,12 @@ static int arp_show(char *name) | |||
459 | arp_disp(hostname, ip, type, flags, hwa, mask, dev); | 459 | arp_disp(hostname, ip, type, flags, hwa, mask, dev); |
460 | } | 460 | } |
461 | if (option_mask32 & ARP_OPT_v) | 461 | if (option_mask32 & ARP_OPT_v) |
462 | printf("Entries: %d\tSkipped: %d\tFound: %d\n", | 462 | printf("Entries: %u\tSkipped: %u\tFound: %u\n", |
463 | entries, entries - shown, shown); | 463 | entries, entries - shown, shown); |
464 | 464 | ||
465 | if (!shown) { | 465 | if (!shown) { |
466 | if (hw_set || host || device[0]) | 466 | if (hw_set || host || device[0]) |
467 | printf("No match found in %d entries\n", entries); | 467 | printf("No match found in %u entries\n", entries); |
468 | } | 468 | } |
469 | if (ENABLE_FEATURE_CLEAN_UP) { | 469 | if (ENABLE_FEATURE_CLEAN_UP) { |
470 | free((char*)host); | 470 | free((char*)host); |
diff --git a/networking/ether-wake.c b/networking/ether-wake.c index 2d389ea30..c38547dda 100644 --- a/networking/ether-wake.c +++ b/networking/ether-wake.c | |||
@@ -62,17 +62,17 @@ | |||
62 | * An alternative to needing 'root' is using a UDP broadcast socket, however | 62 | * An alternative to needing 'root' is using a UDP broadcast socket, however |
63 | * doing so only works with adapters configured for unicast+broadcast Rx | 63 | * doing so only works with adapters configured for unicast+broadcast Rx |
64 | * filter. That configuration consumes more power. | 64 | * filter. That configuration consumes more power. |
65 | */ | 65 | */ |
66 | 66 | ||
67 | //usage:#define ether_wake_trivial_usage | 67 | //usage:#define ether_wake_trivial_usage |
68 | //usage: "[-b] [-i iface] [-p aa:bb:cc:dd[:ee:ff]] MAC" | 68 | //usage: "[-b] [-i IFACE] [-p aa:bb:cc:dd[:ee:ff]/a.b.c.d] MAC" |
69 | //usage:#define ether_wake_full_usage "\n\n" | 69 | //usage:#define ether_wake_full_usage "\n\n" |
70 | //usage: "Send a magic packet to wake up sleeping machines.\n" | 70 | //usage: "Send a magic packet to wake up sleeping machines.\n" |
71 | //usage: "MAC must be a station address (00:11:22:33:44:55) or\n" | 71 | //usage: "MAC must be a station address (00:11:22:33:44:55) or\n" |
72 | //usage: "a hostname with a known 'ethers' entry.\n" | 72 | //usage: "a hostname with a known 'ethers' entry.\n" |
73 | //usage: "\n -b Send wake-up packet to the broadcast address" | 73 | //usage: "\n -b Broadcast the packet" |
74 | //usage: "\n -i iface Interface to use (default eth0)" | 74 | //usage: "\n -i IFACE Interface to use (default eth0)" |
75 | //usage: "\n -p pass Append four or six byte password PW to the packet" | 75 | //usage: "\n -p PASSWORD Append four or six byte PASSWORD to the packet" |
76 | 76 | ||
77 | #include "libbb.h" | 77 | #include "libbb.h" |
78 | #include <netpacket/packet.h> | 78 | #include <netpacket/packet.h> |
@@ -130,7 +130,8 @@ static void get_dest_addr(const char *hostid, struct ether_addr *eaddr) | |||
130 | } | 130 | } |
131 | } | 131 | } |
132 | 132 | ||
133 | static int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) | 133 | #define PKT_HEADER_SIZE (20 + 16*6) |
134 | static int fill_pkt_header(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) | ||
134 | { | 135 | { |
135 | int i; | 136 | int i; |
136 | unsigned char *station_addr = eaddr->ether_addr_octet; | 137 | unsigned char *station_addr = eaddr->ether_addr_octet; |
@@ -153,7 +154,7 @@ static int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) | |||
153 | memcpy(pkt, station_addr, 6); /* 20,26,32,... */ | 154 | memcpy(pkt, station_addr, 6); /* 20,26,32,... */ |
154 | } | 155 | } |
155 | 156 | ||
156 | return 20 + 16*6; /* length of packet */ | 157 | return PKT_HEADER_SIZE; /* length of packet */ |
157 | } | 158 | } |
158 | 159 | ||
159 | static int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd) | 160 | static int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd) |
@@ -195,7 +196,7 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv) | |||
195 | int wol_passwd_sz = 0; | 196 | int wol_passwd_sz = 0; |
196 | int s; /* Raw socket */ | 197 | int s; /* Raw socket */ |
197 | int pktsize; | 198 | int pktsize; |
198 | unsigned char outpack[1000]; | 199 | unsigned char outpack[PKT_HEADER_SIZE + 6 /* max passwd size */ + 16 /* paranoia */]; |
199 | 200 | ||
200 | struct ether_addr eaddr; | 201 | struct ether_addr eaddr; |
201 | struct whereto_t whereto; /* who to wake up */ | 202 | struct whereto_t whereto; /* who to wake up */ |
@@ -217,7 +218,7 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv) | |||
217 | get_dest_addr(argv[optind], &eaddr); | 218 | get_dest_addr(argv[optind], &eaddr); |
218 | 219 | ||
219 | /* fill out the header of the packet */ | 220 | /* fill out the header of the packet */ |
220 | pktsize = get_fill(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */); | 221 | pktsize = fill_pkt_header(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */); |
221 | 222 | ||
222 | bb_debug_dump_packet(outpack, pktsize); | 223 | bb_debug_dump_packet(outpack, pktsize); |
223 | 224 | ||
diff --git a/networking/hostname.c b/networking/hostname.c index d2516b5fb..b3e352242 100644 --- a/networking/hostname.c +++ b/networking/hostname.c | |||
@@ -106,7 +106,7 @@ int hostname_main(int argc UNUSED_PARAM, char **argv) | |||
106 | OPT_i = 0x4, | 106 | OPT_i = 0x4, |
107 | OPT_s = 0x8, | 107 | OPT_s = 0x8, |
108 | OPT_F = 0x10, | 108 | OPT_F = 0x10, |
109 | OPT_dfis = 0xf, | 109 | OPT_dfi = 0x7, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | unsigned opts; | 112 | unsigned opts; |
@@ -134,7 +134,7 @@ int hostname_main(int argc UNUSED_PARAM, char **argv) | |||
134 | if (applet_name[0] == 'd') /* dnsdomainname? */ | 134 | if (applet_name[0] == 'd') /* dnsdomainname? */ |
135 | opts = OPT_d; | 135 | opts = OPT_d; |
136 | 136 | ||
137 | if (opts & OPT_dfis) { | 137 | if (opts & OPT_dfi) { |
138 | /* Cases when we need full hostname (or its part) */ | 138 | /* Cases when we need full hostname (or its part) */ |
139 | struct hostent *hp; | 139 | struct hostent *hp; |
140 | char *p; | 140 | char *p; |
@@ -159,6 +159,9 @@ int hostname_main(int argc UNUSED_PARAM, char **argv) | |||
159 | bb_putchar('\n'); | 159 | bb_putchar('\n'); |
160 | } | 160 | } |
161 | } | 161 | } |
162 | } else if (opts & OPT_s) { | ||
163 | strchrnul(buf, '.')[0] = '\0'; | ||
164 | puts(buf); | ||
162 | } else if (opts & OPT_F) { | 165 | } else if (opts & OPT_F) { |
163 | /* Set the hostname */ | 166 | /* Set the hostname */ |
164 | do_sethostname(hostname_str, 1); | 167 | do_sethostname(hostname_str, 1); |
diff --git a/networking/httpd.c b/networking/httpd.c index cef9b8baf..621d9cddc 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -1104,18 +1104,31 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1104 | 1104 | ||
1105 | /* NB: breaking out of this loop jumps to log_and_exit() */ | 1105 | /* NB: breaking out of this loop jumps to log_and_exit() */ |
1106 | out_cnt = 0; | 1106 | out_cnt = 0; |
1107 | pfd[FROM_CGI].fd = fromCgi_rd; | ||
1108 | pfd[FROM_CGI].events = POLLIN; | ||
1109 | pfd[TO_CGI].fd = toCgi_wr; | ||
1107 | while (1) { | 1110 | while (1) { |
1108 | memset(pfd, 0, sizeof(pfd)); | 1111 | /* Note: even pfd[0].events == 0 won't prevent |
1109 | 1112 | * revents == POLLHUP|POLLERR reports from closed stdin. | |
1110 | pfd[FROM_CGI].fd = fromCgi_rd; | 1113 | * Setting fd to -1 works: */ |
1111 | pfd[FROM_CGI].events = POLLIN; | 1114 | pfd[0].fd = -1; |
1112 | 1115 | pfd[0].events = POLLIN; | |
1113 | if (toCgi_wr) { | 1116 | pfd[0].revents = 0; /* probably not needed, paranoia */ |
1114 | pfd[TO_CGI].fd = toCgi_wr; | 1117 | |
1115 | if (hdr_cnt > 0) { | 1118 | /* We always poll this fd, thus kernel always sets revents: */ |
1116 | pfd[TO_CGI].events = POLLOUT; | 1119 | /*pfd[FROM_CGI].events = POLLIN; - moved out of loop */ |
1117 | } else if (post_len > 0) { | 1120 | /*pfd[FROM_CGI].revents = 0; - not needed */ |
1118 | pfd[0].events = POLLIN; | 1121 | |
1122 | /* gcc-4.8.0 still doesnt fill two shorts with one insn :( */ | ||
1123 | /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47059 */ | ||
1124 | /* hopefully one day it will... */ | ||
1125 | pfd[TO_CGI].events = POLLOUT; | ||
1126 | pfd[TO_CGI].revents = 0; /* needed! */ | ||
1127 | |||
1128 | if (toCgi_wr && hdr_cnt <= 0) { | ||
1129 | if (post_len > 0) { | ||
1130 | /* Expect more POST data from network */ | ||
1131 | pfd[0].fd = 0; | ||
1119 | } else { | 1132 | } else { |
1120 | /* post_len <= 0 && hdr_cnt <= 0: | 1133 | /* post_len <= 0 && hdr_cnt <= 0: |
1121 | * no more POST data to CGI, | 1134 | * no more POST data to CGI, |
@@ -1127,7 +1140,7 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1127 | } | 1140 | } |
1128 | 1141 | ||
1129 | /* Now wait on the set of sockets */ | 1142 | /* Now wait on the set of sockets */ |
1130 | count = safe_poll(pfd, toCgi_wr ? TO_CGI+1 : FROM_CGI+1, -1); | 1143 | count = safe_poll(pfd, hdr_cnt > 0 ? TO_CGI+1 : FROM_CGI+1, -1); |
1131 | if (count <= 0) { | 1144 | if (count <= 0) { |
1132 | #if 0 | 1145 | #if 0 |
1133 | if (safe_waitpid(pid, &status, WNOHANG) <= 0) { | 1146 | if (safe_waitpid(pid, &status, WNOHANG) <= 0) { |
@@ -1144,7 +1157,7 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1144 | } | 1157 | } |
1145 | 1158 | ||
1146 | if (pfd[TO_CGI].revents) { | 1159 | if (pfd[TO_CGI].revents) { |
1147 | /* hdr_cnt > 0 here due to the way pfd[TO_CGI].events set */ | 1160 | /* hdr_cnt > 0 here due to the way poll() called */ |
1148 | /* Have data from peer and can write to CGI */ | 1161 | /* Have data from peer and can write to CGI */ |
1149 | count = safe_write(toCgi_wr, hdr_ptr, hdr_cnt); | 1162 | count = safe_write(toCgi_wr, hdr_ptr, hdr_cnt); |
1150 | /* Doesn't happen, we dont use nonblocking IO here | 1163 | /* Doesn't happen, we dont use nonblocking IO here |
diff --git a/networking/netstat.c b/networking/netstat.c index c0c6ba501..f80b845bc 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
@@ -125,10 +125,10 @@ typedef enum { | |||
125 | */ | 125 | */ |
126 | #define ADDR_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */ | 126 | #define ADDR_WIDE 51 /* INET6_ADDRSTRLEN + 5 for the port number */ |
127 | #if ENABLE_FEATURE_NETSTAT_WIDE | 127 | #if ENABLE_FEATURE_NETSTAT_WIDE |
128 | # define FMT_NET_CONN_DATA "%s %6ld %6ld %-*s %-*s %-12s" | 128 | # define FMT_NET_CONN_DATA "%s %6lu %6lu %-*s %-*s %-12s" |
129 | # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-*s %-*s State %s\n" | 129 | # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-*s %-*s State %s\n" |
130 | #else | 130 | #else |
131 | # define FMT_NET_CONN_DATA "%s %6ld %6ld %-23s %-23s %-12s" | 131 | # define FMT_NET_CONN_DATA "%s %6lu %6lu %-23s %-23s %-12s" |
132 | # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State %s\n" | 132 | # define FMT_NET_CONN_HEADER "\nProto Recv-Q Send-Q %-23s %-23s State %s\n" |
133 | #endif | 133 | #endif |
134 | 134 | ||
@@ -403,7 +403,7 @@ static int scan_inet_proc_line(struct inet_params *param, char *line) | |||
403 | "%*d: %32[0-9A-Fa-f]:%X " | 403 | "%*d: %32[0-9A-Fa-f]:%X " |
404 | "%32[0-9A-Fa-f]:%X %X " | 404 | "%32[0-9A-Fa-f]:%X %X " |
405 | "%lX:%lX %*X:%*X " | 405 | "%lX:%lX %*X:%*X " |
406 | "%*X %d %*d %ld ", | 406 | "%*X %d %*d %lu ", |
407 | local_addr, ¶m->local_port, | 407 | local_addr, ¶m->local_port, |
408 | rem_addr, ¶m->rem_port, ¶m->state, | 408 | rem_addr, ¶m->rem_port, ¶m->state, |
409 | ¶m->txq, ¶m->rxq, | 409 | ¶m->txq, ¶m->rxq, |
@@ -611,7 +611,7 @@ static int FAST_FUNC unix_do_one(char *line) | |||
611 | strcat(ss_flags, "N "); | 611 | strcat(ss_flags, "N "); |
612 | strcat(ss_flags, "]"); | 612 | strcat(ss_flags, "]"); |
613 | 613 | ||
614 | printf("%-5s %-6ld %-11s %-10s %-13s %6lu ", | 614 | printf("%-5s %-6lu %-11s %-10s %-13s %6lu ", |
615 | ss_proto, refcnt, ss_flags, ss_type, ss_state, inode | 615 | ss_proto, refcnt, ss_flags, ss_type, ss_state, inode |
616 | ); | 616 | ); |
617 | 617 | ||
diff --git a/networking/ntpd.c b/networking/ntpd.c index 99817e83b..ed83415b4 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -57,10 +57,10 @@ | |||
57 | 57 | ||
58 | 58 | ||
59 | /* Verbosity control (max level of -dddd options accepted). | 59 | /* Verbosity control (max level of -dddd options accepted). |
60 | * max 5 is very talkative (and bloated). 2 is non-bloated, | 60 | * max 6 is very talkative (and bloated). 3 is non-bloated, |
61 | * production level setting. | 61 | * production level setting. |
62 | */ | 62 | */ |
63 | #define MAX_VERBOSE 2 | 63 | #define MAX_VERBOSE 3 |
64 | 64 | ||
65 | 65 | ||
66 | /* High-level description of the algorithm: | 66 | /* High-level description of the algorithm: |
@@ -90,12 +90,24 @@ | |||
90 | * was hibernated, someone set totally wrong date, etc), | 90 | * was hibernated, someone set totally wrong date, etc), |
91 | * then the time is stepped, all datapoints are discarded, | 91 | * then the time is stepped, all datapoints are discarded, |
92 | * and we go back to steady state. | 92 | * and we go back to steady state. |
93 | * | ||
94 | * Made some changes to speed up re-syncing after our clock goes bad | ||
95 | * (tested with suspending my laptop): | ||
96 | * - if largish offset (>= STEP_THRESHOLD * 8 == 1 sec) is seen | ||
97 | * from a peer, schedule next query for this peer soon | ||
98 | * without drastically lowering poll interval for everybody. | ||
99 | * This makes us collect enough data for step much faster: | ||
100 | * e.g. at poll = 10 (1024 secs), step was done within 5 minutes | ||
101 | * after first reply which indicated that our clock is 14 seconds off. | ||
102 | * - on step, do not discard d_dispersion data of the existing datapoints, | ||
103 | * do not clear reachable_bits. This prevents discarding first ~8 | ||
104 | * datapoints after the step. | ||
93 | */ | 105 | */ |
94 | 106 | ||
95 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ | 107 | #define RETRY_INTERVAL 5 /* on error, retry in N secs */ |
96 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ | 108 | #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ |
97 | #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ | 109 | #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ |
98 | #define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ | 110 | #define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ |
99 | 111 | ||
100 | /* Clock discipline parameters and constants */ | 112 | /* Clock discipline parameters and constants */ |
101 | 113 | ||
@@ -109,6 +121,10 @@ | |||
109 | #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ | 121 | #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ |
110 | #define BURSTPOLL 0 /* initial poll */ | 122 | #define BURSTPOLL 0 /* initial poll */ |
111 | #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ | 123 | #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ |
124 | /* If we got largish offset from a peer, cap next query interval | ||
125 | * for this peer by this many seconds: | ||
126 | */ | ||
127 | #define BIGOFF_INTERVAL (1 << 6) | ||
112 | /* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL, | 128 | /* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL, |
113 | * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_). | 129 | * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_). |
114 | */ | 130 | */ |
@@ -334,7 +350,7 @@ struct globals { | |||
334 | 350 | ||
335 | #define STATE_NSET 0 /* initial state, "nothing is set" */ | 351 | #define STATE_NSET 0 /* initial state, "nothing is set" */ |
336 | //#define STATE_FSET 1 /* frequency set from file */ | 352 | //#define STATE_FSET 1 /* frequency set from file */ |
337 | #define STATE_SPIK 2 /* spike detected */ | 353 | //#define STATE_SPIK 2 /* spike detected */ |
338 | //#define STATE_FREQ 3 /* initial frequency */ | 354 | //#define STATE_FREQ 3 /* initial frequency */ |
339 | #define STATE_SYNC 4 /* clock synchronized (normal operation) */ | 355 | #define STATE_SYNC 4 /* clock synchronized (normal operation) */ |
340 | uint8_t discipline_state; // doc calls it c.state | 356 | uint8_t discipline_state; // doc calls it c.state |
@@ -367,6 +383,7 @@ static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY; | |||
367 | #define VERB3 if (MAX_VERBOSE >= 3 && G.verbose >= 3) | 383 | #define VERB3 if (MAX_VERBOSE >= 3 && G.verbose >= 3) |
368 | #define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4) | 384 | #define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4) |
369 | #define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5) | 385 | #define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5) |
386 | #define VERB6 if (MAX_VERBOSE >= 6 && G.verbose >= 6) | ||
370 | 387 | ||
371 | 388 | ||
372 | static double LOG2D(int a) | 389 | static double LOG2D(int a) |
@@ -568,7 +585,7 @@ filter_datapoints(peer_t *p) | |||
568 | got_newest = 0; | 585 | got_newest = 0; |
569 | sum = 0; | 586 | sum = 0; |
570 | for (i = 0; i < NUM_DATAPOINTS; i++) { | 587 | for (i = 0; i < NUM_DATAPOINTS; i++) { |
571 | VERB4 { | 588 | VERB5 { |
572 | bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", | 589 | bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", |
573 | i, | 590 | i, |
574 | fdp[idx].d_offset, | 591 | fdp[idx].d_offset, |
@@ -665,7 +682,7 @@ filter_datapoints(peer_t *p) | |||
665 | sum = SQRT(sum / NUM_DATAPOINTS); | 682 | sum = SQRT(sum / NUM_DATAPOINTS); |
666 | p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; | 683 | p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; |
667 | 684 | ||
668 | VERB3 bb_error_msg("filter offset:%+f disp:%f jitter:%f", | 685 | VERB4 bb_error_msg("filter offset:%+f disp:%f jitter:%f", |
669 | p->filter_offset, | 686 | p->filter_offset, |
670 | p->filter_dispersion, | 687 | p->filter_dispersion, |
671 | p->filter_jitter); | 688 | p->filter_jitter); |
@@ -677,6 +694,18 @@ reset_peer_stats(peer_t *p, double offset) | |||
677 | int i; | 694 | int i; |
678 | bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; | 695 | bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; |
679 | 696 | ||
697 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP | ||
698 | * and clear reachable bits, but this proved to be too agressive: | ||
699 | * after step (tested with suspinding laptop for ~30 secs), | ||
700 | * this caused all previous data to be considered invalid, | ||
701 | * making us needing to collect full ~8 datapoins per peer | ||
702 | * after step in order to start trusting them. | ||
703 | * In turn, this was making poll interval decrease even after | ||
704 | * step was done. (Poll interval decreases already before step | ||
705 | * in this scenario, because we see large offsets and end up with | ||
706 | * no good peer to select). | ||
707 | */ | ||
708 | |||
680 | for (i = 0; i < NUM_DATAPOINTS; i++) { | 709 | for (i = 0; i < NUM_DATAPOINTS; i++) { |
681 | if (small_ofs) { | 710 | if (small_ofs) { |
682 | p->filter_datapoint[i].d_recv_time += offset; | 711 | p->filter_datapoint[i].d_recv_time += offset; |
@@ -690,17 +719,17 @@ reset_peer_stats(peer_t *p, double offset) | |||
690 | } else { | 719 | } else { |
691 | p->filter_datapoint[i].d_recv_time = G.cur_time; | 720 | p->filter_datapoint[i].d_recv_time = G.cur_time; |
692 | p->filter_datapoint[i].d_offset = 0; | 721 | p->filter_datapoint[i].d_offset = 0; |
693 | p->filter_datapoint[i].d_dispersion = MAXDISP; | 722 | /*p->filter_datapoint[i].d_dispersion = MAXDISP;*/ |
694 | } | 723 | } |
695 | } | 724 | } |
696 | if (small_ofs) { | 725 | if (small_ofs) { |
697 | p->lastpkt_recv_time += offset; | 726 | p->lastpkt_recv_time += offset; |
698 | } else { | 727 | } else { |
699 | p->reachable_bits = 0; | 728 | /*p->reachable_bits = 0;*/ |
700 | p->lastpkt_recv_time = G.cur_time; | 729 | p->lastpkt_recv_time = G.cur_time; |
701 | } | 730 | } |
702 | filter_datapoints(p); /* recalc p->filter_xxx */ | 731 | filter_datapoints(p); /* recalc p->filter_xxx */ |
703 | VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); | 732 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); |
704 | } | 733 | } |
705 | 734 | ||
706 | static void | 735 | static void |
@@ -972,20 +1001,20 @@ fit(peer_t *p, double rd) | |||
972 | { | 1001 | { |
973 | if ((p->reachable_bits & (p->reachable_bits-1)) == 0) { | 1002 | if ((p->reachable_bits & (p->reachable_bits-1)) == 0) { |
974 | /* One or zero bits in reachable_bits */ | 1003 | /* One or zero bits in reachable_bits */ |
975 | VERB3 bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted); | 1004 | VERB4 bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted); |
976 | return 0; | 1005 | return 0; |
977 | } | 1006 | } |
978 | #if 0 /* we filter out such packets earlier */ | 1007 | #if 0 /* we filter out such packets earlier */ |
979 | if ((p->lastpkt_status & LI_ALARM) == LI_ALARM | 1008 | if ((p->lastpkt_status & LI_ALARM) == LI_ALARM |
980 | || p->lastpkt_stratum >= MAXSTRAT | 1009 | || p->lastpkt_stratum >= MAXSTRAT |
981 | ) { | 1010 | ) { |
982 | VERB3 bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted); | 1011 | VERB4 bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted); |
983 | return 0; | 1012 | return 0; |
984 | } | 1013 | } |
985 | #endif | 1014 | #endif |
986 | /* rd is root_distance(p) */ | 1015 | /* rd is root_distance(p) */ |
987 | if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) { | 1016 | if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) { |
988 | VERB3 bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted); | 1017 | VERB4 bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted); |
989 | return 0; | 1018 | return 0; |
990 | } | 1019 | } |
991 | //TODO | 1020 | //TODO |
@@ -1025,7 +1054,7 @@ select_and_cluster(void) | |||
1025 | continue; | 1054 | continue; |
1026 | } | 1055 | } |
1027 | 1056 | ||
1028 | VERB4 bb_error_msg("interval: [%f %f %f] %s", | 1057 | VERB5 bb_error_msg("interval: [%f %f %f] %s", |
1029 | offset - rd, | 1058 | offset - rd, |
1030 | offset, | 1059 | offset, |
1031 | offset + rd, | 1060 | offset + rd, |
@@ -1050,7 +1079,7 @@ select_and_cluster(void) | |||
1050 | } | 1079 | } |
1051 | num_candidates = num_points / 3; | 1080 | num_candidates = num_points / 3; |
1052 | if (num_candidates == 0) { | 1081 | if (num_candidates == 0) { |
1053 | VERB3 bb_error_msg("no valid datapoints, no peer selected"); | 1082 | VERB3 bb_error_msg("no valid datapoints%s", ", no peer selected"); |
1054 | return NULL; | 1083 | return NULL; |
1055 | } | 1084 | } |
1056 | //TODO: sorting does not seem to be done in reference code | 1085 | //TODO: sorting does not seem to be done in reference code |
@@ -1108,12 +1137,13 @@ select_and_cluster(void) | |||
1108 | break; | 1137 | break; |
1109 | num_falsetickers++; | 1138 | num_falsetickers++; |
1110 | if (num_falsetickers * 2 >= num_candidates) { | 1139 | if (num_falsetickers * 2 >= num_candidates) { |
1111 | VERB3 bb_error_msg("too many falsetickers:%d (candidates:%d), no peer selected", | 1140 | VERB3 bb_error_msg("falsetickers:%d, candidates:%d%s", |
1112 | num_falsetickers, num_candidates); | 1141 | num_falsetickers, num_candidates, |
1142 | ", no peer selected"); | ||
1113 | return NULL; | 1143 | return NULL; |
1114 | } | 1144 | } |
1115 | } | 1145 | } |
1116 | VERB3 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d", | 1146 | VERB4 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d", |
1117 | low, high, num_candidates, num_falsetickers); | 1147 | low, high, num_candidates, num_falsetickers); |
1118 | 1148 | ||
1119 | /* Clustering */ | 1149 | /* Clustering */ |
@@ -1131,7 +1161,7 @@ select_and_cluster(void) | |||
1131 | survivor[num_survivors].p = p; | 1161 | survivor[num_survivors].p = p; |
1132 | /* x.opt_rd == root_distance(p); */ | 1162 | /* x.opt_rd == root_distance(p); */ |
1133 | survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd; | 1163 | survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd; |
1134 | VERB4 bb_error_msg("survivor[%d] metric:%f peer:%s", | 1164 | VERB5 bb_error_msg("survivor[%d] metric:%f peer:%s", |
1135 | num_survivors, survivor[num_survivors].metric, p->p_dotted); | 1165 | num_survivors, survivor[num_survivors].metric, p->p_dotted); |
1136 | num_survivors++; | 1166 | num_survivors++; |
1137 | } | 1167 | } |
@@ -1141,8 +1171,9 @@ select_and_cluster(void) | |||
1141 | * is acceptable. | 1171 | * is acceptable. |
1142 | */ | 1172 | */ |
1143 | if (num_survivors < MIN_SELECTED) { | 1173 | if (num_survivors < MIN_SELECTED) { |
1144 | VERB3 bb_error_msg("num_survivors %d < %d, no peer selected", | 1174 | VERB3 bb_error_msg("survivors:%d%s", |
1145 | num_survivors, MIN_SELECTED); | 1175 | num_survivors, |
1176 | ", no peer selected"); | ||
1146 | return NULL; | 1177 | return NULL; |
1147 | } | 1178 | } |
1148 | 1179 | ||
@@ -1162,7 +1193,7 @@ select_and_cluster(void) | |||
1162 | double min_jitter = min_jitter; | 1193 | double min_jitter = min_jitter; |
1163 | 1194 | ||
1164 | if (num_survivors <= MIN_CLUSTERED) { | 1195 | if (num_survivors <= MIN_CLUSTERED) { |
1165 | VERB3 bb_error_msg("num_survivors %d <= %d, not discarding more", | 1196 | VERB4 bb_error_msg("num_survivors %d <= %d, not discarding more", |
1166 | num_survivors, MIN_CLUSTERED); | 1197 | num_survivors, MIN_CLUSTERED); |
1167 | break; | 1198 | break; |
1168 | } | 1199 | } |
@@ -1188,11 +1219,11 @@ select_and_cluster(void) | |||
1188 | max_selection_jitter = selection_jitter_sq; | 1219 | max_selection_jitter = selection_jitter_sq; |
1189 | max_idx = i; | 1220 | max_idx = i; |
1190 | } | 1221 | } |
1191 | VERB5 bb_error_msg("survivor %d selection_jitter^2:%f", | 1222 | VERB6 bb_error_msg("survivor %d selection_jitter^2:%f", |
1192 | i, selection_jitter_sq); | 1223 | i, selection_jitter_sq); |
1193 | } | 1224 | } |
1194 | max_selection_jitter = SQRT(max_selection_jitter / num_survivors); | 1225 | max_selection_jitter = SQRT(max_selection_jitter / num_survivors); |
1195 | VERB4 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f", | 1226 | VERB5 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f", |
1196 | max_idx, max_selection_jitter, min_jitter); | 1227 | max_idx, max_selection_jitter, min_jitter); |
1197 | 1228 | ||
1198 | /* If the maximum selection jitter is less than the | 1229 | /* If the maximum selection jitter is less than the |
@@ -1201,7 +1232,7 @@ select_and_cluster(void) | |||
1201 | * as well stop. | 1232 | * as well stop. |
1202 | */ | 1233 | */ |
1203 | if (max_selection_jitter < min_jitter) { | 1234 | if (max_selection_jitter < min_jitter) { |
1204 | VERB3 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more", | 1235 | VERB4 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more", |
1205 | max_selection_jitter, min_jitter, num_survivors); | 1236 | max_selection_jitter, min_jitter, num_survivors); |
1206 | break; | 1237 | break; |
1207 | } | 1238 | } |
@@ -1209,7 +1240,7 @@ select_and_cluster(void) | |||
1209 | /* Delete survivor[max_idx] from the list | 1240 | /* Delete survivor[max_idx] from the list |
1210 | * and go around again. | 1241 | * and go around again. |
1211 | */ | 1242 | */ |
1212 | VERB5 bb_error_msg("dropping survivor %d", max_idx); | 1243 | VERB6 bb_error_msg("dropping survivor %d", max_idx); |
1213 | num_survivors--; | 1244 | num_survivors--; |
1214 | while (max_idx < num_survivors) { | 1245 | while (max_idx < num_survivors) { |
1215 | survivor[max_idx] = survivor[max_idx + 1]; | 1246 | survivor[max_idx] = survivor[max_idx + 1]; |
@@ -1251,7 +1282,7 @@ select_and_cluster(void) | |||
1251 | /* Starting from 1 is ok here */ | 1282 | /* Starting from 1 is ok here */ |
1252 | for (i = 1; i < num_survivors; i++) { | 1283 | for (i = 1; i < num_survivors; i++) { |
1253 | if (G.last_update_peer == survivor[i].p) { | 1284 | if (G.last_update_peer == survivor[i].p) { |
1254 | VERB4 bb_error_msg("keeping old synced peer"); | 1285 | VERB5 bb_error_msg("keeping old synced peer"); |
1255 | p = G.last_update_peer; | 1286 | p = G.last_update_peer; |
1256 | goto keep_old; | 1287 | goto keep_old; |
1257 | } | 1288 | } |
@@ -1259,7 +1290,7 @@ select_and_cluster(void) | |||
1259 | } | 1290 | } |
1260 | G.last_update_peer = p; | 1291 | G.last_update_peer = p; |
1261 | keep_old: | 1292 | keep_old: |
1262 | VERB3 bb_error_msg("selected peer %s filter_offset:%+f age:%f", | 1293 | VERB4 bb_error_msg("selected peer %s filter_offset:%+f age:%f", |
1263 | p->p_dotted, | 1294 | p->p_dotted, |
1264 | p->filter_offset, | 1295 | p->filter_offset, |
1265 | G.cur_time - p->lastpkt_recv_time | 1296 | G.cur_time - p->lastpkt_recv_time |
@@ -1278,7 +1309,7 @@ set_new_values(int disc_state, double offset, double recv_time) | |||
1278 | * of the last clock filter sample, which must be earlier than | 1309 | * of the last clock filter sample, which must be earlier than |
1279 | * the current time. | 1310 | * the current time. |
1280 | */ | 1311 | */ |
1281 | VERB3 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", | 1312 | VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", |
1282 | disc_state, offset, recv_time); | 1313 | disc_state, offset, recv_time); |
1283 | G.discipline_state = disc_state; | 1314 | G.discipline_state = disc_state; |
1284 | G.last_update_offset = offset; | 1315 | G.last_update_offset = offset; |
@@ -1316,8 +1347,8 @@ update_local_clock(peer_t *p) | |||
1316 | * an old sample or the same sample twice. | 1347 | * an old sample or the same sample twice. |
1317 | */ | 1348 | */ |
1318 | if (recv_time <= G.last_update_recv_time) { | 1349 | if (recv_time <= G.last_update_recv_time) { |
1319 | VERB3 bb_error_msg("same or older datapoint: %f >= %f, not using it", | 1350 | VERB3 bb_error_msg("update from %s: same or older datapoint, not using it", |
1320 | G.last_update_recv_time, recv_time); | 1351 | p->p_dotted); |
1321 | return 0; /* "leave poll interval as is" */ | 1352 | return 0; /* "leave poll interval as is" */ |
1322 | } | 1353 | } |
1323 | 1354 | ||
@@ -1333,7 +1364,7 @@ update_local_clock(peer_t *p) | |||
1333 | if (G.discipline_state == STATE_FREQ) { | 1364 | if (G.discipline_state == STATE_FREQ) { |
1334 | /* Ignore updates until the stepout threshold */ | 1365 | /* Ignore updates until the stepout threshold */ |
1335 | if (since_last_update < WATCH_THRESHOLD) { | 1366 | if (since_last_update < WATCH_THRESHOLD) { |
1336 | VERB3 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", | 1367 | VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", |
1337 | WATCH_THRESHOLD - since_last_update); | 1368 | WATCH_THRESHOLD - since_last_update); |
1338 | return 0; /* "leave poll interval as is" */ | 1369 | return 0; /* "leave poll interval as is" */ |
1339 | } | 1370 | } |
@@ -1347,10 +1378,21 @@ update_local_clock(peer_t *p) | |||
1347 | * offset exceeds the step threshold and when it does not. | 1378 | * offset exceeds the step threshold and when it does not. |
1348 | */ | 1379 | */ |
1349 | if (abs_offset > STEP_THRESHOLD) { | 1380 | if (abs_offset > STEP_THRESHOLD) { |
1381 | #if 0 | ||
1382 | double remains; | ||
1383 | |||
1384 | // This "spike state" seems to be useless, peer selection already drops | ||
1385 | // occassional "bad" datapoints. If we are here, there were _many_ | ||
1386 | // large offsets. When a few first large offsets are seen, | ||
1387 | // we end up in "no valid datapoints, no peer selected" state. | ||
1388 | // Only when enough of them are seen (which means it's not a fluke), | ||
1389 | // we end up here. Looks like _our_ clock is off. | ||
1350 | switch (G.discipline_state) { | 1390 | switch (G.discipline_state) { |
1351 | case STATE_SYNC: | 1391 | case STATE_SYNC: |
1352 | /* The first outlyer: ignore it, switch to SPIK state */ | 1392 | /* The first outlyer: ignore it, switch to SPIK state */ |
1353 | VERB3 bb_error_msg("offset:%+f - spike detected", offset); | 1393 | VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", |
1394 | p->p_dotted, offset, | ||
1395 | ""); | ||
1354 | G.discipline_state = STATE_SPIK; | 1396 | G.discipline_state = STATE_SPIK; |
1355 | return -1; /* "decrease poll interval" */ | 1397 | return -1; /* "decrease poll interval" */ |
1356 | 1398 | ||
@@ -1358,13 +1400,16 @@ update_local_clock(peer_t *p) | |||
1358 | /* Ignore succeeding outlyers until either an inlyer | 1400 | /* Ignore succeeding outlyers until either an inlyer |
1359 | * is found or the stepout threshold is exceeded. | 1401 | * is found or the stepout threshold is exceeded. |
1360 | */ | 1402 | */ |
1361 | if (since_last_update < WATCH_THRESHOLD) { | 1403 | remains = WATCH_THRESHOLD - since_last_update; |
1362 | VERB3 bb_error_msg("spike detected, datapoint ignored, %f sec remains", | 1404 | if (remains > 0) { |
1363 | WATCH_THRESHOLD - since_last_update); | 1405 | VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", |
1406 | p->p_dotted, offset, | ||
1407 | ", datapoint ignored"); | ||
1364 | return -1; /* "decrease poll interval" */ | 1408 | return -1; /* "decrease poll interval" */ |
1365 | } | 1409 | } |
1366 | /* fall through: we need to step */ | 1410 | /* fall through: we need to step */ |
1367 | } /* switch */ | 1411 | } /* switch */ |
1412 | #endif | ||
1368 | 1413 | ||
1369 | /* Step the time and clamp down the poll interval. | 1414 | /* Step the time and clamp down the poll interval. |
1370 | * | 1415 | * |
@@ -1387,7 +1432,7 @@ update_local_clock(peer_t *p) | |||
1387 | * is always suppressed, even at the longer poll | 1432 | * is always suppressed, even at the longer poll |
1388 | * intervals. | 1433 | * intervals. |
1389 | */ | 1434 | */ |
1390 | VERB3 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); | 1435 | VERB4 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); |
1391 | step_time(offset); | 1436 | step_time(offset); |
1392 | if (option_mask32 & OPT_q) { | 1437 | if (option_mask32 & OPT_q) { |
1393 | /* We were only asked to set time once. Done. */ | 1438 | /* We were only asked to set time once. Done. */ |
@@ -1412,7 +1457,7 @@ update_local_clock(peer_t *p) | |||
1412 | } else { /* abs_offset <= STEP_THRESHOLD */ | 1457 | } else { /* abs_offset <= STEP_THRESHOLD */ |
1413 | 1458 | ||
1414 | if (G.poll_exp < MINPOLL && G.initial_poll_complete) { | 1459 | if (G.poll_exp < MINPOLL && G.initial_poll_complete) { |
1415 | VERB3 bb_error_msg("small offset:%+f, disabling burst mode", offset); | 1460 | VERB4 bb_error_msg("small offset:%+f, disabling burst mode", offset); |
1416 | G.polladj_count = 0; | 1461 | G.polladj_count = 0; |
1417 | G.poll_exp = MINPOLL; | 1462 | G.poll_exp = MINPOLL; |
1418 | } | 1463 | } |
@@ -1441,7 +1486,7 @@ update_local_clock(peer_t *p) | |||
1441 | #else | 1486 | #else |
1442 | set_new_values(STATE_SYNC, offset, recv_time); | 1487 | set_new_values(STATE_SYNC, offset, recv_time); |
1443 | #endif | 1488 | #endif |
1444 | VERB3 bb_error_msg("transitioning to FREQ, datapoint ignored"); | 1489 | VERB4 bb_error_msg("transitioning to FREQ, datapoint ignored"); |
1445 | return 0; /* "leave poll interval as is" */ | 1490 | return 0; /* "leave poll interval as is" */ |
1446 | 1491 | ||
1447 | #if 0 /* this is dead code for now */ | 1492 | #if 0 /* this is dead code for now */ |
@@ -1510,7 +1555,7 @@ update_local_clock(peer_t *p) | |||
1510 | dtemp = p->filter_jitter; // SQRT(SQUARE(p->filter_jitter) + SQUARE(G.cluster_jitter)); | 1555 | dtemp = p->filter_jitter; // SQRT(SQUARE(p->filter_jitter) + SQUARE(G.cluster_jitter)); |
1511 | dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); | 1556 | dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); |
1512 | G.rootdisp = p->lastpkt_rootdisp + dtemp; | 1557 | G.rootdisp = p->lastpkt_rootdisp + dtemp; |
1513 | VERB3 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); | 1558 | VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); |
1514 | 1559 | ||
1515 | /* We are in STATE_SYNC now, but did not do adjtimex yet. | 1560 | /* We are in STATE_SYNC now, but did not do adjtimex yet. |
1516 | * (Any other state does not reach this, they all return earlier) | 1561 | * (Any other state does not reach this, they all return earlier) |
@@ -1530,13 +1575,13 @@ update_local_clock(peer_t *p) | |||
1530 | dtemp = SQUARE(dtemp); | 1575 | dtemp = SQUARE(dtemp); |
1531 | G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG); | 1576 | G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG); |
1532 | 1577 | ||
1533 | VERB3 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f", | 1578 | VERB4 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f", |
1534 | G.discipline_freq_drift, | 1579 | G.discipline_freq_drift, |
1535 | (long)(G.discipline_freq_drift * 65536e6), | 1580 | (long)(G.discipline_freq_drift * 65536e6), |
1536 | freq_drift, | 1581 | freq_drift, |
1537 | G.discipline_wander); | 1582 | G.discipline_wander); |
1538 | #endif | 1583 | #endif |
1539 | VERB3 { | 1584 | VERB4 { |
1540 | memset(&tmx, 0, sizeof(tmx)); | 1585 | memset(&tmx, 0, sizeof(tmx)); |
1541 | if (adjtimex(&tmx) < 0) | 1586 | if (adjtimex(&tmx) < 0) |
1542 | bb_perror_msg_and_die("adjtimex"); | 1587 | bb_perror_msg_and_die("adjtimex"); |
@@ -1584,7 +1629,7 @@ update_local_clock(peer_t *p) | |||
1584 | /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4. | 1629 | /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4. |
1585 | * Not sure why. Perhaps it is normal. | 1630 | * Not sure why. Perhaps it is normal. |
1586 | */ | 1631 | */ |
1587 | VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", | 1632 | VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", |
1588 | rc, tmx.freq, tmx.offset, tmx.status); | 1633 | rc, tmx.freq, tmx.offset, tmx.status); |
1589 | G.kernel_freq_drift = tmx.freq / 65536; | 1634 | G.kernel_freq_drift = tmx.freq / 65536; |
1590 | VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", | 1635 | VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", |
@@ -1606,7 +1651,7 @@ retry_interval(void) | |||
1606 | interval = RETRY_INTERVAL; | 1651 | interval = RETRY_INTERVAL; |
1607 | r = random(); | 1652 | r = random(); |
1608 | interval += r % (unsigned)(RETRY_INTERVAL / 4); | 1653 | interval += r % (unsigned)(RETRY_INTERVAL / 4); |
1609 | VERB3 bb_error_msg("chose retry interval:%u", interval); | 1654 | VERB4 bb_error_msg("chose retry interval:%u", interval); |
1610 | return interval; | 1655 | return interval; |
1611 | } | 1656 | } |
1612 | static unsigned | 1657 | static unsigned |
@@ -1619,7 +1664,7 @@ poll_interval(int exponent) | |||
1619 | interval = 1 << exponent; | 1664 | interval = 1 << exponent; |
1620 | r = random(); | 1665 | r = random(); |
1621 | interval += ((r & (interval-1)) >> 4) + ((r >> 8) & 1); /* + 1/16 of interval, max */ | 1666 | interval += ((r & (interval-1)) >> 4) + ((r >> 8) & 1); /* + 1/16 of interval, max */ |
1622 | VERB3 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); | 1667 | VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); |
1623 | return interval; | 1668 | return interval; |
1624 | } | 1669 | } |
1625 | static NOINLINE void | 1670 | static NOINLINE void |
@@ -1629,11 +1674,13 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1629 | ssize_t size; | 1674 | ssize_t size; |
1630 | msg_t msg; | 1675 | msg_t msg; |
1631 | double T1, T2, T3, T4; | 1676 | double T1, T2, T3, T4; |
1632 | double dv; | 1677 | double dv, offset; |
1633 | unsigned interval; | 1678 | unsigned interval; |
1634 | datapoint_t *datapoint; | 1679 | datapoint_t *datapoint; |
1635 | peer_t *q; | 1680 | peer_t *q; |
1636 | 1681 | ||
1682 | offset = 0; | ||
1683 | |||
1637 | /* We can recvfrom here and check from.IP, but some multihomed | 1684 | /* We can recvfrom here and check from.IP, but some multihomed |
1638 | * ntp servers reply from their *other IP*. | 1685 | * ntp servers reply from their *other IP*. |
1639 | * TODO: maybe we should check at least what we can: from.port == 123? | 1686 | * TODO: maybe we should check at least what we can: from.port == 123? |
@@ -1713,7 +1760,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1713 | T4 = G.cur_time; | 1760 | T4 = G.cur_time; |
1714 | 1761 | ||
1715 | p->lastpkt_recv_time = T4; | 1762 | p->lastpkt_recv_time = T4; |
1716 | VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); | 1763 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); |
1717 | 1764 | ||
1718 | /* The delay calculation is a special case. In cases where the | 1765 | /* The delay calculation is a special case. In cases where the |
1719 | * server and client clocks are running at different rates and | 1766 | * server and client clocks are running at different rates and |
@@ -1737,13 +1784,13 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1737 | p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0; | 1784 | p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0; |
1738 | datapoint = &p->filter_datapoint[p->datapoint_idx]; | 1785 | datapoint = &p->filter_datapoint[p->datapoint_idx]; |
1739 | datapoint->d_recv_time = T4; | 1786 | datapoint->d_recv_time = T4; |
1740 | datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2; | 1787 | datapoint->d_offset = offset = ((T2 - T1) + (T3 - T4)) / 2; |
1741 | datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec; | 1788 | datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec; |
1742 | if (!p->reachable_bits) { | 1789 | if (!p->reachable_bits) { |
1743 | /* 1st datapoint ever - replicate offset in every element */ | 1790 | /* 1st datapoint ever - replicate offset in every element */ |
1744 | int i; | 1791 | int i; |
1745 | for (i = 0; i < NUM_DATAPOINTS; i++) { | 1792 | for (i = 0; i < NUM_DATAPOINTS; i++) { |
1746 | p->filter_datapoint[i].d_offset = datapoint->d_offset; | 1793 | p->filter_datapoint[i].d_offset = offset; |
1747 | } | 1794 | } |
1748 | } | 1795 | } |
1749 | 1796 | ||
@@ -1751,7 +1798,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1751 | if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { | 1798 | if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { |
1752 | bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", | 1799 | bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", |
1753 | p->p_dotted, | 1800 | p->p_dotted, |
1754 | datapoint->d_offset, | 1801 | offset, |
1755 | p->lastpkt_delay, | 1802 | p->lastpkt_delay, |
1756 | p->lastpkt_status, | 1803 | p->lastpkt_status, |
1757 | p->lastpkt_stratum, | 1804 | p->lastpkt_stratum, |
@@ -1776,7 +1823,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1776 | * drop poll interval one step down. | 1823 | * drop poll interval one step down. |
1777 | */ | 1824 | */ |
1778 | if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { | 1825 | if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { |
1779 | VERB3 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); | 1826 | VERB4 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); |
1780 | goto poll_down; | 1827 | goto poll_down; |
1781 | } | 1828 | } |
1782 | } | 1829 | } |
@@ -1798,11 +1845,11 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1798 | G.polladj_count = 0; | 1845 | G.polladj_count = 0; |
1799 | if (G.poll_exp < MAXPOLL) { | 1846 | if (G.poll_exp < MAXPOLL) { |
1800 | G.poll_exp++; | 1847 | G.poll_exp++; |
1801 | VERB3 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", | 1848 | VERB4 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", |
1802 | G.discipline_jitter, G.poll_exp); | 1849 | G.discipline_jitter, G.poll_exp); |
1803 | } | 1850 | } |
1804 | } else { | 1851 | } else { |
1805 | VERB3 bb_error_msg("polladj: incr:%d", G.polladj_count); | 1852 | VERB4 bb_error_msg("polladj: incr:%d", G.polladj_count); |
1806 | } | 1853 | } |
1807 | } else { | 1854 | } else { |
1808 | G.polladj_count -= G.poll_exp * 2; | 1855 | G.polladj_count -= G.poll_exp * 2; |
@@ -1824,11 +1871,11 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1824 | if (pp->p_fd < 0) | 1871 | if (pp->p_fd < 0) |
1825 | pp->next_action_time -= (1 << G.poll_exp); | 1872 | pp->next_action_time -= (1 << G.poll_exp); |
1826 | } | 1873 | } |
1827 | VERB3 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", | 1874 | VERB4 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", |
1828 | G.discipline_jitter, G.poll_exp); | 1875 | G.discipline_jitter, G.poll_exp); |
1829 | } | 1876 | } |
1830 | } else { | 1877 | } else { |
1831 | VERB3 bb_error_msg("polladj: decr:%d", G.polladj_count); | 1878 | VERB4 bb_error_msg("polladj: decr:%d", G.polladj_count); |
1832 | } | 1879 | } |
1833 | } | 1880 | } |
1834 | } | 1881 | } |
@@ -1836,6 +1883,20 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1836 | /* Decide when to send new query for this peer */ | 1883 | /* Decide when to send new query for this peer */ |
1837 | pick_normal_interval: | 1884 | pick_normal_interval: |
1838 | interval = poll_interval(0); | 1885 | interval = poll_interval(0); |
1886 | if (fabs(offset) >= STEP_THRESHOLD * 8 && interval > BIGOFF_INTERVAL) { | ||
1887 | /* If we are synced, offsets are less than STEP_THRESHOLD, | ||
1888 | * or at the very least not much larger than it. | ||
1889 | * Now we see a largish one. | ||
1890 | * Either this peer is feeling bad, or packet got corrupted, | ||
1891 | * or _our_ clock is wrong now and _all_ peers will show similar | ||
1892 | * largish offsets too. | ||
1893 | * I observed this with laptop suspend stopping clock. | ||
1894 | * In any case, it makes sense to make next request soonish: | ||
1895 | * cases 1 and 2: get a better datapoint, | ||
1896 | * case 3: allows to resync faster. | ||
1897 | */ | ||
1898 | interval = BIGOFF_INTERVAL; | ||
1899 | } | ||
1839 | 1900 | ||
1840 | set_next_and_ret: | 1901 | set_next_and_ret: |
1841 | set_next(p, interval); | 1902 | set_next(p, interval); |
diff --git a/networking/ping.c b/networking/ping.c index f27e2143d..5d71fe8cc 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -168,9 +168,22 @@ create_icmp_socket(void) | |||
168 | #endif | 168 | #endif |
169 | sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */ | 169 | sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */ |
170 | if (sock < 0) { | 170 | if (sock < 0) { |
171 | if (errno == EPERM) | 171 | if (errno != EPERM) |
172 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | 172 | bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); |
173 | bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); | 173 | #if defined(__linux__) || defined(__APPLE__) |
174 | /* We don't have root privileges. Try SOCK_DGRAM instead. | ||
175 | * Linux needs net.ipv4.ping_group_range for this to work. | ||
176 | * MacOSX allows ICMP_ECHO, ICMP_TSTAMP or ICMP_MASKREQ | ||
177 | */ | ||
178 | #if ENABLE_PING6 | ||
179 | if (lsa->u.sa.sa_family == AF_INET6) | ||
180 | sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); | ||
181 | else | ||
182 | #endif | ||
183 | sock = socket(AF_INET, SOCK_DGRAM, 1); /* 1 == ICMP */ | ||
184 | if (sock < 0) | ||
185 | #endif | ||
186 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | ||
174 | } | 187 | } |
175 | 188 | ||
176 | xmove_fd(sock, pingsock); | 189 | xmove_fd(sock, pingsock); |
@@ -516,7 +529,7 @@ static void sendping6(int junk UNUSED_PARAM) | |||
516 | pkt->icmp6_id = myid; | 529 | pkt->icmp6_id = myid; |
517 | 530 | ||
518 | /*if (datalen >= 4)*/ | 531 | /*if (datalen >= 4)*/ |
519 | *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); | 532 | *(bb__aliased_uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); |
520 | 533 | ||
521 | //TODO? pkt->icmp_cksum = inet_cksum(...); | 534 | //TODO? pkt->icmp_cksum = inet_cksum(...); |
522 | 535 | ||
diff --git a/networking/pscan.c b/networking/pscan.c index 28005ad57..72ed8cdb5 100644 --- a/networking/pscan.c +++ b/networking/pscan.c | |||
@@ -157,7 +157,7 @@ int pscan_main(int argc UNUSED_PARAM, char **argv) | |||
157 | } | 157 | } |
158 | if (ENABLE_FEATURE_CLEAN_UP) free(lsap); | 158 | if (ENABLE_FEATURE_CLEAN_UP) free(lsap); |
159 | 159 | ||
160 | printf("%d closed, %d open, %d timed out (or blocked) ports\n", | 160 | printf("%u closed, %u open, %u timed out (or blocked) ports\n", |
161 | closed_ports, | 161 | closed_ports, |
162 | open_ports, | 162 | open_ports, |
163 | nports - (closed_ports + open_ports)); | 163 | nports - (closed_ports + open_ports)); |
diff --git a/networking/tc.c b/networking/tc.c index b9a4d16cc..533f7c042 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
@@ -418,9 +418,6 @@ static int print_class(const struct sockaddr_nl *who UNUSED_PARAM, | |||
418 | static int print_filter(const struct sockaddr_nl *who UNUSED_PARAM, | 418 | static int print_filter(const struct sockaddr_nl *who UNUSED_PARAM, |
419 | struct nlmsghdr *hdr, void *arg UNUSED_PARAM) | 419 | struct nlmsghdr *hdr, void *arg UNUSED_PARAM) |
420 | { | 420 | { |
421 | struct tcmsg *msg = NLMSG_DATA(hdr); | ||
422 | int len = hdr->nlmsg_len; | ||
423 | struct rtattr * tb[TCA_MAX+1]; | ||
424 | return 0; | 421 | return 0; |
425 | } | 422 | } |
426 | 423 | ||
diff --git a/networking/traceroute.c b/networking/traceroute.c index 0c18d6c0c..97a7a19e0 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -791,7 +791,9 @@ static int | |||
791 | common_traceroute_main(int op, char **argv) | 791 | common_traceroute_main(int op, char **argv) |
792 | { | 792 | { |
793 | int minpacket; | 793 | int minpacket; |
794 | #ifdef IP_TOS | ||
794 | int tos = 0; | 795 | int tos = 0; |
796 | #endif | ||
795 | int max_ttl = 30; | 797 | int max_ttl = 30; |
796 | int nprobes = 3; | 798 | int nprobes = 3; |
797 | int first_ttl = 1; | 799 | int first_ttl = 1; |
@@ -838,8 +840,10 @@ common_traceroute_main(int op, char **argv) | |||
838 | if (op & OPT_IP_CHKSUM) | 840 | if (op & OPT_IP_CHKSUM) |
839 | bb_error_msg("warning: ip checksums disabled"); | 841 | bb_error_msg("warning: ip checksums disabled"); |
840 | #endif | 842 | #endif |
843 | #ifdef IP_TOS | ||
841 | if (op & OPT_TOS) | 844 | if (op & OPT_TOS) |
842 | tos = xatou_range(tos_str, 0, 255); | 845 | tos = xatou_range(tos_str, 0, 255); |
846 | #endif | ||
843 | if (op & OPT_MAX_TTL) | 847 | if (op & OPT_MAX_TTL) |
844 | max_ttl = xatou_range(max_ttl_str, 1, 255); | 848 | max_ttl = xatou_range(max_ttl_str, 1, 255); |
845 | if (op & OPT_PORT) | 849 | if (op & OPT_PORT) |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 11b7b1f06..fe322db4f 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -62,6 +62,7 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
62 | { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ | 62 | { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ |
63 | { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ | 63 | { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ |
64 | #endif | 64 | #endif |
65 | { OPTION_STRING , 0xd1 }, /* DHCP_PXE_CONF_FILE */ | ||
65 | { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ | 66 | { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ |
66 | { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ | 67 | { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ |
67 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ | 68 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ |
@@ -128,6 +129,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
128 | "vlanid" "\0" /* DHCP_VLAN_ID */ | 129 | "vlanid" "\0" /* DHCP_VLAN_ID */ |
129 | "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ | 130 | "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ |
130 | #endif | 131 | #endif |
132 | "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */ | ||
131 | "ip6rd" "\0" /* DHCP_6RD */ | 133 | "ip6rd" "\0" /* DHCP_6RD */ |
132 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ | 134 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ |
133 | "wpad" "\0" /* DHCP_WPAD */ | 135 | "wpad" "\0" /* DHCP_WPAD */ |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 0e8e45fd2..5e70d609f 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -149,8 +149,9 @@ enum { | |||
149 | //#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ | 149 | //#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ |
150 | //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ | 150 | //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ |
151 | //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ | 151 | //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ |
152 | #define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ | 152 | //#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ |
153 | #define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ | 153 | //#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ |
154 | //#define DHCP_PXE_CONF_FILE 0xd1 /* RFC 5071 Configuration File */ | ||
154 | //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ | 155 | //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ |
155 | //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ | 156 | //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ |
156 | #define DHCP_END 0xff | 157 | #define DHCP_END 0xff |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 53d8a5e08..8dee916d9 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -667,6 +667,15 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet) | |||
667 | client_config.ifindex); | 667 | client_config.ifindex); |
668 | } | 668 | } |
669 | 669 | ||
670 | static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) | ||
671 | { | ||
672 | if (server) | ||
673 | return udhcp_send_kernel_packet(packet, | ||
674 | ciaddr, CLIENT_PORT, | ||
675 | server, SERVER_PORT); | ||
676 | return raw_bcast_from_client_config_ifindex(packet); | ||
677 | } | ||
678 | |||
670 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ | 679 | /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ |
671 | /* NOINLINE: limit stack usage in caller */ | 680 | /* NOINLINE: limit stack usage in caller */ |
672 | static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | 681 | static NOINLINE int send_discover(uint32_t xid, uint32_t requested) |
@@ -773,11 +782,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
773 | add_client_options(&packet); | 782 | add_client_options(&packet); |
774 | 783 | ||
775 | bb_info_msg("Sending renew..."); | 784 | bb_info_msg("Sending renew..."); |
776 | if (server) | 785 | return bcast_or_ucast(&packet, ciaddr, server); |
777 | return udhcp_send_kernel_packet(&packet, | ||
778 | ciaddr, CLIENT_PORT, | ||
779 | server, SERVER_PORT); | ||
780 | return raw_bcast_from_client_config_ifindex(&packet); | ||
781 | } | 786 | } |
782 | 787 | ||
783 | #if ENABLE_FEATURE_UDHCPC_ARPING | 788 | #if ENABLE_FEATURE_UDHCPC_ARPING |
@@ -826,7 +831,11 @@ static int send_release(uint32_t server, uint32_t ciaddr) | |||
826 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 831 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
827 | 832 | ||
828 | bb_info_msg("Sending release..."); | 833 | bb_info_msg("Sending release..."); |
829 | return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); | 834 | /* Note: normally we unicast here since "server" is not zero. |
835 | * However, there _are_ people who run "address-less" DHCP servers, | ||
836 | * and reportedly ISC dhcp client and Windows allow that. | ||
837 | */ | ||
838 | return bcast_or_ucast(&packet, ciaddr, server); | ||
830 | } | 839 | } |
831 | 840 | ||
832 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ | 841 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ |
@@ -1648,14 +1657,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1648 | * might work too. | 1657 | * might work too. |
1649 | * "Next server" and router are definitely wrong ones to use, though... | 1658 | * "Next server" and router are definitely wrong ones to use, though... |
1650 | */ | 1659 | */ |
1660 | /* We used to ignore pcakets without DHCP_SERVER_ID. | ||
1661 | * I've got user reports from people who run "address-less" servers. | ||
1662 | * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. | ||
1663 | * They say ISC DHCP client supports this case. | ||
1664 | */ | ||
1665 | server_addr = 0; | ||
1651 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1666 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); |
1652 | if (!temp) { | 1667 | if (!temp) { |
1653 | bb_error_msg("no server ID, ignoring packet"); | 1668 | bb_error_msg("no server ID, using 0.0.0.0"); |
1654 | continue; | 1669 | } else { |
1655 | /* still selecting - this server looks bad */ | 1670 | /* it IS unaligned sometimes, don't "optimize" */ |
1671 | move_from_unaligned32(server_addr, temp); | ||
1656 | } | 1672 | } |
1657 | /* it IS unaligned sometimes, don't "optimize" */ | ||
1658 | move_from_unaligned32(server_addr, temp); | ||
1659 | /*xid = packet.xid; - already is */ | 1673 | /*xid = packet.xid; - already is */ |
1660 | requested_ip = packet.yiaddr; | 1674 | requested_ip = packet.yiaddr; |
1661 | 1675 | ||
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 33c9585cf..148f52551 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -143,8 +143,15 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | |||
143 | * | 143 | * |
144 | * In order to work with those buggy servers, | 144 | * In order to work with those buggy servers, |
145 | * we truncate packets after end option byte. | 145 | * we truncate packets after end option byte. |
146 | * | ||
147 | * However, RFC 1542 says "The IP Total Length and UDP Length | ||
148 | * must be large enough to contain the minimal BOOTP header of 300 octets". | ||
149 | * Thus, we retain enough padding to not go below 300 BOOTP bytes. | ||
150 | * Some devices have filters which drop DHCP packets shorter than that. | ||
146 | */ | 151 | */ |
147 | padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options); | 152 | padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options); |
153 | if (padding > DHCP_SIZE - 300) | ||
154 | padding = DHCP_SIZE - 300; | ||
148 | 155 | ||
149 | packet.ip.protocol = IPPROTO_UDP; | 156 | packet.ip.protocol = IPPROTO_UDP; |
150 | packet.ip.saddr = source_nip; | 157 | packet.ip.saddr = source_nip; |
@@ -215,6 +222,8 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | |||
215 | 222 | ||
216 | udhcp_dump_packet(dhcp_pkt); | 223 | udhcp_dump_packet(dhcp_pkt); |
217 | padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); | 224 | padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); |
225 | if (padding > DHCP_SIZE - 300) | ||
226 | padding = DHCP_SIZE - 300; | ||
218 | result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); | 227 | result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding); |
219 | msg = "write"; | 228 | msg = "write"; |
220 | ret_close: | 229 | ret_close: |
diff --git a/networking/wget.c b/networking/wget.c index 5dac2b500..d6c509edc 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -72,6 +72,7 @@ struct globals { | |||
72 | const char *user_agent; /* "User-Agent" header field */ | 72 | const char *user_agent; /* "User-Agent" header field */ |
73 | #if ENABLE_FEATURE_WGET_TIMEOUT | 73 | #if ENABLE_FEATURE_WGET_TIMEOUT |
74 | unsigned timeout_seconds; | 74 | unsigned timeout_seconds; |
75 | bool connecting; | ||
75 | #endif | 76 | #endif |
76 | int output_fd; | 77 | int output_fd; |
77 | int o_flags; | 78 | int o_flags; |
@@ -87,7 +88,9 @@ struct globals { | |||
87 | #define G (*ptr_to_globals) | 88 | #define G (*ptr_to_globals) |
88 | #define INIT_G() do { \ | 89 | #define INIT_G() do { \ |
89 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 90 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
90 | IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) \ | 91 | } while (0) |
92 | #define FINI_G() do { \ | ||
93 | FREE_PTR_TO_GLOBALS(); \ | ||
91 | } while (0) | 94 | } while (0) |
92 | 95 | ||
93 | 96 | ||
@@ -195,13 +198,27 @@ static char* sanitize_string(char *s) | |||
195 | return s; | 198 | return s; |
196 | } | 199 | } |
197 | 200 | ||
201 | #if ENABLE_FEATURE_WGET_TIMEOUT | ||
202 | static void alarm_handler(int sig UNUSED_PARAM) | ||
203 | { | ||
204 | /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ | ||
205 | if (G.connecting) | ||
206 | bb_error_msg_and_die("download timed out"); | ||
207 | } | ||
208 | #endif | ||
209 | |||
198 | static FILE *open_socket(len_and_sockaddr *lsa) | 210 | static FILE *open_socket(len_and_sockaddr *lsa) |
199 | { | 211 | { |
212 | int fd; | ||
200 | FILE *fp; | 213 | FILE *fp; |
201 | 214 | ||
215 | IF_FEATURE_WGET_TIMEOUT(alarm(G.timeout_seconds); G.connecting = 1;) | ||
216 | fd = xconnect_stream(lsa); | ||
217 | IF_FEATURE_WGET_TIMEOUT(G.connecting = 0;) | ||
218 | |||
202 | /* glibc 2.4 seems to try seeking on it - ??! */ | 219 | /* glibc 2.4 seems to try seeking on it - ??! */ |
203 | /* hopefully it understands what ESPIPE means... */ | 220 | /* hopefully it understands what ESPIPE means... */ |
204 | fp = fdopen(xconnect_stream(lsa), "r+"); | 221 | fp = fdopen(fd, "r+"); |
205 | if (fp == NULL) | 222 | if (fp == NULL) |
206 | bb_perror_msg_and_die(bb_msg_memory_exhausted); | 223 | bb_perror_msg_and_die(bb_msg_memory_exhausted); |
207 | 224 | ||
@@ -209,6 +226,7 @@ static FILE *open_socket(len_and_sockaddr *lsa) | |||
209 | } | 226 | } |
210 | 227 | ||
211 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ | 228 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ |
229 | /* FIXME: does not respect FEATURE_WGET_TIMEOUT and -T N: */ | ||
212 | static char fgets_and_trim(FILE *fp) | 230 | static char fgets_and_trim(FILE *fp) |
213 | { | 231 | { |
214 | char c; | 232 | char c; |
@@ -256,15 +274,22 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
256 | free(h->allocated); | 274 | free(h->allocated); |
257 | h->allocated = url = xstrdup(src_url); | 275 | h->allocated = url = xstrdup(src_url); |
258 | 276 | ||
259 | if (strncmp(url, "http://", 7) == 0) { | 277 | if (strncmp(url, "ftp://", 6) == 0) { |
260 | h->port = bb_lookup_port("http", "tcp", 80); | ||
261 | h->host = url + 7; | ||
262 | h->is_ftp = 0; | ||
263 | } else if (strncmp(url, "ftp://", 6) == 0) { | ||
264 | h->port = bb_lookup_port("ftp", "tcp", 21); | 278 | h->port = bb_lookup_port("ftp", "tcp", 21); |
265 | h->host = url + 6; | 279 | h->host = url + 6; |
266 | h->is_ftp = 1; | 280 | h->is_ftp = 1; |
267 | } else | 281 | } else |
282 | if (strncmp(url, "http://", 7) == 0) { | ||
283 | h->host = url + 7; | ||
284 | http: | ||
285 | h->port = bb_lookup_port("http", "tcp", 80); | ||
286 | h->is_ftp = 0; | ||
287 | } else | ||
288 | if (!strstr(url, "//")) { | ||
289 | // GNU wget is user-friendly and falls back to http:// | ||
290 | h->host = url; | ||
291 | goto http; | ||
292 | } else | ||
268 | bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); | 293 | bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); |
269 | 294 | ||
270 | // FYI: | 295 | // FYI: |
@@ -944,7 +969,10 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
944 | 969 | ||
945 | INIT_G(); | 970 | INIT_G(); |
946 | 971 | ||
947 | IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) | 972 | #if ENABLE_FEATURE_WGET_TIMEOUT |
973 | G.timeout_seconds = 900; | ||
974 | signal(SIGALRM, alarm_handler); | ||
975 | #endif | ||
948 | G.proxy_flag = "on"; /* use proxies if env vars are set */ | 976 | G.proxy_flag = "on"; /* use proxies if env vars are set */ |
949 | G.user_agent = "Wget"; /* "User-Agent" header field */ | 977 | G.user_agent = "Wget"; /* "User-Agent" header field */ |
950 | 978 | ||
@@ -995,5 +1023,10 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
995 | if (G.output_fd >= 0) | 1023 | if (G.output_fd >= 0) |
996 | xclose(G.output_fd); | 1024 | xclose(G.output_fd); |
997 | 1025 | ||
1026 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_WGET_LONG_OPTIONS | ||
1027 | free(G.extra_headers); | ||
1028 | #endif | ||
1029 | FINI_G(); | ||
1030 | |||
998 | return EXIT_SUCCESS; | 1031 | return EXIT_SUCCESS; |
999 | } | 1032 | } |
diff --git a/procps/kill.c b/procps/kill.c index cd189bcd6..c5c7a8d72 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -60,7 +60,7 @@ | |||
60 | * This is needed to avoid collision with kill -9 ... syntax | 60 | * This is needed to avoid collision with kill -9 ... syntax |
61 | */ | 61 | */ |
62 | 62 | ||
63 | int kill_main(int argc, char **argv) | 63 | int kill_main(int argc UNUSED_PARAM, char **argv) |
64 | { | 64 | { |
65 | char *arg; | 65 | char *arg; |
66 | pid_t pid; | 66 | pid_t pid; |
@@ -79,10 +79,9 @@ int kill_main(int argc, char **argv) | |||
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /* Parse any options */ | 81 | /* Parse any options */ |
82 | argc--; | ||
83 | arg = *++argv; | 82 | arg = *++argv; |
84 | 83 | ||
85 | if (argc < 1 || arg[0] != '-') { | 84 | if (!arg || arg[0] != '-') { |
86 | goto do_it_now; | 85 | goto do_it_now; |
87 | } | 86 | } |
88 | 87 | ||
@@ -91,13 +90,14 @@ int kill_main(int argc, char **argv) | |||
91 | * echo "Died of SIG`kill -l $?`" | 90 | * echo "Died of SIG`kill -l $?`" |
92 | * We try to mimic what kill from coreutils-6.8 does */ | 91 | * We try to mimic what kill from coreutils-6.8 does */ |
93 | if (arg[1] == 'l' && arg[2] == '\0') { | 92 | if (arg[1] == 'l' && arg[2] == '\0') { |
94 | if (argc == 1) { | 93 | arg = *++argv; |
94 | if (!arg) { | ||
95 | /* Print the whole signal list */ | 95 | /* Print the whole signal list */ |
96 | print_signames(); | 96 | print_signames(); |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | /* -l <sig list> */ | 99 | /* -l <sig list> */ |
100 | while ((arg = *++argv)) { | 100 | do { |
101 | if (isdigit(arg[0])) { | 101 | if (isdigit(arg[0])) { |
102 | signo = bb_strtou(arg, NULL, 10); | 102 | signo = bb_strtou(arg, NULL, 10); |
103 | if (errno) { | 103 | if (errno) { |
@@ -118,8 +118,8 @@ int kill_main(int argc, char **argv) | |||
118 | } | 118 | } |
119 | printf("%d\n", signo); | 119 | printf("%d\n", signo); |
120 | } | 120 | } |
121 | } | 121 | arg = *++argv; |
122 | /* If they specified -l, we are all done */ | 122 | } while (arg); |
123 | return EXIT_SUCCESS; | 123 | return EXIT_SUCCESS; |
124 | } | 124 | } |
125 | 125 | ||
@@ -127,8 +127,7 @@ int kill_main(int argc, char **argv) | |||
127 | if (killall && arg[1] == 'q' && arg[2] == '\0') { | 127 | if (killall && arg[1] == 'q' && arg[2] == '\0') { |
128 | quiet = 1; | 128 | quiet = 1; |
129 | arg = *++argv; | 129 | arg = *++argv; |
130 | argc--; | 130 | if (!arg) |
131 | if (argc < 1) | ||
132 | bb_show_usage(); | 131 | bb_show_usage(); |
133 | if (arg[0] != '-') | 132 | if (arg[0] != '-') |
134 | goto do_it_now; | 133 | goto do_it_now; |
@@ -140,8 +139,7 @@ int kill_main(int argc, char **argv) | |||
140 | if (killall5 && arg[0] == 'o') | 139 | if (killall5 && arg[0] == 'o') |
141 | goto do_it_now; | 140 | goto do_it_now; |
142 | 141 | ||
143 | if (argc > 1 && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */ | 142 | if (argv[1] && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */ |
144 | argc--; | ||
145 | arg = *++argv; | 143 | arg = *++argv; |
146 | } /* else it must be -SIG */ | 144 | } /* else it must be -SIG */ |
147 | signo = get_signum(arg); | 145 | signo = get_signum(arg); |
@@ -150,7 +148,6 @@ int kill_main(int argc, char **argv) | |||
150 | return EXIT_FAILURE; | 148 | return EXIT_FAILURE; |
151 | } | 149 | } |
152 | arg = *++argv; | 150 | arg = *++argv; |
153 | argc--; | ||
154 | 151 | ||
155 | do_it_now: | 152 | do_it_now: |
156 | pid = getpid(); | 153 | pid = getpid(); |
@@ -158,7 +155,8 @@ int kill_main(int argc, char **argv) | |||
158 | if (killall5) { | 155 | if (killall5) { |
159 | pid_t sid; | 156 | pid_t sid; |
160 | procps_status_t* p = NULL; | 157 | procps_status_t* p = NULL; |
161 | int ret = 0; | 158 | /* compat: exitcode 2 is "no one was signaled" */ |
159 | int ret = 2; | ||
162 | 160 | ||
163 | /* Find out our session id */ | 161 | /* Find out our session id */ |
164 | sid = getsid(pid); | 162 | sid = getsid(pid); |
@@ -167,9 +165,10 @@ int kill_main(int argc, char **argv) | |||
167 | kill(-1, SIGSTOP); | 165 | kill(-1, SIGSTOP); |
168 | /* Signal all processes except those in our session */ | 166 | /* Signal all processes except those in our session */ |
169 | while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) != NULL) { | 167 | while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) != NULL) { |
170 | int i; | 168 | char **args; |
171 | 169 | ||
172 | if (p->sid == (unsigned)sid | 170 | if (p->sid == (unsigned)sid |
171 | || p->sid == 0 /* compat: kernel thread, don't signal it */ | ||
173 | || p->pid == (unsigned)pid | 172 | || p->pid == (unsigned)pid |
174 | || p->pid == 1 | 173 | || p->pid == 1 |
175 | ) { | 174 | ) { |
@@ -178,18 +177,19 @@ int kill_main(int argc, char **argv) | |||
178 | 177 | ||
179 | /* All remaining args must be -o PID options. | 178 | /* All remaining args must be -o PID options. |
180 | * Check p->pid against them. */ | 179 | * Check p->pid against them. */ |
181 | for (i = 0; i < argc; i++) { | 180 | args = argv; |
181 | while (*args) { | ||
182 | pid_t omit; | 182 | pid_t omit; |
183 | 183 | ||
184 | arg = argv[i]; | 184 | arg = *args++; |
185 | if (arg[0] != '-' || arg[1] != 'o') { | 185 | if (arg[0] != '-' || arg[1] != 'o') { |
186 | bb_error_msg("bad option '%s'", arg); | 186 | bb_error_msg("bad option '%s'", arg); |
187 | ret = 1; | 187 | ret = 1; |
188 | goto resume; | 188 | goto resume; |
189 | } | 189 | } |
190 | arg += 2; | 190 | arg += 2; |
191 | if (!arg[0] && argv[++i]) | 191 | if (!arg[0] && *args) |
192 | arg = argv[i]; | 192 | arg = *args++; |
193 | omit = bb_strtoi(arg, NULL, 10); | 193 | omit = bb_strtoi(arg, NULL, 10); |
194 | if (errno) { | 194 | if (errno) { |
195 | bb_error_msg("invalid number '%s'", arg); | 195 | bb_error_msg("invalid number '%s'", arg); |
@@ -200,6 +200,7 @@ int kill_main(int argc, char **argv) | |||
200 | goto dont_kill; | 200 | goto dont_kill; |
201 | } | 201 | } |
202 | kill(p->pid, signo); | 202 | kill(p->pid, signo); |
203 | ret = 0; | ||
203 | dont_kill: ; | 204 | dont_kill: ; |
204 | } | 205 | } |
205 | resume: | 206 | resume: |
@@ -210,14 +211,14 @@ int kill_main(int argc, char **argv) | |||
210 | } | 211 | } |
211 | 212 | ||
212 | /* Pid or name is required for kill/killall */ | 213 | /* Pid or name is required for kill/killall */ |
213 | if (argc < 1) { | 214 | if (!arg) { |
214 | bb_error_msg("you need to specify whom to kill"); | 215 | bb_error_msg("you need to specify whom to kill"); |
215 | return EXIT_FAILURE; | 216 | return EXIT_FAILURE; |
216 | } | 217 | } |
217 | 218 | ||
218 | if (killall) { | 219 | if (killall) { |
219 | /* Looks like they want to do a killall. Do that */ | 220 | /* Looks like they want to do a killall. Do that */ |
220 | while (arg) { | 221 | do { |
221 | pid_t* pidList; | 222 | pid_t* pidList; |
222 | 223 | ||
223 | pidList = find_pid_by_name(arg); | 224 | pidList = find_pid_by_name(arg); |
@@ -240,7 +241,7 @@ int kill_main(int argc, char **argv) | |||
240 | } | 241 | } |
241 | free(pidList); | 242 | free(pidList); |
242 | arg = *++argv; | 243 | arg = *++argv; |
243 | } | 244 | } while (arg); |
244 | return errors; | 245 | return errors; |
245 | } | 246 | } |
246 | 247 | ||
diff --git a/procps/nmeter.c b/procps/nmeter.c index 6a3b32743..5d5b83b8d 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c | |||
@@ -333,8 +333,7 @@ static void scale(ullong ul) | |||
333 | char buf[5]; | 333 | char buf[5]; |
334 | 334 | ||
335 | /* see http://en.wikipedia.org/wiki/Tera */ | 335 | /* see http://en.wikipedia.org/wiki/Tera */ |
336 | smart_ulltoa4(ul, buf, " kmgtpezy"); | 336 | smart_ulltoa4(ul, buf, " kmgtpezy")[0] = '\0'; |
337 | buf[4] = '\0'; | ||
338 | put(buf); | 337 | put(buf); |
339 | } | 338 | } |
340 | 339 | ||
diff --git a/procps/pgrep.c b/procps/pgrep.c index 8daf5b28a..1c7c7c48b 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c | |||
@@ -65,9 +65,9 @@ static void act(unsigned pid, char *cmd, int signo) | |||
65 | { | 65 | { |
66 | if (pgrep) { | 66 | if (pgrep) { |
67 | if (option_mask32 & (1 << OPTBIT_L)) /* OPT_LIST */ | 67 | if (option_mask32 & (1 << OPTBIT_L)) /* OPT_LIST */ |
68 | printf("%d %s\n", pid, cmd); | 68 | printf("%u %s\n", pid, cmd); |
69 | else | 69 | else |
70 | printf("%d\n", pid); | 70 | printf("%u\n", pid); |
71 | } else | 71 | } else |
72 | kill(pid, signo); | 72 | kill(pid, signo); |
73 | } | 73 | } |
diff --git a/procps/powertop.c b/procps/powertop.c index 71988a295..e3c29d1c3 100644 --- a/procps/powertop.c +++ b/procps/powertop.c | |||
@@ -627,7 +627,6 @@ static void show_timerstats(void) | |||
627 | int i, n = 0; | 627 | int i, n = 0; |
628 | char strbuf6[6]; | 628 | char strbuf6[6]; |
629 | 629 | ||
630 | strbuf6[5] = '\0'; | ||
631 | puts("\nTop causes for wakeups:"); | 630 | puts("\nTop causes for wakeups:"); |
632 | for (i = 0; i < G.lines_cnt; i++) { | 631 | for (i = 0; i < G.lines_cnt; i++) { |
633 | if ((G.lines[i].count > 0 /*|| G.lines[i].disk_count > 0*/) | 632 | if ((G.lines[i].count > 0 /*|| G.lines[i].disk_count > 0*/) |
@@ -639,7 +638,7 @@ static void show_timerstats(void) | |||
639 | /*char c = ' '; | 638 | /*char c = ' '; |
640 | if (G.lines[i].disk_count) | 639 | if (G.lines[i].disk_count) |
641 | c = 'D';*/ | 640 | c = 'D';*/ |
642 | smart_ulltoa5(G.lines[i].count, strbuf6, " KMGTPEZY"); | 641 | smart_ulltoa5(G.lines[i].count, strbuf6, " KMGTPEZY")[0] = '\0'; |
643 | printf(/*" %5.1f%% (%s)%c %s\n"*/ | 642 | printf(/*" %5.1f%% (%s)%c %s\n"*/ |
644 | " %5.1f%% (%s) %s\n", | 643 | " %5.1f%% (%s) %s\n", |
645 | G.lines[i].count * 100.0 / G.lines_cumulative_count, | 644 | G.lines[i].count * 100.0 / G.lines_cumulative_count, |
diff --git a/procps/ps.c b/procps/ps.c index 0dfda2039..32563776d 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -299,8 +299,7 @@ static void put_lu(char *buf, int size, unsigned long u) | |||
299 | char buf4[5]; | 299 | char buf4[5]; |
300 | 300 | ||
301 | /* see http://en.wikipedia.org/wiki/Tera */ | 301 | /* see http://en.wikipedia.org/wiki/Tera */ |
302 | smart_ulltoa4(u, buf4, " mgtpezy"); | 302 | smart_ulltoa4(u, buf4, " mgtpezy")[0] = '\0'; |
303 | buf4[4] = '\0'; | ||
304 | sprintf(buf, "%.*s", size, buf4); | 303 | sprintf(buf, "%.*s", size, buf4); |
305 | } | 304 | } |
306 | 305 | ||
@@ -750,8 +749,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
750 | #endif | 749 | #endif |
751 | { | 750 | { |
752 | char buf6[6]; | 751 | char buf6[6]; |
753 | smart_ulltoa5(p->vsz, buf6, " mgtpezy"); | 752 | smart_ulltoa5(p->vsz, buf6, " mgtpezy")[0] = '\0'; |
754 | buf6[5] = '\0'; | ||
755 | #if ENABLE_FEATURE_PS_LONG | 753 | #if ENABLE_FEATURE_PS_LONG |
756 | if (opts & OPT_l) { | 754 | if (opts & OPT_l) { |
757 | char bufr[6], stime_str[6]; | 755 | char bufr[6], stime_str[6]; |
@@ -762,8 +760,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
762 | time_t start = now - elapsed; | 760 | time_t start = now - elapsed; |
763 | struct tm *tm = localtime(&start); | 761 | struct tm *tm = localtime(&start); |
764 | 762 | ||
765 | smart_ulltoa5(p->rss, bufr, " mgtpezy"); | 763 | smart_ulltoa5(p->rss, bufr, " mgtpezy")[0] = '\0'; |
766 | bufr[5] = '\0'; | ||
767 | 764 | ||
768 | if (p->tty_major == 136) | 765 | if (p->tty_major == 136) |
769 | /* It should be pts/N, not ptsN, but N > 9 | 766 | /* It should be pts/N, not ptsN, but N > 9 |
diff --git a/procps/top.c b/procps/top.c index abee69806..51f1c1aed 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -677,7 +677,7 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
677 | if (s->vsz >= 100000) | 677 | if (s->vsz >= 100000) |
678 | sprintf(vsz_str_buf, "%6ldm", s->vsz/1024); | 678 | sprintf(vsz_str_buf, "%6ldm", s->vsz/1024); |
679 | else | 679 | else |
680 | sprintf(vsz_str_buf, "%7ld", s->vsz); | 680 | sprintf(vsz_str_buf, "%7lu", s->vsz); |
681 | /* PID PPID USER STAT VSZ %VSZ [%CPU] COMMAND */ | 681 | /* PID PPID USER STAT VSZ %VSZ [%CPU] COMMAND */ |
682 | col = snprintf(line_buf, scr_width, | 682 | col = snprintf(line_buf, scr_width, |
683 | "\n" "%5u%6u %-8.8s %s%s" FMT | 683 | "\n" "%5u%6u %-8.8s %s%s" FMT |
@@ -847,8 +847,7 @@ static void display_topmem_header(int scr_width, int *lines_rem_p) | |||
847 | static void ulltoa6_and_space(unsigned long long ul, char buf[6]) | 847 | static void ulltoa6_and_space(unsigned long long ul, char buf[6]) |
848 | { | 848 | { |
849 | /* see http://en.wikipedia.org/wiki/Tera */ | 849 | /* see http://en.wikipedia.org/wiki/Tera */ |
850 | smart_ulltoa5(ul, buf, " mgtpezy"); | 850 | smart_ulltoa5(ul, buf, " mgtpezy")[0] = ' '; |
851 | buf[5] = ' '; | ||
852 | } | 851 | } |
853 | 852 | ||
854 | static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) | 853 | static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) |
diff --git a/runit/chpst.c b/runit/chpst.c index ed72c8b8c..71af29f66 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -236,7 +236,6 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
236 | { | 236 | { |
237 | struct bb_uidgid_t ugid; | 237 | struct bb_uidgid_t ugid; |
238 | char *set_user = set_user; /* for compiler */ | 238 | char *set_user = set_user; /* for compiler */ |
239 | char *env_user = env_user; | ||
240 | char *env_dir = env_dir; | 239 | char *env_dir = env_dir; |
241 | char *root; | 240 | char *root; |
242 | char *nicestr; | 241 | char *nicestr; |
@@ -264,7 +263,7 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
264 | IF_CHPST("/:n:vP012"), | 263 | IF_CHPST("/:n:vP012"), |
265 | &limita, &limitc, &limitd, &limitf, &limitl, | 264 | &limita, &limitc, &limitd, &limitf, &limitl, |
266 | &limitm, &limito, &limitp, &limitr, &limits, &limitt, | 265 | &limitm, &limito, &limitp, &limitr, &limits, &limitt, |
267 | &set_user, &env_user, &env_dir | 266 | &set_user, &set_user, &env_dir |
268 | IF_CHPST(, &root, &nicestr)); | 267 | IF_CHPST(, &root, &nicestr)); |
269 | argv += optind; | 268 | argv += optind; |
270 | if (opt & OPT_m) { // -m means -asld | 269 | if (opt & OPT_m) { // -m means -asld |
@@ -292,7 +291,7 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
292 | 291 | ||
293 | // envuidgid? | 292 | // envuidgid? |
294 | if (ENABLE_ENVUIDGID && applet_name[0] == 'e' && applet_name[3] == 'u') { | 293 | if (ENABLE_ENVUIDGID && applet_name[0] == 'e' && applet_name[3] == 'u') { |
295 | env_user = *argv++; | 294 | set_user = *argv++; |
296 | opt |= OPT_U; | 295 | opt |= OPT_U; |
297 | } | 296 | } |
298 | 297 | ||
diff --git a/runit/runsv.c b/runit/runsv.c index 3e1a3c8e5..d941e897d 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -33,7 +33,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
33 | //usage:#define runsv_full_usage "\n\n" | 33 | //usage:#define runsv_full_usage "\n\n" |
34 | //usage: "Start and monitor a service and optionally an appendant log service" | 34 | //usage: "Start and monitor a service and optionally an appendant log service" |
35 | 35 | ||
36 | #include <sys/poll.h> | ||
37 | #include <sys/file.h> | 36 | #include <sys/file.h> |
38 | #include "libbb.h" | 37 | #include "libbb.h" |
39 | #include "runit_lib.h" | 38 | #include "runit_lib.h" |
diff --git a/runit/runsvdir.c b/runit/runsvdir.c index 32526cf4c..af7e75ba7 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c | |||
@@ -35,7 +35,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
35 | //usage: "\n -P Put each runsv in a new session" | 35 | //usage: "\n -P Put each runsv in a new session" |
36 | //usage: "\n -s SCRIPT Run SCRIPT <signo> after signal is processed" | 36 | //usage: "\n -s SCRIPT Run SCRIPT <signo> after signal is processed" |
37 | 37 | ||
38 | #include <sys/poll.h> | ||
39 | #include <sys/file.h> | 38 | #include <sys/file.h> |
40 | #include "libbb.h" | 39 | #include "libbb.h" |
41 | #include "runit_lib.h" | 40 | #include "runit_lib.h" |
diff --git a/runit/sv.c b/runit/sv.c index 5b01c875c..825e9d45b 100644 --- a/runit/sv.c +++ b/runit/sv.c | |||
@@ -169,7 +169,6 @@ Exit Codes | |||
169 | //usage: "pause, cont, hup, alarm, interrupt, quit, 1, 2, term, kill: send\n" | 169 | //usage: "pause, cont, hup, alarm, interrupt, quit, 1, 2, term, kill: send\n" |
170 | //usage: "STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, KILL signal to service" | 170 | //usage: "STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, KILL signal to service" |
171 | 171 | ||
172 | #include <sys/poll.h> | ||
173 | #include <sys/file.h> | 172 | #include <sys/file.h> |
174 | #include "libbb.h" | 173 | #include "libbb.h" |
175 | #include "runit_lib.h" | 174 | #include "runit_lib.h" |
diff --git a/runit/svlogd.c b/runit/svlogd.c index 8b8a6d858..c080b9acc 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c | |||
@@ -142,7 +142,6 @@ log message, you can use a pattern like this instead | |||
142 | //usage: "\n""+,-PATTERN - (de)select line for logging" | 142 | //usage: "\n""+,-PATTERN - (de)select line for logging" |
143 | //usage: "\n""E,ePATTERN - (de)select line for stderr" | 143 | //usage: "\n""E,ePATTERN - (de)select line for stderr" |
144 | 144 | ||
145 | #include <sys/poll.h> | ||
146 | #include <sys/file.h> | 145 | #include <sys/file.h> |
147 | #include "libbb.h" | 146 | #include "libbb.h" |
148 | #include "runit_lib.h" | 147 | #include "runit_lib.h" |
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 6db2a5e58..cb861b8e9 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter | |||
@@ -7,11 +7,14 @@ | |||
7 | # This software may be used and distributed according to the terms | 7 | # This software may be used and distributed according to the terms |
8 | # of the GNU General Public License, incorporated herein by reference. | 8 | # of the GNU General Public License, incorporated herein by reference. |
9 | 9 | ||
10 | import sys, os#, re | 10 | import sys, os |
11 | 11 | ||
12 | def usage(): | 12 | def usage(): |
13 | sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0]) | 13 | sys.stderr.write("usage: %s [-t] file1 file2 [-- <readelf options>]\n" |
14 | sys.exit(-1) | 14 | % sys.argv[0]) |
15 | sys.stderr.write("\t-t\tShow time spent on parsing/processing\n") | ||
16 | sys.stderr.write("\t--\tPass additional parameters to readelf\n") | ||
17 | sys.exit(1) | ||
15 | 18 | ||
16 | f1, f2 = (None, None) | 19 | f1, f2 = (None, None) |
17 | flag_timing, dashes = (False, False) | 20 | flag_timing, dashes = (False, False) |
@@ -31,6 +34,8 @@ for f in sys.argv[1:]: | |||
31 | f1 = f | 34 | f1 = f |
32 | elif f2 is None: | 35 | elif f2 is None: |
33 | f2 = f | 36 | f2 = f |
37 | else: | ||
38 | usage() | ||
34 | if flag_timing: | 39 | if flag_timing: |
35 | import time | 40 | import time |
36 | if f1 is None or f2 is None: | 41 | if f1 is None or f2 is None: |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 1651390a6..38bae809a 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -150,7 +150,7 @@ HOSTCFLAGS_zconf.tab.o := -I$(src) | |||
150 | HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl | 150 | HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl |
151 | HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK | 151 | HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK |
152 | 152 | ||
153 | HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` | 153 | HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl |
154 | HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ | 154 | HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ |
155 | -D LKC_DIRECT_LINK | 155 | -D LKC_DIRECT_LINK |
156 | 156 | ||
diff --git a/scripts/mkconfigs b/scripts/mkconfigs index db94fcc44..6a26fe1dd 100755 --- a/scripts/mkconfigs +++ b/scripts/mkconfigs | |||
@@ -65,11 +65,11 @@ static const char bbconfig_config_bz2[] ALIGN1 = {" | |||
65 | 65 | ||
66 | grep -e '^# CONFIG_' -e '^CONFIG_' "$config" \ | 66 | grep -e '^# CONFIG_' -e '^CONFIG_' "$config" \ |
67 | | bzip2 -1 | dd bs=2 skip=1 2>/dev/null \ | 67 | | bzip2 -1 | dd bs=2 skip=1 2>/dev/null \ |
68 | | od -v -t x1 \ | 68 | | od -v -b \ |
69 | | sed -e 's/^[^ ]*//' \ | 69 | | sed -e 's/^[^ ]*//' \ |
70 | -e 's/ //g' \ | 70 | -e 's/ //g' \ |
71 | -e '/^$/d' \ | 71 | -e '/^$/d' \ |
72 | -e 's/\(..\)/0x\1,/g' | 72 | -e 's/\(...\)/0\1,/g' |
73 | 73 | ||
74 | echo "};" | 74 | echo "};" |
75 | echo "#endif" | 75 | echo "#endif" |
diff --git a/scripts/randomtest b/scripts/randomtest index a102593d3..d2b26bc76 100755 --- a/scripts/randomtest +++ b/scripts/randomtest | |||
@@ -65,6 +65,7 @@ if test x"$LIBC" = x"uclibc"; then | |||
65 | | grep -v CONFIG_BUILD_LIBBUSYBOX \ | 65 | | grep -v CONFIG_BUILD_LIBBUSYBOX \ |
66 | | grep -v CONFIG_PIE \ | 66 | | grep -v CONFIG_PIE \ |
67 | \ | 67 | \ |
68 | | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ | ||
68 | | grep -v CONFIG_FEATURE_2_4_MODULES \ | 69 | | grep -v CONFIG_FEATURE_2_4_MODULES \ |
69 | >.config.new | 70 | >.config.new |
70 | mv .config.new .config | 71 | mv .config.new .config |
@@ -72,6 +73,7 @@ if test x"$LIBC" = x"uclibc"; then | |||
72 | echo '# CONFIG_BUILD_LIBBUSYBOX is not set' >>.config | 73 | echo '# CONFIG_BUILD_LIBBUSYBOX is not set' >>.config |
73 | echo '# CONFIG_PIE is not set' >>.config | 74 | echo '# CONFIG_PIE is not set' >>.config |
74 | echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config | 75 | echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config |
76 | echo '# CONFIG_FEATURE_TOUCH_NODEREF is not set' >>.config | ||
75 | fi | 77 | fi |
76 | 78 | ||
77 | # If STATIC, remove some things. | 79 | # If STATIC, remove some things. |
diff --git a/scripts/trylink b/scripts/trylink index a8b0b2e03..e47169917 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -117,7 +117,7 @@ LDLIBS=`echo "$LDLIBS" | xargs -n1 | sort | uniq | xargs` | |||
117 | # First link with all libs. If it fails, bail out | 117 | # First link with all libs. If it fails, bail out |
118 | echo "Trying libraries: $LDLIBS" | 118 | echo "Trying libraries: $LDLIBS" |
119 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" | 119 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" |
120 | l_list=`echo "$LDLIBS" | sed -e 's/ / -l/g' -e 's/^/-l/' -e 's/^-l$//'` | 120 | l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` |
121 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" | 121 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" |
122 | try $CC $CFLAGS $LDFLAGS \ | 122 | try $CC $CFLAGS $LDFLAGS \ |
123 | -o $EXE \ | 123 | -o $EXE \ |
@@ -141,7 +141,7 @@ while test "$LDLIBS"; do | |||
141 | for one in $LDLIBS; do | 141 | for one in $LDLIBS; do |
142 | without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs` | 142 | without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs` |
143 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" | 143 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" |
144 | l_list=`echo "$without_one" | sed -e 's/ / -l/g' -e 's/^/-l/' -e 's/^-l$//'` | 144 | l_list=`echo " $without_one " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` |
145 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" | 145 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" |
146 | $debug && echo "Trying -l options: '$l_list'" | 146 | $debug && echo "Trying -l options: '$l_list'" |
147 | try $CC $CFLAGS $LDFLAGS \ | 147 | try $CC $CFLAGS $LDFLAGS \ |
@@ -172,7 +172,7 @@ done | |||
172 | 172 | ||
173 | # Make the binary with final, minimal list of libs | 173 | # Make the binary with final, minimal list of libs |
174 | echo "Final link with: ${LDLIBS:-<none>}" | 174 | echo "Final link with: ${LDLIBS:-<none>}" |
175 | l_list=`echo "$LDLIBS" | sed -e 's/ / -l/g' -e 's/^/-l/' -e 's/^-l$//'` | 175 | l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` |
176 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" | 176 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" |
177 | # --verbose gives us gobs of info to stdout (e.g. linker script used) | 177 | # --verbose gives us gobs of info to stdout (e.g. linker script used) |
178 | if ! test -f busybox_ldscript; then | 178 | if ! test -f busybox_ldscript; then |
diff --git a/shell/ash.c b/shell/ash.c index 6e6fc6a71..97c9589cc 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2348,7 +2348,7 @@ unsetvar(const char *s) | |||
2348 | free(vp); | 2348 | free(vp); |
2349 | INT_ON; | 2349 | INT_ON; |
2350 | } else { | 2350 | } else { |
2351 | setvar(s, 0, 0); | 2351 | setvar2(s, 0); |
2352 | vp->flags &= ~VEXPORT; | 2352 | vp->flags &= ~VEXPORT; |
2353 | } | 2353 | } |
2354 | ok: | 2354 | ok: |
@@ -6698,7 +6698,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6698 | 6698 | ||
6699 | switch (subtype) { | 6699 | switch (subtype) { |
6700 | case VSASSIGN: | 6700 | case VSASSIGN: |
6701 | setvar(varname, startp, 0); | 6701 | setvar2(varname, startp); |
6702 | amount = startp - expdest; | 6702 | amount = startp - expdest; |
6703 | STADJUST(amount, expdest); | 6703 | STADJUST(amount, expdest); |
6704 | return startp; | 6704 | return startp; |
@@ -8960,7 +8960,7 @@ evalfor(union node *n, int flags) | |||
8960 | loopnest++; | 8960 | loopnest++; |
8961 | flags &= EV_TESTED; | 8961 | flags &= EV_TESTED; |
8962 | for (sp = arglist.list; sp; sp = sp->next) { | 8962 | for (sp = arglist.list; sp; sp = sp->next) { |
8963 | setvar(n->nfor.var, sp->text, 0); | 8963 | setvar2(n->nfor.var, sp->text); |
8964 | evaltree(n->nfor.body, flags); | 8964 | evaltree(n->nfor.body, flags); |
8965 | if (evalskip) { | 8965 | if (evalskip) { |
8966 | if (evalskip == SKIPCONT && --skipcount <= 0) { | 8966 | if (evalskip == SKIPCONT && --skipcount <= 0) { |
@@ -9955,7 +9955,7 @@ evalcommand(union node *cmd, int flags) | |||
9955 | * '_' in 'vi' command mode during line editing... | 9955 | * '_' in 'vi' command mode during line editing... |
9956 | * However I implemented that within libedit itself. | 9956 | * However I implemented that within libedit itself. |
9957 | */ | 9957 | */ |
9958 | setvar("_", lastarg, 0); | 9958 | setvar2("_", lastarg); |
9959 | } | 9959 | } |
9960 | popstackmark(&smark); | 9960 | popstackmark(&smark); |
9961 | } | 9961 | } |
@@ -12777,7 +12777,6 @@ dotcmd(int argc, char **argv) | |||
12777 | * bash returns exitcode 1 instead. | 12777 | * bash returns exitcode 1 instead. |
12778 | */ | 12778 | */ |
12779 | fullname = find_dot_file(argv[1]); | 12779 | fullname = find_dot_file(argv[1]); |
12780 | |||
12781 | argv += 2; | 12780 | argv += 2; |
12782 | argc -= 2; | 12781 | argc -= 2; |
12783 | if (argc) { /* argc > 0, argv[0] != NULL */ | 12782 | if (argc) { /* argc > 0, argv[0] != NULL */ |
@@ -13615,8 +13614,11 @@ init(void) | |||
13615 | } | 13614 | } |
13616 | 13615 | ||
13617 | if (!ENABLE_PLATFORM_MINGW32) | 13616 | if (!ENABLE_PLATFORM_MINGW32) |
13618 | setvar("PPID", utoa(getppid()), 0); | 13617 | setvar2("PPID", utoa(getppid())); |
13619 | 13618 | #if ENABLE_ASH_BASH_COMPAT | |
13619 | p = lookupvar("SHLVL"); | ||
13620 | setvar2("SHLVL", utoa(p ? atoi(p) + 1 : 1)); | ||
13621 | #endif | ||
13620 | p = lookupvar("PWD"); | 13622 | p = lookupvar("PWD"); |
13621 | if (p) { | 13623 | if (p) { |
13622 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) | 13624 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) |
@@ -13909,7 +13911,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
13909 | hp = lookupvar("HOME"); | 13911 | hp = lookupvar("HOME"); |
13910 | if (hp) { | 13912 | if (hp) { |
13911 | hp = concat_path_file(hp, ".ash_history"); | 13913 | hp = concat_path_file(hp, ".ash_history"); |
13912 | setvar("HISTFILE", hp, 0); | 13914 | setvar2("HISTFILE", hp); |
13913 | free((char*)hp); | 13915 | free((char*)hp); |
13914 | hp = lookupvar("HISTFILE"); | 13916 | hp = lookupvar("HISTFILE"); |
13915 | } | 13917 | } |
diff --git a/shell/hush.c b/shell/hush.c index 912ecf15f..927193450 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1310,7 +1310,7 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
1310 | * backgrounds (i.e. stops) or kills all members of currently running | 1310 | * backgrounds (i.e. stops) or kills all members of currently running |
1311 | * pipe. | 1311 | * pipe. |
1312 | * | 1312 | * |
1313 | * Wait builtin in interruptible by signals for which user trap is set | 1313 | * Wait builtin is interruptible by signals for which user trap is set |
1314 | * or by SIGINT in interactive shell. | 1314 | * or by SIGINT in interactive shell. |
1315 | * | 1315 | * |
1316 | * Trap handlers will execute even within trap handlers. (right?) | 1316 | * Trap handlers will execute even within trap handlers. (right?) |
@@ -1398,7 +1398,7 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
1398 | * for them - a bit like emulating kernel pending signal mask in userspace. | 1398 | * for them - a bit like emulating kernel pending signal mask in userspace. |
1399 | * We are interested in: signals which need to have special handling | 1399 | * We are interested in: signals which need to have special handling |
1400 | * as described above, and all signals which have traps set. | 1400 | * as described above, and all signals which have traps set. |
1401 | * Signals are rocorded in pending_set. | 1401 | * Signals are recorded in pending_set. |
1402 | * After each pipe execution, we extract any pending signals | 1402 | * After each pipe execution, we extract any pending signals |
1403 | * and act on them. | 1403 | * and act on them. |
1404 | * | 1404 | * |
diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 2b6415f47..bea73d932 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c | |||
@@ -49,6 +49,7 @@ struct globals { | |||
49 | memcpy(SMrup, init_sem, sizeof(init_sem)); \ | 49 | memcpy(SMrup, init_sem, sizeof(init_sem)); \ |
50 | } while (0) | 50 | } while (0) |
51 | 51 | ||
52 | #if 0 | ||
52 | static void error_exit(const char *str) NORETURN; | 53 | static void error_exit(const char *str) NORETURN; |
53 | static void error_exit(const char *str) | 54 | static void error_exit(const char *str) |
54 | { | 55 | { |
@@ -56,6 +57,10 @@ static void error_exit(const char *str) | |||
56 | shmdt(shbuf); | 57 | shmdt(shbuf); |
57 | bb_perror_msg_and_die(str); | 58 | bb_perror_msg_and_die(str); |
58 | } | 59 | } |
60 | #else | ||
61 | /* On Linux, shmdt is not mandatory on exit */ | ||
62 | # define error_exit(str) bb_perror_msg_and_die(str) | ||
63 | #endif | ||
59 | 64 | ||
60 | /* | 65 | /* |
61 | * sem_up - up()'s a semaphore. | 66 | * sem_up - up()'s a semaphore. |
@@ -68,7 +73,7 @@ static void sem_up(int semid) | |||
68 | 73 | ||
69 | static void interrupted(int sig) | 74 | static void interrupted(int sig) |
70 | { | 75 | { |
71 | shmdt(shbuf); | 76 | /* shmdt(shbuf); - on Linux, shmdt is not mandatory on exit */ |
72 | kill_myself_with_sig(sig); | 77 | kill_myself_with_sig(sig); |
73 | } | 78 | } |
74 | 79 | ||
@@ -84,12 +89,12 @@ int logread_main(int argc UNUSED_PARAM, char **argv) | |||
84 | 89 | ||
85 | log_shmid = shmget(KEY_ID, 0, 0); | 90 | log_shmid = shmget(KEY_ID, 0, 0); |
86 | if (log_shmid == -1) | 91 | if (log_shmid == -1) |
87 | bb_perror_msg_and_die("can't find syslogd buffer"); | 92 | bb_perror_msg_and_die("can't %s syslogd buffer", "find"); |
88 | 93 | ||
89 | /* Attach shared memory to our char* */ | 94 | /* Attach shared memory to our char* */ |
90 | shbuf = shmat(log_shmid, NULL, SHM_RDONLY); | 95 | shbuf = shmat(log_shmid, NULL, SHM_RDONLY); |
91 | if (shbuf == NULL) | 96 | if (shbuf == NULL) |
92 | bb_perror_msg_and_die("can't access syslogd buffer"); | 97 | bb_perror_msg_and_die("can't %s syslogd buffer", "access"); |
93 | 98 | ||
94 | log_semid = semget(KEY_ID, 0, 0); | 99 | log_semid = semget(KEY_ID, 0, 0); |
95 | if (log_semid == -1) | 100 | if (log_semid == -1) |
@@ -121,7 +126,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv) | |||
121 | shbuf_data = shbuf->data; /* pointer! */ | 126 | shbuf_data = shbuf->data; /* pointer! */ |
122 | 127 | ||
123 | if (DEBUG) | 128 | if (DEBUG) |
124 | printf("cur:%d tail:%i size:%i\n", | 129 | printf("cur:%u tail:%u size:%u\n", |
125 | cur, shbuf_tail, shbuf_size); | 130 | cur, shbuf_tail, shbuf_size); |
126 | 131 | ||
127 | if (!follow) { | 132 | if (!follow) { |
@@ -182,9 +187,10 @@ int logread_main(int argc UNUSED_PARAM, char **argv) | |||
182 | } | 187 | } |
183 | free(copy); | 188 | free(copy); |
184 | #endif | 189 | #endif |
190 | fflush_all(); | ||
185 | } while (follow); | 191 | } while (follow); |
186 | 192 | ||
187 | shmdt(shbuf); | 193 | /* shmdt(shbuf); - on Linux, shmdt is not mandatory on exit */ |
188 | 194 | ||
189 | fflush_stdout_and_exit(EXIT_SUCCESS); | 195 | fflush_stdout_and_exit(EXIT_SUCCESS); |
190 | } | 196 | } |
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 6af6072b8..132afc6a9 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -269,10 +269,31 @@ testing "awk FS assignment" "awk '{FS=\":\"; print \$1}'" \ | |||
269 | "" \ | 269 | "" \ |
270 | "a:b c:d\ne:f g:h" | 270 | "a:b c:d\ne:f g:h" |
271 | 271 | ||
272 | optional FEATURE_AWK_LIBM | ||
272 | testing "awk large integer" \ | 273 | testing "awk large integer" \ |
273 | "awk 'BEGIN{n=(2^31)-1; print n, int(n), n%1, ++n, int(n), n%1}'" \ | 274 | "awk 'BEGIN{n=(2^31)-1; print n, int(n), n%1, ++n, int(n), n%1}'" \ |
274 | "2147483647 2147483647 0 2147483648 2147483648 0\n" \ | 275 | "2147483647 2147483647 0 2147483648 2147483648 0\n" \ |
275 | "" "" | 276 | "" "" |
277 | SKIP= | ||
278 | |||
279 | testing "awk length(array)" \ | ||
280 | "awk 'BEGIN{ A[1]=2; A[\"qwe\"]=\"asd\"; print length(A)}'" \ | ||
281 | "2\n" \ | ||
282 | "" "" | ||
283 | |||
284 | testing "awk -f and ARGC" \ | ||
285 | "awk -f - input" \ | ||
286 | "re\n2\n" \ | ||
287 | "do re mi\n" \ | ||
288 | '{print $2; print ARGC;}' \ | ||
289 | |||
290 | optional FEATURE_AWK_GNU_EXTENSIONS | ||
291 | testing "awk -e and ARGC" \ | ||
292 | "awk -e '{print \$2; print ARGC;}' input" \ | ||
293 | "re\n2\n" \ | ||
294 | "do re mi\n" \ | ||
295 | "" | ||
296 | SKIP= | ||
276 | 297 | ||
277 | # testing "description" "command" "result" "infile" "stdin" | 298 | # testing "description" "command" "result" "infile" "stdin" |
278 | 299 | ||
diff --git a/testsuite/date/date-works b/testsuite/date/date-works index 901c485ec..35c24686c 100644 --- a/testsuite/date/date-works +++ b/testsuite/date/date-works | |||
@@ -31,9 +31,11 @@ dt=`busybox date -d '1999-1-2 3:4:5'` | |||
31 | dt=`echo "$dt" | cut -b1-19` | 31 | dt=`echo "$dt" | cut -b1-19` |
32 | test x"$dt" = x"Sat Jan 2 03:04:05" | 32 | test x"$dt" = x"Sat Jan 2 03:04:05" |
33 | 33 | ||
34 | dt=`busybox date -d 01231133` | 34 | # date (GNU coreutils) 8.17 doesn't accept 01231133 either: |
35 | dt=`echo "$dt" | cut -b5-19` | 35 | # date: invalid date '01231133' |
36 | test x"$dt" = x"Jan 23 11:33:00" | 36 | #dt=`busybox date -d 01231133` |
37 | #dt=`echo "$dt" | cut -b5-19` | ||
38 | #test x"$dt" = x"Jan 23 11:33:00" | ||
37 | 39 | ||
38 | dt=`busybox date -d 200001231133` | 40 | dt=`busybox date -d 200001231133` |
39 | dt=`echo "$dt" | cut -b1-19` | 41 | dt=`echo "$dt" | cut -b1-19` |
diff --git a/testsuite/date/date-works-1 b/testsuite/date/date-works-1 index cb5cea2c5..4f53939ee 100644 --- a/testsuite/date/date-works-1 +++ b/testsuite/date/date-works-1 | |||
@@ -41,9 +41,9 @@ test x"$hdt" = x"$dt" | |||
41 | # Avoiding using week day in this evaluation, as it's mostly different every year | 41 | # Avoiding using week day in this evaluation, as it's mostly different every year |
42 | # date (GNU coreutils) 6.10 reports: | 42 | # date (GNU coreutils) 6.10 reports: |
43 | # date: invalid date '01231133' | 43 | # date: invalid date '01231133' |
44 | dt=`busybox date -d 01231133 +%c` | 44 | #dt=`busybox date -d 01231133 +%c` |
45 | dt=`echo "$dt" | cut -b5-19` | 45 | #dt=`echo "$dt" | cut -b5-19` |
46 | test x"$dt" = x"Jan 23 11:33:00" | 46 | #test x"$dt" = x"Jan 23 11:33:00" |
47 | 47 | ||
48 | # date (GNU coreutils) 6.10 reports: | 48 | # date (GNU coreutils) 6.10 reports: |
49 | # date: invalid date '012311332000' | 49 | # date: invalid date '012311332000' |
diff --git a/testsuite/du/du-k-works b/testsuite/du/du-k-works index 417b0daa5..213e9ba99 100644 --- a/testsuite/du/du-k-works +++ b/testsuite/du/du-k-works | |||
@@ -4,8 +4,10 @@ dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null | |||
4 | dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null | 4 | dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null |
5 | # ext4 on images <512M gives 81kb | 5 | # ext4 on images <512M gives 81kb |
6 | # ext3 on images <512M gives 83kb | 6 | # ext3 on images <512M gives 83kb |
7 | # a bsd system reportedly gives 82kb | ||
7 | test x"`busybox du -k .`" = x"80 ." \ | 8 | test x"`busybox du -k .`" = x"80 ." \ |
8 | -o x"`busybox du -k .`" = x"81 ." \ | 9 | -o x"`busybox du -k .`" = x"81 ." \ |
10 | -o x"`busybox du -k .`" = x"82 ." \ | ||
9 | -o x"`busybox du -k .`" = x"83 ." \ | 11 | -o x"`busybox du -k .`" = x"83 ." \ |
10 | -o x"`busybox du -k .`" = x"84 ." \ | 12 | -o x"`busybox du -k .`" = x"84 ." \ |
11 | -o x"`busybox du -k .`" = x"88 ." | 13 | -o x"`busybox du -k .`" = x"88 ." |
diff --git a/testsuite/du/du-l-works b/testsuite/du/du-l-works index 426ee891b..af87345db 100644 --- a/testsuite/du/du-l-works +++ b/testsuite/du/du-l-works | |||
@@ -6,6 +6,7 @@ dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null | |||
6 | ln file1 file1.1 | 6 | ln file1 file1.1 |
7 | dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null | 7 | dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null |
8 | test x"`busybox du -l .`" = x"144 ." \ | 8 | test x"`busybox du -l .`" = x"144 ." \ |
9 | -o x"`busybox du -l .`" = x"146 ." \ | ||
9 | -o x"`busybox du -l .`" = x"148 ." \ | 10 | -o x"`busybox du -l .`" = x"148 ." \ |
10 | -o x"`busybox du -l .`" = x"152 ." \ | 11 | -o x"`busybox du -l .`" = x"152 ." \ |
11 | -o x"`busybox du -l .`" = x"156 ." | 12 | -o x"`busybox du -l .`" = x"156 ." |
diff --git a/testsuite/hostid/hostid-works b/testsuite/hostid/hostid-works index bcfd717af..8c20bdfcc 100644 --- a/testsuite/hostid/hostid-works +++ b/testsuite/hostid/hostid-works | |||
@@ -1,8 +1,6 @@ | |||
1 | h=x$(busybox hostid) | 1 | h=x$(busybox hostid) |
2 | # Is $h a sequence of hex numbers? | 2 | # Is $h a sequence of hex numbers? |
3 | x="${h//[0123456789abcdef]/x}" | 3 | case "$h" in |
4 | x="${x//xxx/x}" | 4 | x*[!0-9a-f]*) false;; |
5 | x="${x//xxx/x}" | 5 | *) true;; |
6 | x="${x//xxx/x}" | 6 | esac |
7 | x="${x//xx/x}" | ||
8 | test x"$x" = x"x" | ||
diff --git a/testsuite/md5sum.tests b/testsuite/md5sum.tests index 1068b083f..6c75b6d1c 100755 --- a/testsuite/md5sum.tests +++ b/testsuite/md5sum.tests | |||
@@ -30,13 +30,13 @@ result=`( | |||
30 | n=0 | 30 | n=0 |
31 | while test $n -le 999; do | 31 | while test $n -le 999; do |
32 | echo "$text" | head -c $n | "$sum" | 32 | echo "$text" | head -c $n | "$sum" |
33 | : $((n++)) | 33 | n=$(($n+1)) |
34 | done | "$sum" | 34 | done | "$sum" |
35 | )` | 35 | )` |
36 | 36 | ||
37 | if test x"$result" = x"$expected -"; then | 37 | if test x"$result" = x"$expected -"; then |
38 | echo "PASS: $sum" | 38 | echo "PASS: $sum" |
39 | exit 0 | 39 | exit 0 |
40 | fi | 40 | fi |
41 | 41 | ||
42 | echo "FAIL: $sum (r:$result exp:$expected)" | 42 | echo "FAIL: $sum (r:$result exp:$expected)" |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 2af1e4c97..9494ac2de 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
@@ -154,11 +154,9 @@ testing "sed selective matches insert newline" \ | |||
154 | testing "sed selective matches noinsert newline" \ | 154 | testing "sed selective matches noinsert newline" \ |
155 | "sed -ne 's/woo/bang/p' input -" "a bang\nb bang" "a woo\nb woo" \ | 155 | "sed -ne 's/woo/bang/p' input -" "a bang\nb bang" "a woo\nb woo" \ |
156 | "c no\nd no" | 156 | "c no\nd no" |
157 | test x"$SKIP_KNOWN_BUGS" = x"" && { | ||
158 | testing "sed clusternewline" \ | 157 | testing "sed clusternewline" \ |
159 | "sed -e '/one/a 111' -e '/two/i 222' -e p input -" \ | 158 | "sed -e '/one/a 111' -e '/two/i 222' -e p input -" \ |
160 | "one\none\n111\n222\ntwo\ntwo" "one" "two" | 159 | "one\none\n111\n222\ntwo\ntwo" "one" "two" |
161 | } | ||
162 | testing "sed subst+write" \ | 160 | testing "sed subst+write" \ |
163 | "sed -e 's/i/z/' -e 'woutputw' input -; $ECHO -n X; cat outputw" \ | 161 | "sed -e 's/i/z/' -e 'woutputw' input -; $ECHO -n X; cat outputw" \ |
164 | "thzngy\nagaznXthzngy\nagazn" "thingy" "again" | 162 | "thzngy\nagaznXthzngy\nagazn" "thingy" "again" |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 7927020c1..4929f4e49 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -15,6 +15,44 @@ mkdir tar.tempdir && cd tar.tempdir || exit 1 | |||
15 | 15 | ||
16 | # testing "test name" "script" "expected result" "file input" "stdin" | 16 | # testing "test name" "script" "expected result" "file input" "stdin" |
17 | 17 | ||
18 | testing "Empty file is not a tarball" '\ | ||
19 | tar xvf - 2>&1; echo $? | ||
20 | ' "\ | ||
21 | tar: short read | ||
22 | 1 | ||
23 | " \ | ||
24 | "" "" | ||
25 | SKIP= | ||
26 | |||
27 | optional FEATURE_SEAMLESS_GZ | ||
28 | # In NOMMU case, "invalid magic" message comes from gunzip child process. | ||
29 | # Otherwise, it comes from tar. | ||
30 | # Need to fix output up to avoid false positive. | ||
31 | testing "Empty file is not a tarball.tar.gz" '\ | ||
32 | { tar xvzf - 2>&1; echo $?; } | grep -Fv "invalid magic" | ||
33 | ' "\ | ||
34 | tar: short read | ||
35 | 1 | ||
36 | " \ | ||
37 | "" "" | ||
38 | SKIP= | ||
39 | |||
40 | testing "Two zeroed blocks is a ('truncated') empty tarball" '\ | ||
41 | dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $? | ||
42 | ' "\ | ||
43 | 0 | ||
44 | " \ | ||
45 | "" "" | ||
46 | SKIP= | ||
47 | |||
48 | testing "Twenty zeroed blocks is an empty tarball" '\ | ||
49 | dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $? | ||
50 | ' "\ | ||
51 | 0 | ||
52 | " \ | ||
53 | "" "" | ||
54 | SKIP= | ||
55 | |||
18 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES | 56 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES |
19 | testing "tar hardlinks and repeated files" '\ | 57 | testing "tar hardlinks and repeated files" '\ |
20 | rm -rf input_* test.tar 2>/dev/null | 58 | rm -rf input_* test.tar 2>/dev/null |
diff --git a/testsuite/testing.sh b/testsuite/testing.sh index e7e64e58b..f5b756947 100644 --- a/testsuite/testing.sh +++ b/testsuite/testing.sh | |||
@@ -56,10 +56,10 @@ optional() | |||
56 | { | 56 | { |
57 | SKIP= | 57 | SKIP= |
58 | while test "$1"; do | 58 | while test "$1"; do |
59 | if test x"${OPTIONFLAGS/*:$1:*/y}" != x"y"; then | 59 | case "${OPTIONFLAGS}" in |
60 | SKIP=1 | 60 | *:$1:*) ;; |
61 | return | 61 | *) SKIP=1; return ;; |
62 | fi | 62 | esac |
63 | shift | 63 | shift |
64 | done | 64 | done |
65 | } | 65 | } |
diff --git a/testsuite/which/which-uses-default-path b/testsuite/which/which-uses-default-path index 63ceb9f8f..349583dcc 100644 --- a/testsuite/which/which-uses-default-path +++ b/testsuite/which/which-uses-default-path | |||
@@ -1,4 +1,4 @@ | |||
1 | BUSYBOX=$(type -p busybox) | 1 | BUSYBOX=$(command -pv busybox) |
2 | SAVED_PATH=$PATH | 2 | SAVED_PATH=$PATH |
3 | unset PATH | 3 | unset PATH |
4 | $BUSYBOX which ls | 4 | $BUSYBOX which ls |
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c index b3e918fb0..6f49cec8f 100644 --- a/util-linux/fdformat.c +++ b/util-linux/fdformat.c | |||
@@ -72,7 +72,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) | |||
72 | /* original message was: "Could not determine current format type" */ | 72 | /* original message was: "Could not determine current format type" */ |
73 | xioctl(fd, FDGETPRM, ¶m); | 73 | xioctl(fd, FDGETPRM, ¶m); |
74 | 74 | ||
75 | printf("%s-sided, %d tracks, %d sec/track. Total capacity %d kB\n", | 75 | printf("%s-sided, %u tracks, %u sec/track. Total capacity %d kB\n", |
76 | (param.head == 2) ? "Double" : "Single", | 76 | (param.head == 2) ? "Double" : "Single", |
77 | param.track, param.sect, param.size >> 1); | 77 | param.track, param.sect, param.size >> 1); |
78 | 78 | ||
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index f45f68af0..5786d5f7d 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c | |||
@@ -93,9 +93,7 @@ gpt_list_table(int xtra UNUSED_PARAM) | |||
93 | int i; | 93 | int i; |
94 | char numstr6[6]; | 94 | char numstr6[6]; |
95 | 95 | ||
96 | numstr6[5] = '\0'; | 96 | smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0'; |
97 | |||
98 | smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY"); | ||
99 | printf("Disk %s: %llu sectors, %s\n", disk_device, | 97 | printf("Disk %s: %llu sectors, %s\n", disk_device, |
100 | (unsigned long long)total_number_of_sectors, | 98 | (unsigned long long)total_number_of_sectors, |
101 | numstr6); | 99 | numstr6); |
@@ -113,7 +111,7 @@ gpt_list_table(int xtra UNUSED_PARAM) | |||
113 | gpt_partition *p = gpt_part(i); | 111 | gpt_partition *p = gpt_part(i); |
114 | if (p->lba_start) { | 112 | if (p->lba_start) { |
115 | smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size, | 113 | smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size, |
116 | numstr6, " KMGTPEZY"); | 114 | numstr6, " KMGTPEZY")[0] = '\0'; |
117 | printf("%4u %15llu %15llu %11s %04x ", | 115 | printf("%4u %15llu %15llu %11s %04x ", |
118 | i + 1, | 116 | i + 1, |
119 | (unsigned long long)SWAP_LE64(p->lba_start), | 117 | (unsigned long long)SWAP_LE64(p->lba_start), |
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index c1d1b2cc3..33767a1af 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c | |||
@@ -686,7 +686,7 @@ static void get_inode_common(unsigned nr, uint16_t i_mode) | |||
686 | total++; | 686 | total++; |
687 | if (!inode_count[nr]) { | 687 | if (!inode_count[nr]) { |
688 | if (!inode_in_use(nr)) { | 688 | if (!inode_in_use(nr)) { |
689 | printf("Inode %d is marked as 'unused', but it is used " | 689 | printf("Inode %u is marked as 'unused', but it is used " |
690 | "for file '%s'\n", nr, current_name); | 690 | "for file '%s'\n", nr, current_name); |
691 | if (OPT_repair) { | 691 | if (OPT_repair) { |
692 | if (ask("Mark as 'in use'", 1)) | 692 | if (ask("Mark as 'in use'", 1)) |
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c new file mode 100644 index 000000000..675a02184 --- /dev/null +++ b/util-linux/fstrim.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * fstrim.c - discard the part (or whole) of mounted filesystem. | ||
4 | * | ||
5 | * 03 March 2012 - Malek Degachi <malek-degachi@laposte.net> | ||
6 | * Adapted for busybox from util-linux-2.12a. | ||
7 | * | ||
8 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
9 | */ | ||
10 | |||
11 | //config:config FSTRIM | ||
12 | //config: bool "fstrim" | ||
13 | //config: default y | ||
14 | //config: select PLATFORM_LINUX | ||
15 | //config: help | ||
16 | //config: Discard unused blocks on a mounted filesystem. | ||
17 | |||
18 | //applet:IF_FSTRIM(APPLET(fstrim, BB_DIR_SBIN, BB_SUID_DROP)) | ||
19 | |||
20 | //kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o | ||
21 | |||
22 | //usage:#define fstrim_trivial_usage | ||
23 | //usage: "[OPTIONS] MOUNTPOINT" | ||
24 | //usage:#define fstrim_full_usage "\n\n" | ||
25 | //usage: IF_LONG_OPTS( | ||
26 | //usage: " -o,--offset=OFFSET Offset in bytes to discard from" | ||
27 | //usage: "\n -l,--length=LEN Bytes to discard" | ||
28 | //usage: "\n -m,--minimum=MIN Minimum extent length" | ||
29 | //usage: "\n -v,--verbose Print number of discarded bytes" | ||
30 | //usage: ) | ||
31 | //usage: IF_NOT_LONG_OPTS( | ||
32 | //usage: " -o OFFSET Offset in bytes to discard from" | ||
33 | //usage: "\n -l LEN Bytes to discard" | ||
34 | //usage: "\n -m MIN Minimum extent length" | ||
35 | //usage: "\n -v, Print number of discarded bytes" | ||
36 | //usage: ) | ||
37 | |||
38 | #include "libbb.h" | ||
39 | #include <linux/fs.h> | ||
40 | |||
41 | #ifndef FITRIM | ||
42 | struct fstrim_range { | ||
43 | uint64_t start; | ||
44 | uint64_t len; | ||
45 | uint64_t minlen; | ||
46 | }; | ||
47 | #define FITRIM _IOWR('X', 121, struct fstrim_range) | ||
48 | #endif | ||
49 | |||
50 | static const struct suffix_mult fstrim_sfx[] = { | ||
51 | { "KiB", 1024 }, | ||
52 | { "kiB", 1024 }, | ||
53 | { "K", 1024 }, | ||
54 | { "k", 1024 }, | ||
55 | { "MiB", 1048576 }, | ||
56 | { "miB", 1048576 }, | ||
57 | { "M", 1048576 }, | ||
58 | { "m", 1048576 }, | ||
59 | { "GiB", 1073741824 }, | ||
60 | { "giB", 1073741824 }, | ||
61 | { "G", 1073741824 }, | ||
62 | { "g", 1073741824 }, | ||
63 | { "KB", 1000 }, | ||
64 | { "MB", 1000000 }, | ||
65 | { "GB", 1000000000 }, | ||
66 | { "", 0 } | ||
67 | }; | ||
68 | |||
69 | int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
70 | int fstrim_main(int argc UNUSED_PARAM, char **argv) | ||
71 | { | ||
72 | struct fstrim_range range; | ||
73 | char *arg_o, *arg_l, *arg_m, *mp; | ||
74 | unsigned opts; | ||
75 | int fd; | ||
76 | |||
77 | enum { | ||
78 | OPT_o = (1 << 0), | ||
79 | OPT_l = (1 << 1), | ||
80 | OPT_m = (1 << 2), | ||
81 | OPT_v = (1 << 3), | ||
82 | }; | ||
83 | |||
84 | #if ENABLE_LONG_OPTS | ||
85 | static const char getopt_longopts[] ALIGN1 = | ||
86 | "offset\0" Required_argument "o" | ||
87 | "length\0" Required_argument "l" | ||
88 | "minimum\0" Required_argument "m" | ||
89 | "verbose\0" No_argument "v" | ||
90 | ; | ||
91 | applet_long_options = getopt_longopts; | ||
92 | #endif | ||
93 | |||
94 | opt_complementary = "=1"; /* exactly one non-option arg: the mountpoint */ | ||
95 | opts = getopt32(argv, "o:l:m:v", &arg_o, &arg_l, &arg_m); | ||
96 | |||
97 | memset(&range, 0, sizeof(range)); | ||
98 | range.len = ULLONG_MAX; | ||
99 | |||
100 | if (opts & OPT_o) | ||
101 | range.start = xatoull_sfx(arg_o, fstrim_sfx); | ||
102 | if (opts & OPT_l) | ||
103 | range.len = xatoull_sfx(arg_l, fstrim_sfx); | ||
104 | if (opts & OPT_m) | ||
105 | range.minlen = xatoull_sfx(arg_m, fstrim_sfx); | ||
106 | |||
107 | mp = argv[optind]; | ||
108 | if (find_block_device(mp)) { | ||
109 | fd = xopen_nonblocking(mp); | ||
110 | xioctl(fd, FITRIM, &range); | ||
111 | if (ENABLE_FEATURE_CLEAN_UP) | ||
112 | close(fd); | ||
113 | |||
114 | if (opts & OPT_v) | ||
115 | printf("%s: %llu bytes trimmed\n", mp, (unsigned long long)range.len); | ||
116 | return EXIT_SUCCESS; | ||
117 | } | ||
118 | return EXIT_FAILURE; | ||
119 | } | ||
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c index 2668cafd4..67a25a8ef 100644 --- a/util-linux/ipcs.c +++ b/util-linux/ipcs.c | |||
@@ -166,10 +166,10 @@ static NOINLINE void do_shm(void) | |||
166 | case STATUS: | 166 | case STATUS: |
167 | printf("------ Shared Memory %s --------\n", "Status"); | 167 | printf("------ Shared Memory %s --------\n", "Status"); |
168 | printf("segments allocated %d\n" | 168 | printf("segments allocated %d\n" |
169 | "pages allocated %ld\n" | 169 | "pages allocated %lu\n" |
170 | "pages resident %ld\n" | 170 | "pages resident %lu\n" |
171 | "pages swapped %ld\n" | 171 | "pages swapped %lu\n" |
172 | "Swap performance: %ld attempts\t%ld successes\n", | 172 | "Swap performance: %lu attempts\t%lu successes\n", |
173 | shm_info.used_ids, | 173 | shm_info.used_ids, |
174 | shm_info.shm_tot, | 174 | shm_info.shm_tot, |
175 | shm_info.shm_rss, | 175 | shm_info.shm_rss, |
@@ -569,7 +569,7 @@ static void print_sem(int semid) | |||
569 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { | 569 | if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { |
570 | bb_perror_msg_and_die("semctl"); | 570 | bb_perror_msg_and_die("semctl"); |
571 | } | 571 | } |
572 | printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); | 572 | printf("%-10u %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); |
573 | } | 573 | } |
574 | bb_putchar('\n'); | 574 | bb_putchar('\n'); |
575 | } | 575 | } |
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c index 49afd1176..d65a5161c 100644 --- a/util-linux/mkfs_minix.c +++ b/util-linux/mkfs_minix.c | |||
@@ -505,7 +505,7 @@ static void get_list_blocks(char *filename) | |||
505 | 505 | ||
506 | listfile = xfopen_for_read(filename); | 506 | listfile = xfopen_for_read(filename); |
507 | while (!feof(listfile)) { | 507 | while (!feof(listfile)) { |
508 | fscanf(listfile, "%ld\n", &blockno); | 508 | fscanf(listfile, "%lu\n", &blockno); |
509 | mark_zone(blockno); | 509 | mark_zone(blockno); |
510 | G.badblocks++; | 510 | G.badblocks++; |
511 | } | 511 | } |
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c index 974fe89c4..a64540464 100644 --- a/util-linux/readprofile.c +++ b/util-linux/readprofile.c | |||
@@ -152,7 +152,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) | |||
152 | 152 | ||
153 | step = buf[0]; | 153 | step = buf[0]; |
154 | if (optInfo) { | 154 | if (optInfo) { |
155 | printf("Sampling_step: %i\n", step); | 155 | printf("Sampling_step: %u\n", step); |
156 | return EXIT_SUCCESS; | 156 | return EXIT_SUCCESS; |
157 | } | 157 | } |
158 | 158 | ||
@@ -219,10 +219,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) | |||
219 | && (fn_len = next_add-fn_add) != 0 | 219 | && (fn_len = next_add-fn_add) != 0 |
220 | ) { | 220 | ) { |
221 | if (optVerbose) | 221 | if (optVerbose) |
222 | printf("%016llx %-40s %6i %8.4f\n", fn_add, | 222 | printf("%016llx %-40s %6u %8.4f\n", fn_add, |
223 | fn_name, this, this/(double)fn_len); | 223 | fn_name, this, this/(double)fn_len); |
224 | else | 224 | else |
225 | printf("%6i %-40s %8.4f\n", | 225 | printf("%6u %-40s %8.4f\n", |
226 | this, fn_name, this/(double)fn_len); | 226 | this, fn_name, this/(double)fn_len); |
227 | if (optSub) { | 227 | if (optSub) { |
228 | unsigned long long scan; | 228 | unsigned long long scan; |
@@ -246,14 +246,14 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) | |||
246 | } | 246 | } |
247 | 247 | ||
248 | /* clock ticks, out of kernel text - probably modules */ | 248 | /* clock ticks, out of kernel text - probably modules */ |
249 | printf("%6i %s\n", buf[len/sizeof(*buf)-1], "*unknown*"); | 249 | printf("%6u %s\n", buf[len/sizeof(*buf)-1], "*unknown*"); |
250 | 250 | ||
251 | /* trailer */ | 251 | /* trailer */ |
252 | if (optVerbose) | 252 | if (optVerbose) |
253 | printf("%016x %-40s %6i %8.4f\n", | 253 | printf("%016x %-40s %6u %8.4f\n", |
254 | 0, "total", total, total/(double)(fn_add-add0)); | 254 | 0, "total", total, total/(double)(fn_add-add0)); |
255 | else | 255 | else |
256 | printf("%6i %-40s %8.4f\n", | 256 | printf("%6u %-40s %8.4f\n", |
257 | total, "total", total/(double)(fn_add-add0)); | 257 | total, "total", total/(double)(fn_add-add0)); |
258 | 258 | ||
259 | fclose(map); | 259 | fclose(map); |
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index afad4ab8f..3f223343e 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c | |||
@@ -98,10 +98,10 @@ static int do_em_all(void) | |||
98 | #if ENABLE_FEATURE_SWAPON_PRI | 98 | #if ENABLE_FEATURE_SWAPON_PRI |
99 | char *p; | 99 | char *p; |
100 | g_flags = 0; /* each swap space might have different flags */ | 100 | g_flags = 0; /* each swap space might have different flags */ |
101 | p = strstr(m->mnt_opts, "pri="); | 101 | p = hasmntopt(m, "pri"); |
102 | if (p) { | 102 | if (p) { |
103 | /* Max allowed 32767 (==SWAP_FLAG_PRIO_MASK) */ | 103 | /* Max allowed 32767 (==SWAP_FLAG_PRIO_MASK) */ |
104 | int swap_prio = MIN(bb_strtoull(p + 4 , NULL, 10), SWAP_FLAG_PRIO_MASK); | 104 | unsigned int swap_prio = MIN(bb_strtou(p + 4 , NULL, 10), SWAP_FLAG_PRIO_MASK); |
105 | /* We want to allow "NNNN,foo", thus errno == EINVAL is allowed too */ | 105 | /* We want to allow "NNNN,foo", thus errno == EINVAL is allowed too */ |
106 | if (errno != ERANGE) { | 106 | if (errno != ERANGE) { |
107 | g_flags = SWAP_FLAG_PREFER | | 107 | g_flags = SWAP_FLAG_PREFER | |
diff --git a/util-linux/volume_id/unused_msdos.c b/util-linux/volume_id/unused_msdos.c index d2fc66caa..5ebaa3eef 100644 --- a/util-linux/volume_id/unused_msdos.c +++ b/util-linux/volume_id/unused_msdos.c | |||
@@ -176,7 +176,7 @@ int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t of | |||
176 | if (id->partition_count < 4) | 176 | if (id->partition_count < 4) |
177 | id->partition_count = 4; | 177 | id->partition_count = 4; |
178 | 178 | ||
179 | p = &id->partitions[id->partition_count]; | 179 | // p = &id->partitions[id->partition_count]; |
180 | 180 | ||
181 | // if (is_raid(part[i].sys_ind)) | 181 | // if (is_raid(part[i].sys_ind)) |
182 | // volume_id_set_usage_part(p, VOLUME_ID_RAID); | 182 | // volume_id_set_usage_part(p, VOLUME_ID_RAID); |