mirror of
https://github.com/sheumann/hush.git
synced 2024-06-08 16:29:32 +00:00
Compare commits
261 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
868530ade2 | ||
|
c3b34d8b39 | ||
|
10c0e91786 | ||
|
7cf45ae10e | ||
|
e24e88697a | ||
|
ea9ebc011b | ||
|
df3ec0e2f7 | ||
|
984b0a613a | ||
|
ecf25cb5bc | ||
|
5c3e060604 | ||
|
0ad872baf3 | ||
|
94046d0495 | ||
|
bb0bf287d8 | ||
|
015db5800c | ||
|
ce824aecf2 | ||
|
ba12081a9e | ||
|
e4caf1dd9c | ||
|
b684d1b186 | ||
|
8e95068c7f | ||
|
877dedb825 | ||
|
852e8dd734 | ||
|
f2559e5c2b | ||
|
2fbc3123a2 | ||
|
e1d426fd65 | ||
|
4ab372d49a | ||
|
cbdff15bb7 | ||
|
4c8fa34417 | ||
|
3e134ebf6a | ||
|
663d1da1e6 | ||
|
7ff24bd5fb | ||
|
d7b502c059 | ||
|
93e1aaa1c7 | ||
|
f56fb5eb11 | ||
|
df70a43af2 | ||
|
9de2e5a222 | ||
|
47cfbf32fd | ||
|
e6a2f4cc5a | ||
|
5598bdf0d3 | ||
|
07bd979921 | ||
|
bca4deee83 | ||
|
0ccf52a9fb | ||
|
84ba50c32f | ||
|
2b91958dff | ||
|
e4d925b889 | ||
|
d7d4750e1e | ||
|
ee22fe8793 | ||
|
ea1b44412a | ||
|
d63d77a7f0 | ||
|
935fe68236 | ||
|
d35ba8b5ed | ||
|
e62c715b3e | ||
|
f755430d79 | ||
|
8c3f943410 | ||
|
74f58ed48c | ||
|
a0f24a06df | ||
|
f48bd92285 | ||
|
993dab7822 | ||
|
b22061718d | ||
|
6aab9928de | ||
|
b068cf2a7e | ||
|
cb92640998 | ||
|
46b494635e | ||
|
bc14f4d13d | ||
|
056e1f558c | ||
|
1cf68e3033 | ||
|
a93e4fd376 | ||
|
8b0f459af7 | ||
|
b14374a5ba | ||
|
8220399173 | ||
|
c87e81f944 | ||
|
dd02a05e08 | ||
|
9f2f96edfa | ||
|
80c934a251 | ||
|
c4199f22d0 | ||
|
29b33b63d4 | ||
|
52977a7d60 | ||
|
a27dc33f97 | ||
|
f75a96d74c | ||
|
16efe19128 | ||
|
8f2e99c813 | ||
|
80f0f1d712 | ||
|
2a17fbe88a | ||
|
32c08acba3 | ||
|
8ac6effb02 | ||
|
c418f48d8d | ||
|
3b757f0798 | ||
|
cde1199e01 | ||
|
066e76befe | ||
|
76b680c7a8 | ||
|
610c4c385b | ||
|
9844d7e830 | ||
|
20dd499341 | ||
|
31c984dd69 | ||
|
2fb63292f7 | ||
|
73dfdda92e | ||
|
b9b7aa1910 | ||
|
787972f60b | ||
|
3e3bfb896e | ||
|
6701e91d84 | ||
|
0d1b71e8e6 | ||
|
41b1e2c392 | ||
|
a63e2a8cb2 | ||
|
8a26fda98c | ||
|
99c71c9e80 | ||
|
e4de8c6316 | ||
|
fd5a2b7b04 | ||
|
23961b2fd3 | ||
|
dbb58a3879 | ||
|
1b7c17391d | ||
|
d474ffc682 | ||
|
d2b820b540 | ||
|
ea351b9742 | ||
|
7849ccb61c | ||
|
86d9f60f3a | ||
|
aee7cd82be | ||
|
c8641962e4 | ||
|
f37f28199f | ||
|
4c48a64747 | ||
|
35e063e1b9 | ||
|
abe8f7515a | ||
|
ea2b71be66 | ||
|
e5aba88712 | ||
|
352f79acbd | ||
|
5bec08cebd | ||
|
5fa9fefddc | ||
|
03718bb274 | ||
|
3a5cc98902 | ||
|
43e56639c6 | ||
|
8efcc9589b | ||
|
29eae728e9 | ||
|
383201e725 | ||
|
fc47fcefb6 | ||
|
f2c043acfc | ||
|
c30a5b1373 | ||
|
40eea690c7 | ||
|
4a79224cfc | ||
|
2a4bba3ce2 | ||
|
eb5091070f | ||
|
c7e47cf627 | ||
|
ccf7f0e4d3 | ||
|
6a70db85cf | ||
|
e111a16404 | ||
|
bae8f98633 | ||
|
76915bf738 | ||
|
dbf5a6da6a | ||
|
c2a2625bcb | ||
|
911d265faf | ||
|
ce4bc1ed04 | ||
|
6c634f7968 | ||
|
2c0d3f5fd0 | ||
|
b505251242 | ||
|
6df961257d | ||
|
e0942acb9e | ||
|
5f11ec3f6a | ||
|
77e2bde6a5 | ||
|
196e400441 | ||
|
48dc80bbba | ||
|
34adecc2b0 | ||
|
95ebcf79ff | ||
|
bc9bee01f3 | ||
|
85405c80a2 | ||
|
2cf4591413 | ||
|
5ed6989d80 | ||
|
74bb9d5e63 | ||
|
1fe75b8ef1 | ||
|
1cde5f79d4 | ||
|
fc8eb056ea | ||
|
99f025a499 | ||
|
1062391365 | ||
|
6bd3fff51a | ||
|
95650a86d1 | ||
|
8c55dc79a7 | ||
|
e939856c87 | ||
|
ace833028f | ||
|
fe0dc34746 | ||
|
f23264b35f | ||
|
ae57af6e78 | ||
|
112889d706 | ||
|
c0e007663d | ||
|
6bd2fabc52 | ||
|
713f07d906 | ||
|
7b14ede049 | ||
|
ef2386b80a | ||
|
3f221113a5 | ||
|
e2f32c02b1 | ||
|
383b885ff7 | ||
|
ab80e01cd9 | ||
|
9121510dc6 | ||
|
4c8576fea1 | ||
|
4840325351 | ||
|
82c2fad26c | ||
|
cddc98eab7 | ||
|
fbe50cf6bc | ||
|
1de25a6e87 | ||
|
d683c5c2f1 | ||
|
028524317d | ||
|
db700330d8 | ||
|
0269789537 | ||
|
8814431aca | ||
|
6d777b75ed | ||
|
f98705a00c | ||
|
d320a1e7a5 | ||
|
334e12ac6a | ||
|
49d51598ac | ||
|
bf1866c183 | ||
|
1a1cfedbef | ||
|
4f8ecf273c | ||
|
d32a1a4054 | ||
|
9a51217668 | ||
|
941e7a4919 | ||
|
cd13974b20 | ||
|
2e9a0662bc | ||
|
049b007865 | ||
|
00da72bee0 | ||
|
59f8475924 | ||
|
d3d6534b2a | ||
|
641caaec3d | ||
|
a960748748 | ||
|
accd9eeb71 | ||
|
537389cedd | ||
|
f167e4503d | ||
|
62ae323df0 | ||
|
6c563e370d | ||
|
c47917865d | ||
|
92e1b0826d | ||
|
edcd5dcc9b | ||
|
58d0e20ad0 | ||
|
5134010d88 | ||
|
76efb3ed33 | ||
|
f2ccefb946 | ||
|
0506e292b5 | ||
|
d1ed3e68b8 | ||
|
fd19faf705 | ||
|
2e86a5c98d | ||
|
3d0805e9e7 | ||
|
526d85831e | ||
|
f3d58a29be | ||
|
c4fb8c6ad5 | ||
|
36647abcc3 | ||
|
95dee81a46 | ||
|
28826ac8c0 | ||
|
854bb6879d | ||
|
0863e1a576 | ||
|
000eda41c0 | ||
|
d34f300db6 | ||
|
2735bc00e3 | ||
|
93dd9fd90a | ||
|
5251135bc1 | ||
|
4ad702c0a7 | ||
|
926d801fa5 | ||
|
0f296a3a56 | ||
|
69934701fd | ||
|
7b85ec30b5 | ||
|
4d0c1ea478 | ||
|
ab3964db4e | ||
|
f7ad927c20 | ||
|
bf74fb4497 | ||
|
6390a3a4e5 | ||
|
450a367a11 | ||
|
b5dabd9078 | ||
|
966423d403 |
22
Config.in
22
Config.in
|
@ -116,9 +116,21 @@ config FEATURE_COMPRESS_USAGE
|
|||
and have very little memory, this might not be a win. Otherwise,
|
||||
you probably want this.
|
||||
|
||||
config BUSYBOX
|
||||
bool "Include busybox applet"
|
||||
default y
|
||||
help
|
||||
The busybox applet provides general help regarding busybox and
|
||||
allows the included applets to be listed. It's also required
|
||||
if applet links are to be installed at runtime.
|
||||
|
||||
If you can live without these features disabling this will save
|
||||
some space.
|
||||
|
||||
config FEATURE_INSTALLER
|
||||
bool "Support --install [-s] to install applet links at runtime"
|
||||
default y
|
||||
depends on BUSYBOX
|
||||
help
|
||||
Enable 'busybox --install [-s]' support. This will allow you to use
|
||||
busybox at runtime to create hard links or symlinks for all the
|
||||
|
@ -688,6 +700,16 @@ config DEBUG_PESSIMIZE
|
|||
in a much bigger executable that more closely matches the source
|
||||
code.
|
||||
|
||||
config DEBUG_SANITIZE
|
||||
bool "Enable runtime sanitizers (ASAN/LSAN/USAN/etc...)"
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to enable runtime sanitizers. These help
|
||||
catch bad memory accesses (e.g. buffer overflows), but will make
|
||||
the executable larger and slow down runtime a bit.
|
||||
|
||||
If you aren't developing/testing busybox, say N here.
|
||||
|
||||
config UNIT_TEST
|
||||
bool "Build unit tests"
|
||||
default n
|
||||
|
|
11
Makefile
11
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 1
|
||||
PATCHLEVEL = 24
|
||||
SUBLEVEL = 0
|
||||
PATCHLEVEL = 25
|
||||
SUBLEVEL = 1
|
||||
EXTRAVERSION =
|
||||
NAME = Unnamed
|
||||
|
||||
|
@ -610,7 +610,8 @@ quiet_cmd_busybox__ ?= LINK $@
|
|||
"$(LDFLAGS) $(EXTRA_LDFLAGS)" \
|
||||
"$(core-y)" \
|
||||
"$(libs-y)" \
|
||||
"$(LDLIBS)"
|
||||
"$(LDLIBS)" \
|
||||
&& $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h
|
||||
|
||||
# Generate System.map
|
||||
quiet_cmd_sysmap = SYSMAP
|
||||
|
@ -844,12 +845,15 @@ export CPPFLAGS_busybox.lds += -P -C -U$(ARCH)
|
|||
# Split autoconf.h into include/linux/config/*
|
||||
quiet_cmd_gen_bbconfigopts = GEN include/bbconfigopts.h
|
||||
cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h include/bbconfigopts_bz2.h
|
||||
quiet_cmd_gen_common_bufsiz = GEN include/common_bufsiz.h
|
||||
cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h
|
||||
quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/*
|
||||
cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config
|
||||
#bbox# piggybacked generation of few .h files
|
||||
include/config/MARKER: scripts/basic/split-include include/autoconf.h
|
||||
$(call cmd,split_autoconf)
|
||||
$(call cmd,gen_bbconfigopts)
|
||||
$(call cmd,gen_common_bufsiz)
|
||||
@touch $@
|
||||
|
||||
# Generate some files
|
||||
|
@ -965,6 +969,7 @@ CLEAN_FILES += busybox busybox_unstripped* busybox.links \
|
|||
MRPROPER_DIRS += include/config include2
|
||||
MRPROPER_FILES += .config .config.old include/asm .version .old_version \
|
||||
include/NUM_APPLETS.h \
|
||||
include/common_bufsiz.h \
|
||||
include/autoconf.h \
|
||||
include/bbconfigopts.h \
|
||||
include/bbconfigopts_bz2.h \
|
||||
|
|
|
@ -75,6 +75,11 @@ else
|
|||
CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,))
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CONFIG_DEBUG_SANITIZE),y)
|
||||
CFLAGS += $(call cc-option,-fsanitize=address,)
|
||||
CFLAGS += $(call cc-option,-fsanitize=leak,)
|
||||
CFLAGS += $(call cc-option,-fsanitize=undefined,)
|
||||
endif
|
||||
|
||||
# If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)...
|
||||
ARCH_FPIC ?= -fpic
|
||||
|
|
2
TODO
2
TODO
|
@ -258,5 +258,3 @@ vdprintf() -> similar sized functionality
|
|||
|
||||
* more support for advanced linux 2.6.x features, see: iotop
|
||||
most likely there is more
|
||||
|
||||
* even more support for statistics: mpstat, iostat, powertop....
|
||||
|
|
|
@ -41,8 +41,6 @@ struct bb_applet {
|
|||
|
||||
enum { NUM_APPLETS = ARRAY_SIZE(applets) };
|
||||
|
||||
static int offset[NUM_APPLETS];
|
||||
|
||||
static int cmp_name(const void *a, const void *b)
|
||||
{
|
||||
const struct bb_applet *aa = a;
|
||||
|
@ -62,24 +60,30 @@ static int str_isalnum_(const char *s)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int ofs;
|
||||
// unsigned MAX_APPLET_NAME_LEN = 1;
|
||||
int i, j;
|
||||
|
||||
// In find_applet_by_name(), before linear search, narrow it down
|
||||
// by looking at N "equidistant" names. With ~350 applets:
|
||||
// KNOWN_APPNAME_OFFSETS cycles
|
||||
// 0 9057
|
||||
// 2 4604 + ~100 bytes of code
|
||||
// 4 2407 + 4 bytes
|
||||
// 8 1342 + 8 bytes
|
||||
// 16 908 + 16 bytes
|
||||
// 32 884 + 32 bytes
|
||||
// With 8, int16_t applet_nameofs[] table has 7 elements.
|
||||
int KNOWN_APPNAME_OFFSETS = 8;
|
||||
// With 128 applets we do two linear searches, with 1..7 strcmp's in the first one
|
||||
// and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's.
|
||||
if (NUM_APPLETS < 128)
|
||||
KNOWN_APPNAME_OFFSETS = 4;
|
||||
if (NUM_APPLETS < 32)
|
||||
KNOWN_APPNAME_OFFSETS = 0;
|
||||
|
||||
qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name);
|
||||
|
||||
ofs = 0;
|
||||
for (i = 0; i < NUM_APPLETS; i++) {
|
||||
offset[i] = ofs;
|
||||
ofs += strlen(applets[i].name) + 1;
|
||||
}
|
||||
/* We reuse 4 high-order bits of offset array for other purposes,
|
||||
* so if they are indeed needed, refuse to proceed */
|
||||
if (ofs > 0xfff)
|
||||
return 1;
|
||||
if (!argv[1])
|
||||
return 1;
|
||||
|
||||
i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
||||
if (i < 0)
|
||||
return 1;
|
||||
|
@ -94,7 +98,27 @@ int main(int argc, char **argv)
|
|||
printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name);
|
||||
printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS);
|
||||
if (KNOWN_APPNAME_OFFSETS > 0) {
|
||||
int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS];
|
||||
for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++)
|
||||
index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS;
|
||||
ofs = 0;
|
||||
for (i = 0; i < NUM_APPLETS; i++) {
|
||||
for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++)
|
||||
if (i == index[j])
|
||||
offset[j] = ofs;
|
||||
ofs += strlen(applets[i].name) + 1;
|
||||
}
|
||||
/* If the list of names is too long refuse to proceed */
|
||||
if (ofs > 0xffff)
|
||||
return 1;
|
||||
printf("const uint16_t applet_nameofs[] ALIGN2 = {\n");
|
||||
for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++)
|
||||
printf("%d,\n", offset[i]);
|
||||
printf("};\n\n");
|
||||
}
|
||||
|
||||
//printf("#ifndef SKIP_definitions\n");
|
||||
printf("const char applet_names[] ALIGN1 = \"\"\n");
|
||||
|
@ -119,20 +143,39 @@ int main(int argc, char **argv)
|
|||
printf("};\n");
|
||||
printf("#endif\n\n");
|
||||
|
||||
printf("const uint16_t applet_nameofs[] ALIGN2 = {\n");
|
||||
for (i = 0; i < NUM_APPLETS; i++) {
|
||||
printf("0x%04x,\n",
|
||||
offset[i]
|
||||
#if ENABLE_FEATURE_PREFER_APPLETS
|
||||
+ (applets[i].nofork << 12)
|
||||
+ (applets[i].noexec << 13)
|
||||
#endif
|
||||
#if ENABLE_FEATURE_SUID
|
||||
+ (applets[i].need_suid << 14) /* 2 bits */
|
||||
#endif
|
||||
);
|
||||
printf("const uint8_t applet_flags[] ALIGN1 = {\n");
|
||||
i = 0;
|
||||
while (i < NUM_APPLETS) {
|
||||
int v = applets[i].nofork + (applets[i].noexec << 1);
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= (applets[i].nofork + (applets[i].noexec << 1)) << 2;
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= (applets[i].nofork + (applets[i].noexec << 1)) << 4;
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= (applets[i].nofork + (applets[i].noexec << 1)) << 6;
|
||||
printf("0x%02x,\n", v);
|
||||
i++;
|
||||
}
|
||||
printf("};\n\n");
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_SUID
|
||||
printf("const uint8_t applet_suid[] ALIGN1 = {\n");
|
||||
i = 0;
|
||||
while (i < NUM_APPLETS) {
|
||||
int v = applets[i].need_suid; /* 2 bits */
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= applets[i].need_suid << 2;
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= applets[i].need_suid << 4;
|
||||
if (++i < NUM_APPLETS)
|
||||
v |= applets[i].need_suid << 6;
|
||||
printf("0x%02x,\n", v);
|
||||
i++;
|
||||
}
|
||||
printf("};\n\n");
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_INSTALLER
|
||||
printf("const uint8_t applet_install_loc[] ALIGN1 = {\n");
|
||||
|
|
|
@ -31,7 +31,7 @@ config FEATURE_SEAMLESS_GZ
|
|||
|
||||
config FEATURE_SEAMLESS_Z
|
||||
bool "tar, rpm, modprobe etc understand .Z data"
|
||||
default n
|
||||
default n # it is ancient
|
||||
help
|
||||
Make tar, rpm, modprobe etc understand .Z data.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# Licensed under GPLv2, see file LICENSE in this source tree.
|
||||
|
||||
libs-y += libarchive/
|
||||
libs-y += libarchive/
|
||||
|
||||
lib-y:=
|
||||
|
||||
|
|
|
@ -22,23 +22,13 @@
|
|||
//config: default n # needs to be improved to be able to replace binutils ar
|
||||
//config: help
|
||||
//config: ar is an archival utility program used to create, modify, and
|
||||
//config: extract contents from archives. An archive is a single file holding
|
||||
//config: a collection of other files in a structure that makes it possible to
|
||||
//config: retrieve the original individual files (called archive members).
|
||||
//config: The original files' contents, mode (permissions), timestamp, owner,
|
||||
//config: and group are preserved in the archive, and can be restored on
|
||||
//config: extraction.
|
||||
//config: extract contents from archives. In practice, it is used exclusively
|
||||
//config: for object module archives used by compilers.
|
||||
//config:
|
||||
//config: The stored filename is limited to 15 characters. (for more information
|
||||
//config: see long filename support).
|
||||
//config: ar has 60 bytes of overheads for every stored file.
|
||||
//config:
|
||||
//config: This implementation of ar can extract archives, it cannot create or
|
||||
//config: modify them.
|
||||
//config: On an x86 system, the ar applet adds about 1K.
|
||||
//config:
|
||||
//config: Unless you have a specific application which requires ar, you should
|
||||
//config: probably say N here.
|
||||
//config: probably say N here: most compilers come with their own ar utility.
|
||||
//config:
|
||||
//config:config FEATURE_AR_LONG_FILENAMES
|
||||
//config: bool "Support for long filenames (not needed for debs)"
|
||||
|
|
|
@ -121,7 +121,7 @@ int FAST_FUNC bbunpack(char **argv,
|
|||
|
||||
if (!(option_mask32 & SEAMLESS_MAGIC)) {
|
||||
init_transformer_state(&xstate);
|
||||
xstate.check_signature = 1;
|
||||
xstate.signature_skipped = 0;
|
||||
/*xstate.src_fd = STDIN_FILENO; - already is */
|
||||
xstate.dst_fd = STDOUT_FILENO;
|
||||
status = unpacker(&xstate);
|
||||
|
@ -220,7 +220,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
|
|||
|
||||
//config:config UNCOMPRESS
|
||||
//config: bool "uncompress"
|
||||
//config: default n
|
||||
//config: default n # ancient
|
||||
//config: help
|
||||
//config: uncompress is used to decompress archives created by compress.
|
||||
//config: Not much used anymore, replaced by gzip/gunzip.
|
||||
|
@ -290,6 +290,13 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv)
|
|||
//config: gunzip is used to decompress archives created by gzip.
|
||||
//config: You can use the `-t' option to test the integrity of
|
||||
//config: an archive, without decompressing it.
|
||||
//config:
|
||||
//config:config FEATURE_GUNZIP_LONG_OPTIONS
|
||||
//config: bool "Enable long options"
|
||||
//config: default y
|
||||
//config: depends on GUNZIP && LONG_OPTS
|
||||
//config: help
|
||||
//config: Enable use of long options.
|
||||
|
||||
//applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP))
|
||||
//applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat))
|
||||
|
@ -321,6 +328,17 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN
|
|||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
|
||||
static const char gunzip_longopts[] ALIGN1 =
|
||||
"stdout\0" No_argument "c"
|
||||
"to-stdout\0" No_argument "c"
|
||||
"force\0" No_argument "f"
|
||||
"test\0" No_argument "t"
|
||||
"no-name\0" No_argument "n"
|
||||
;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Linux kernel build uses gzip -d -n. We accept and ignore it.
|
||||
* Man page says:
|
||||
|
@ -337,6 +355,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN
|
|||
int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int gunzip_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
|
||||
applet_long_options = gunzip_longopts;
|
||||
#endif
|
||||
getopt32(argv, "cfvqdtn");
|
||||
argv += optind;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Only supports new ASCII and CRC formats
|
||||
*/
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "bb_archive.h"
|
||||
|
||||
//config:config CPIO
|
||||
|
@ -46,7 +47,7 @@
|
|||
//kbuild:lib-$(CONFIG_CPIO) += cpio.o
|
||||
|
||||
//usage:#define cpio_trivial_usage
|
||||
//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]")
|
||||
//usage: "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]")
|
||||
//usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
|
||||
//usage: " [EXTR_FILE]..."
|
||||
//usage:#define cpio_full_usage "\n\n"
|
||||
|
@ -71,6 +72,7 @@
|
|||
//usage: "\n -v Verbose"
|
||||
//usage: "\n -u Overwrite"
|
||||
//usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file"
|
||||
//usage: "\n -R USER[:GRP] Set owner of created files"
|
||||
//usage: IF_FEATURE_CPIO_O(
|
||||
//usage: "\n -H newc Archive format"
|
||||
//usage: )
|
||||
|
@ -130,7 +132,7 @@
|
|||
-I FILE File to use instead of standard input
|
||||
-L, --dereference Dereference symbolic links (copy the files
|
||||
that they point to instead of copying the links)
|
||||
-R, --owner=[USER][:.][GROUP] Set owner of created files
|
||||
-R, --owner=[USER][:.][GRP] Set owner of created files
|
||||
|
||||
Options valid in --extract and --pass-through modes:
|
||||
-d, --make-directories Create leading directories where needed
|
||||
|
@ -150,7 +152,8 @@ enum {
|
|||
OPT_PRESERVE_MTIME = (1 << 6),
|
||||
OPT_DEREF = (1 << 7),
|
||||
OPT_FILE = (1 << 8),
|
||||
OPTBIT_FILE = 8,
|
||||
OPT_OWNER = (1 << 9),
|
||||
OPTBIT_OWNER = 9,
|
||||
IF_FEATURE_CPIO_O(OPTBIT_CREATE ,)
|
||||
IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,)
|
||||
IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,)
|
||||
|
@ -163,7 +166,18 @@ enum {
|
|||
OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0,
|
||||
};
|
||||
|
||||
#define OPTION_STR "it0uvdmLF:"
|
||||
#define OPTION_STR "it0uvdmLF:R:"
|
||||
|
||||
struct globals {
|
||||
struct bb_uidgid_t owner_ugid;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
void BUG_cpio_globals_too_big(void);
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
G.owner_ugid.uid = -1L; \
|
||||
G.owner_ugid.gid = -1L; \
|
||||
} while (0)
|
||||
|
||||
#if ENABLE_FEATURE_CPIO_O
|
||||
static off_t cpio_pad4(off_t size)
|
||||
|
@ -181,7 +195,6 @@ static off_t cpio_pad4(off_t size)
|
|||
* It's ok to exit instead of return. */
|
||||
static NOINLINE int cpio_o(void)
|
||||
{
|
||||
static const char trailer[] ALIGN1 = "TRAILER!!!";
|
||||
struct name_s {
|
||||
struct name_s *next;
|
||||
char name[1];
|
||||
|
@ -223,6 +236,11 @@ static NOINLINE int cpio_o(void)
|
|||
bb_simple_perror_msg_and_die(name);
|
||||
}
|
||||
|
||||
if (G.owner_ugid.uid != (uid_t)-1L)
|
||||
st.st_uid = G.owner_ugid.uid;
|
||||
if (G.owner_ugid.gid != (gid_t)-1L)
|
||||
st.st_gid = G.owner_ugid.gid;
|
||||
|
||||
if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode)))
|
||||
st.st_size = 0; /* paranoia */
|
||||
|
||||
|
@ -275,7 +293,7 @@ static NOINLINE int cpio_o(void)
|
|||
} else {
|
||||
/* If no (more) hardlinks to output,
|
||||
* output "trailer" entry */
|
||||
name = trailer;
|
||||
name = cpio_TRAILER;
|
||||
/* st.st_size == 0 is a must, but for uniformity
|
||||
* in the output, we zero out everything */
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
@ -323,7 +341,7 @@ static NOINLINE int cpio_o(void)
|
|||
}
|
||||
|
||||
if (!line) {
|
||||
if (name != trailer)
|
||||
if (name != cpio_TRAILER)
|
||||
goto next_link;
|
||||
/* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -339,6 +357,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
|
|||
{
|
||||
archive_handle_t *archive_handle;
|
||||
char *cpio_filename;
|
||||
char *cpio_owner;
|
||||
IF_FEATURE_CPIO_O(const char *cpio_fmt = "";)
|
||||
unsigned opt;
|
||||
|
||||
|
@ -353,12 +372,14 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
|
|||
"pass-through\0" No_argument "p"
|
||||
#endif
|
||||
#endif
|
||||
"owner\0" Required_argument "R"
|
||||
"verbose\0" No_argument "v"
|
||||
"quiet\0" No_argument "\xff"
|
||||
"to-stdout\0" No_argument "\xfe"
|
||||
;
|
||||
#endif
|
||||
|
||||
INIT_G();
|
||||
archive_handle = init_handle();
|
||||
/* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */
|
||||
archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER;
|
||||
|
@ -369,14 +390,21 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
|
|||
/* -L makes sense only with -o or -p */
|
||||
|
||||
#if !ENABLE_FEATURE_CPIO_O
|
||||
opt = getopt32(argv, OPTION_STR, &cpio_filename);
|
||||
opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner);
|
||||
#else
|
||||
opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"),
|
||||
&cpio_filename, &cpio_owner, &cpio_fmt);
|
||||
#endif
|
||||
argv += optind;
|
||||
if (opt & OPT_OWNER) { /* -R */
|
||||
parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner);
|
||||
archive_handle->cpio__owner = G.owner_ugid;
|
||||
}
|
||||
#if !ENABLE_FEATURE_CPIO_O
|
||||
if (opt & OPT_FILE) { /* -F */
|
||||
xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
|
||||
}
|
||||
#else
|
||||
opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt);
|
||||
argv += optind;
|
||||
if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */
|
||||
xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
|
||||
}
|
||||
|
|
|
@ -77,13 +77,15 @@ aa: 85.1% -- replaced with aa.gz
|
|||
//kbuild:lib-$(CONFIG_GZIP) += gzip.o
|
||||
|
||||
//usage:#define gzip_trivial_usage
|
||||
//usage: "[-cfd" IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..."
|
||||
//usage: "[-cf" IF_GUNZIP("d") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..."
|
||||
//usage:#define gzip_full_usage "\n\n"
|
||||
//usage: "Compress FILEs (or stdin)\n"
|
||||
//usage: IF_FEATURE_GZIP_LEVELS(
|
||||
//usage: "\n -1..9 Compression level"
|
||||
//usage: )
|
||||
//usage: IF_GUNZIP(
|
||||
//usage: "\n -d Decompress"
|
||||
//usage: )
|
||||
//usage: "\n -c Write to stdout"
|
||||
//usage: "\n -f Force"
|
||||
//usage:
|
||||
|
@ -2160,6 +2162,7 @@ static const char gzip_longopts[] ALIGN1 =
|
|||
"quiet\0" No_argument "q"
|
||||
"fast\0" No_argument "1"
|
||||
"best\0" No_argument "9"
|
||||
"no-name\0" No_argument "n"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
@ -2217,10 +2220,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
|
|||
opt >>= ENABLE_GUNZIP ? 7 : 5; /* drop cfv[dt]qn bits */
|
||||
if (opt == 0)
|
||||
opt = 1 << 6; /* default: 6 */
|
||||
/* Map 1..3 to 4 */
|
||||
if (opt & 0x7)
|
||||
opt |= 1 << 4;
|
||||
opt = ffs(opt >> 3);
|
||||
opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */
|
||||
max_chain_length = 1 << gzip_level_config[opt].chain_shift;
|
||||
good_match = gzip_level_config[opt].good;
|
||||
max_lazy_match = gzip_level_config[opt].lazy2 * 2;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||
|
||||
lib-y:=
|
||||
lib-y:= common.o
|
||||
|
||||
COMMON_FILES:= \
|
||||
\
|
||||
|
|
9
archival/libarchive/common.c
Normal file
9
archival/libarchive/common.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||
*/
|
||||
|
||||
#include "libbb.h"
|
||||
#include "bb_archive.h"
|
||||
|
||||
const char cpio_TRAILER[] ALIGN1 = "TRAILER!!!";
|
|
@ -11,6 +11,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
file_header_t *file_header = archive_handle->file_header;
|
||||
int dst_fd;
|
||||
int res;
|
||||
char *hard_link;
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
char *dst_name;
|
||||
#else
|
||||
# define dst_name (file_header->name)
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_TAR_SELINUX
|
||||
char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
|
||||
|
@ -23,11 +29,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Hard links are encoded as regular files of size 0
|
||||
* with a nonempty link field */
|
||||
hard_link = NULL;
|
||||
if (S_ISREG(file_header->mode) && file_header->size == 0)
|
||||
hard_link = file_header->link_target;
|
||||
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
dst_name = file_header->name;
|
||||
if (archive_handle->tar__strip_components) {
|
||||
unsigned n = archive_handle->tar__strip_components;
|
||||
do {
|
||||
dst_name = strchr(dst_name, '/');
|
||||
if (!dst_name || dst_name[1] == '\0') {
|
||||
data_skip(archive_handle);
|
||||
goto ret;
|
||||
}
|
||||
dst_name++;
|
||||
/*
|
||||
* Link target is shortened only for hardlinks:
|
||||
* softlinks restored unchanged.
|
||||
*/
|
||||
if (hard_link) {
|
||||
// GNU tar 1.26 does not check that we reached end of link name:
|
||||
// if "dir/hardlink" is hardlinked to "file",
|
||||
// tar xvf a.tar --strip-components=1 says:
|
||||
// tar: hardlink: Cannot hard link to '': No such file or directory
|
||||
// and continues processing. We silently skip such entries.
|
||||
hard_link = strchr(hard_link, '/');
|
||||
if (!hard_link || hard_link[1] == '\0') {
|
||||
data_skip(archive_handle);
|
||||
goto ret;
|
||||
}
|
||||
hard_link++;
|
||||
}
|
||||
} while (--n != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
|
||||
char *slash = strrchr(file_header->name, '/');
|
||||
char *slash = strrchr(dst_name, '/');
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
|
||||
bb_make_directory(dst_name, -1, FILEUTILS_RECUR);
|
||||
*slash = '/';
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +79,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
|
||||
/* Remove the entry if it exists */
|
||||
if (!S_ISDIR(file_header->mode)) {
|
||||
/* Is it hardlink?
|
||||
* We encode hard links as regular files of size 0 with a symlink */
|
||||
if (S_ISREG(file_header->mode)
|
||||
&& file_header->link_target
|
||||
&& file_header->size == 0
|
||||
) {
|
||||
if (hard_link) {
|
||||
/* Ugly special case:
|
||||
* tar cf t.tar hardlink1 hardlink2 hardlink1
|
||||
* results in this tarball structure:
|
||||
|
@ -48,22 +87,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
* hardlink2 -> hardlink1
|
||||
* hardlink1 -> hardlink1 <== !!!
|
||||
*/
|
||||
if (strcmp(file_header->link_target, file_header->name) == 0)
|
||||
if (strcmp(hard_link, dst_name) == 0)
|
||||
goto ret;
|
||||
}
|
||||
/* Proceed with deleting */
|
||||
if (unlink(file_header->name) == -1
|
||||
if (unlink(dst_name) == -1
|
||||
&& errno != ENOENT
|
||||
) {
|
||||
bb_perror_msg_and_die("can't remove old file %s",
|
||||
file_header->name);
|
||||
dst_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
|
||||
/* Remove the existing entry if its older than the extracted entry */
|
||||
struct stat existing_sb;
|
||||
if (lstat(file_header->name, &existing_sb) == -1) {
|
||||
if (lstat(dst_name, &existing_sb) == -1) {
|
||||
if (errno != ENOENT) {
|
||||
bb_perror_msg_and_die("can't stat old file");
|
||||
}
|
||||
|
@ -73,30 +112,25 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
&& !S_ISDIR(file_header->mode)
|
||||
) {
|
||||
bb_error_msg("%s not created: newer or "
|
||||
"same age file exists", file_header->name);
|
||||
"same age file exists", dst_name);
|
||||
}
|
||||
data_skip(archive_handle);
|
||||
goto ret;
|
||||
}
|
||||
else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
|
||||
else if ((unlink(dst_name) == -1) && (errno != EISDIR)) {
|
||||
bb_perror_msg_and_die("can't remove old file %s",
|
||||
file_header->name);
|
||||
dst_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle hard links separately
|
||||
* We encode hard links as regular files of size 0 with a symlink */
|
||||
if (S_ISREG(file_header->mode)
|
||||
&& file_header->link_target
|
||||
&& file_header->size == 0
|
||||
) {
|
||||
/* hard link */
|
||||
res = link(file_header->link_target, file_header->name);
|
||||
if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
|
||||
/* Handle hard links separately */
|
||||
if (hard_link) {
|
||||
res = link(hard_link, dst_name);
|
||||
if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
|
||||
bb_perror_msg("can't create %slink "
|
||||
"from %s to %s", "hard",
|
||||
file_header->name,
|
||||
file_header->link_target);
|
||||
dst_name,
|
||||
hard_link);
|
||||
}
|
||||
/* Hardlinks have no separate mode/ownership, skip chown/chmod */
|
||||
goto ret;
|
||||
|
@ -106,17 +140,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
switch (file_header->mode & S_IFMT) {
|
||||
case S_IFREG: {
|
||||
/* Regular file */
|
||||
char *dst_name;
|
||||
char *dst_nameN;
|
||||
int flags = O_WRONLY | O_CREAT | O_EXCL;
|
||||
if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
dst_name = file_header->name;
|
||||
dst_nameN = dst_name;
|
||||
#ifdef ARCHIVE_REPLACE_VIA_RENAME
|
||||
if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
|
||||
/* rpm-style temp file name */
|
||||
dst_name = xasprintf("%s;%x", dst_name, (int)getpid());
|
||||
dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid());
|
||||
#endif
|
||||
dst_fd = xopen3(dst_name,
|
||||
dst_fd = xopen3(dst_nameN,
|
||||
flags,
|
||||
file_header->mode
|
||||
);
|
||||
|
@ -124,32 +158,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
close(dst_fd);
|
||||
#ifdef ARCHIVE_REPLACE_VIA_RENAME
|
||||
if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
|
||||
xrename(dst_name, file_header->name);
|
||||
free(dst_name);
|
||||
xrename(dst_nameN, dst_name);
|
||||
free(dst_nameN);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case S_IFDIR:
|
||||
res = mkdir(file_header->name, file_header->mode);
|
||||
res = mkdir(dst_name, file_header->mode);
|
||||
if ((res == -1)
|
||||
&& (errno != EISDIR) /* btw, Linux doesn't return this */
|
||||
&& (errno != EEXIST)
|
||||
&& !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
|
||||
) {
|
||||
bb_perror_msg("can't make dir %s", file_header->name);
|
||||
bb_perror_msg("can't make dir %s", dst_name);
|
||||
}
|
||||
break;
|
||||
case S_IFLNK:
|
||||
/* Symlink */
|
||||
//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
|
||||
res = symlink(file_header->link_target, file_header->name);
|
||||
if ((res == -1)
|
||||
res = symlink(file_header->link_target, dst_name);
|
||||
if (res != 0
|
||||
&& !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
|
||||
) {
|
||||
bb_perror_msg("can't create %slink "
|
||||
"from %s to %s", "sym",
|
||||
file_header->name,
|
||||
dst_name,
|
||||
file_header->link_target);
|
||||
}
|
||||
break;
|
||||
|
@ -157,11 +191,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
case S_IFBLK:
|
||||
case S_IFCHR:
|
||||
case S_IFIFO:
|
||||
res = mknod(file_header->name, file_header->mode, file_header->device);
|
||||
res = mknod(dst_name, file_header->mode, file_header->device);
|
||||
if ((res == -1)
|
||||
&& !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
|
||||
) {
|
||||
bb_perror_msg("can't create node %s", file_header->name);
|
||||
bb_perror_msg("can't create node %s", dst_name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -186,20 +220,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||
}
|
||||
#endif
|
||||
/* GNU tar 1.15.1 uses chown, not lchown */
|
||||
chown(file_header->name, uid, gid);
|
||||
chown(dst_name, uid, gid);
|
||||
}
|
||||
/* uclibc has no lchmod, glibc is even stranger -
|
||||
* it has lchmod which seems to do nothing!
|
||||
* so we use chmod... */
|
||||
if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
|
||||
chmod(file_header->name, file_header->mode);
|
||||
chmod(dst_name, file_header->mode);
|
||||
}
|
||||
if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
|
||||
struct timeval t[2];
|
||||
|
||||
t[1].tv_sec = t[0].tv_sec = file_header->mtime;
|
||||
t[1].tv_usec = t[0].tv_usec = 0;
|
||||
utimes(file_header->name, t);
|
||||
utimes(dst_name, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
|
|||
bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
|
||||
close(p[1]);
|
||||
|
||||
if (safe_waitpid(pid, &status, 0) == -1)
|
||||
bb_perror_msg_and_die("waitpid");
|
||||
status = wait_for_exitstatus(pid);
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status))
|
||||
bb_error_msg_and_die("'%s' returned status %d",
|
||||
archive_handle->tar__to_command, WEXITSTATUS(status));
|
||||
|
|
|
@ -305,11 +305,11 @@ static int huft_build(const unsigned *b, const unsigned n,
|
|||
unsigned i; /* counter, current code */
|
||||
unsigned j; /* counter */
|
||||
int k; /* number of bits in current code */
|
||||
unsigned *p; /* pointer into c[], b[], or v[] */
|
||||
const unsigned *p; /* pointer into c[], b[], or v[] */
|
||||
huft_t *q; /* points to current table */
|
||||
huft_t r; /* table entry for structure assignment */
|
||||
huft_t *u[BMAX]; /* table stack */
|
||||
unsigned v[N_MAX]; /* values in order of bit length */
|
||||
unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */
|
||||
int ws[BMAX + 1]; /* bits decoded stack */
|
||||
int w; /* bits decoded */
|
||||
unsigned x[BMAX + 1]; /* bit offsets, then code stack */
|
||||
|
@ -324,7 +324,7 @@ static int huft_build(const unsigned *b, const unsigned n,
|
|||
|
||||
/* Generate counts for each bit length */
|
||||
memset(c, 0, sizeof(c));
|
||||
p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */
|
||||
p = b;
|
||||
i = n;
|
||||
do {
|
||||
c[*p]++; /* assume all entries <= BMAX */
|
||||
|
@ -364,8 +364,12 @@ static int huft_build(const unsigned *b, const unsigned n,
|
|||
*xp++ = j;
|
||||
}
|
||||
|
||||
/* Make a table of values in order of bit lengths */
|
||||
p = (unsigned *) b;
|
||||
/* Make a table of values in order of bit lengths.
|
||||
* To detect bad input, unused v[i]'s are set to invalid value UINT_MAX.
|
||||
* In particular, last v[i] is never filled and must not be accessed.
|
||||
*/
|
||||
memset(v, 0xff, sizeof(v));
|
||||
p = b;
|
||||
i = 0;
|
||||
do {
|
||||
j = *p++;
|
||||
|
@ -432,7 +436,9 @@ static int huft_build(const unsigned *b, const unsigned n,
|
|||
|
||||
/* set up table entry in r */
|
||||
r.b = (unsigned char) (k - w);
|
||||
if (p >= v + n) {
|
||||
if (/*p >= v + n || -- redundant, caught by the second check: */
|
||||
*p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/
|
||||
) {
|
||||
r.e = 99; /* out of values--invalid code */
|
||||
} else if (*p < s) {
|
||||
r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */
|
||||
|
@ -517,8 +523,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
|
|||
e = t->e;
|
||||
if (e > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
abort_unzip(PASS_STATE_ONLY);;
|
||||
if (e == 99) {
|
||||
abort_unzip(PASS_STATE_ONLY);
|
||||
}
|
||||
bb >>= t->b;
|
||||
k -= t->b;
|
||||
e -= 16;
|
||||
|
@ -554,8 +561,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
|
|||
e = t->e;
|
||||
if (e > 16)
|
||||
do {
|
||||
if (e == 99)
|
||||
if (e == 99) {
|
||||
abort_unzip(PASS_STATE_ONLY);
|
||||
}
|
||||
bb >>= t->b;
|
||||
k -= t->b;
|
||||
e -= 16;
|
||||
|
@ -821,8 +829,9 @@ static int inflate_block(STATE_PARAM smallint *e)
|
|||
|
||||
b_dynamic >>= 4;
|
||||
k_dynamic -= 4;
|
||||
if (nl > 286 || nd > 30)
|
||||
if (nl > 286 || nd > 30) {
|
||||
abort_unzip(PASS_STATE_ONLY); /* bad lengths */
|
||||
}
|
||||
|
||||
/* read in bit-length-code lengths */
|
||||
for (j = 0; j < nb; j++) {
|
||||
|
@ -903,12 +912,14 @@ static int inflate_block(STATE_PARAM smallint *e)
|
|||
bl = lbits;
|
||||
|
||||
i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl);
|
||||
if (i != 0)
|
||||
if (i != 0) {
|
||||
abort_unzip(PASS_STATE_ONLY);
|
||||
}
|
||||
bd = dbits;
|
||||
i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd);
|
||||
if (i != 0)
|
||||
if (i != 0) {
|
||||
abort_unzip(PASS_STATE_ONLY);
|
||||
}
|
||||
|
||||
/* set up data for inflate_codes() */
|
||||
inflate_codes_setup(PASS_STATE bl, bd);
|
||||
|
@ -996,6 +1007,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
|
|||
error_msg = "corrupted data";
|
||||
if (setjmp(error_jmp)) {
|
||||
/* Error from deep inside zip machinery */
|
||||
bb_error_msg(error_msg);
|
||||
n = -1;
|
||||
goto ret;
|
||||
}
|
||||
|
@ -1118,9 +1130,8 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate)
|
|||
uint8_t os_flags_UNUSED;
|
||||
} PACKED formatted;
|
||||
} header;
|
||||
struct BUG_header {
|
||||
char BUG_header[sizeof(header) == 8 ? 1 : -1];
|
||||
};
|
||||
|
||||
BUILD_BUG_ON(sizeof(header) != 8);
|
||||
|
||||
/*
|
||||
* Rewind bytebuffer. We use the beginning because the header has 8
|
||||
|
@ -1190,7 +1201,7 @@ unpack_gz_stream(transformer_state_t *xstate)
|
|||
if (check_signature16(xstate, GZIP_MAGIC))
|
||||
return -1;
|
||||
#else
|
||||
if (xstate->check_signature) {
|
||||
if (!xstate->signature_skipped) {
|
||||
uint16_t magic2;
|
||||
|
||||
if (full_read(xstate->src_fd, &magic2, 2) != 2) {
|
||||
|
@ -1199,7 +1210,7 @@ unpack_gz_stream(transformer_state_t *xstate)
|
|||
return -1;
|
||||
}
|
||||
if (magic2 == COMPRESS_MAGIC) {
|
||||
xstate->check_signature = 0;
|
||||
xstate->signature_skipped = 2;
|
||||
return unpack_Z_stream(xstate);
|
||||
}
|
||||
if (magic2 != GZIP_MAGIC)
|
||||
|
|
|
@ -55,7 +55,7 @@ unpack_xz_stream(transformer_state_t *xstate)
|
|||
iobuf.out = membuf + BUFSIZ;
|
||||
iobuf.out_size = BUFSIZ;
|
||||
|
||||
if (!xstate || xstate->check_signature == 0) {
|
||||
if (!xstate || xstate->signature_skipped) {
|
||||
/* Preload XZ file signature */
|
||||
strcpy((char*)membuf, HEADER_MAGIC);
|
||||
iobuf.in_size = HEADER_MAGIC_SIZE;
|
||||
|
|
|
@ -52,6 +52,11 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
|
|||
&major, &minor, &namesize) != 10)
|
||||
bb_error_msg_and_die("damaged cpio file");
|
||||
file_header->mode = mode;
|
||||
/* "cpio -R USER:GRP" support: */
|
||||
if (archive_handle->cpio__owner.uid != (uid_t)-1L)
|
||||
uid = archive_handle->cpio__owner.uid;
|
||||
if (archive_handle->cpio__owner.gid != (gid_t)-1L)
|
||||
gid = archive_handle->cpio__owner.gid;
|
||||
file_header->uid = uid;
|
||||
file_header->gid = gid;
|
||||
file_header->mtime = mtime;
|
||||
|
@ -75,7 +80,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
|
|||
/* Update offset amount and skip padding before file contents */
|
||||
data_align(archive_handle, 4);
|
||||
|
||||
if (strcmp(file_header->name, "TRAILER!!!") == 0) {
|
||||
if (strcmp(file_header->name, cpio_TRAILER) == 0) {
|
||||
/* Always round up. ">> 9" divides by 512 */
|
||||
archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9;
|
||||
goto create_hardlinks;
|
||||
|
|
|
@ -60,13 +60,21 @@ static unsigned long long getOctal(char *str, int len)
|
|||
}
|
||||
#define GET_OCTAL(a) getOctal((a), sizeof(a))
|
||||
|
||||
#define TAR_EXTD (ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX)
|
||||
#if !TAR_EXTD
|
||||
#define process_pax_hdr(archive_handle, sz, global) \
|
||||
process_pax_hdr(archive_handle, sz)
|
||||
#endif
|
||||
/* "global" is 0 or 1 */
|
||||
static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global)
|
||||
{
|
||||
#if !TAR_EXTD
|
||||
unsigned blk_sz = (sz + 511) & (~511);
|
||||
seek_by_read(archive_handle->src_fd, blk_sz);
|
||||
#else
|
||||
unsigned blk_sz = (sz + 511) & (~511);
|
||||
char *buf, *p;
|
||||
unsigned blk_sz;
|
||||
|
||||
blk_sz = (sz + 511) & (~511);
|
||||
p = buf = xmalloc(blk_sz + 1);
|
||||
xread(archive_handle->src_fd, buf, blk_sz);
|
||||
archive_handle->offset += blk_sz;
|
||||
|
@ -104,30 +112,31 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g
|
|||
p[-1] = '\0';
|
||||
value = end + 1;
|
||||
|
||||
#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
||||
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
||||
if (!global && is_prefixed_with(value, "path=")) {
|
||||
value += sizeof("path=") - 1;
|
||||
free(archive_handle->tar__longname);
|
||||
archive_handle->tar__longname = xstrdup(value);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#if ENABLE_FEATURE_TAR_SELINUX
|
||||
# if ENABLE_FEATURE_TAR_SELINUX
|
||||
/* Scan for SELinux contexts, via "RHT.security.selinux" keyword.
|
||||
* This is what Red Hat's patched version of tar uses.
|
||||
*/
|
||||
# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
|
||||
# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
|
||||
if (is_prefixed_with(value, SELINUX_CONTEXT_KEYWORD"=")) {
|
||||
value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1;
|
||||
free(archive_handle->tar__sctx[global]);
|
||||
archive_handle->tar__sctx[global] = xstrdup(value);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
free(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
||||
|
@ -418,6 +427,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
|||
|
||||
/* Everything up to and including last ".." component is stripped */
|
||||
overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name));
|
||||
//TODO: do the same for file_header->link_target?
|
||||
|
||||
/* Strip trailing '/' in directories */
|
||||
/* Must be done after mode is set as '/' is used to check if it's a directory */
|
||||
|
|
|
@ -13,16 +13,13 @@ void FAST_FUNC init_transformer_state(transformer_state_t *xstate)
|
|||
|
||||
int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16)
|
||||
{
|
||||
if (xstate->check_signature) {
|
||||
if (!xstate->signature_skipped) {
|
||||
uint16_t magic2;
|
||||
if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) {
|
||||
bb_error_msg("invalid magic");
|
||||
#if 0 /* possible future extension */
|
||||
if (xstate->check_signature > 1)
|
||||
xfunc_die();
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
xstate->signature_skipped = 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,7 +99,7 @@ void check_errors_in_children(int signo)
|
|||
/* transformer(), more than meets the eye */
|
||||
#if BB_MMU
|
||||
void FAST_FUNC fork_transformer(int fd,
|
||||
int check_signature,
|
||||
int signature_skipped,
|
||||
IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate)
|
||||
)
|
||||
#else
|
||||
|
@ -123,7 +120,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog)
|
|||
IF_DESKTOP(long long) int r;
|
||||
transformer_state_t xstate;
|
||||
init_transformer_state(&xstate);
|
||||
xstate.check_signature = check_signature;
|
||||
xstate.signature_skipped = signature_skipped;
|
||||
xstate.src_fd = fd;
|
||||
xstate.dst_fd = fd_pipe.wr;
|
||||
r = transformer(&xstate);
|
||||
|
@ -168,12 +165,11 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
|
|||
uint16_t b16[2];
|
||||
uint32_t b32[1];
|
||||
} magic;
|
||||
int offset;
|
||||
transformer_state_t *xstate;
|
||||
|
||||
offset = -2;
|
||||
xstate = xzalloc(sizeof(*xstate));
|
||||
xstate->src_fd = fd;
|
||||
xstate->signature_skipped = 2;
|
||||
|
||||
/* .gz and .bz2 both have 2-byte signature, and their
|
||||
* unpack_XXX_stream wants this header skipped. */
|
||||
|
@ -202,7 +198,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
|
|||
if (ENABLE_FEATURE_SEAMLESS_XZ
|
||||
&& magic.b16[0] == XZ_MAGIC1
|
||||
) {
|
||||
offset = -6;
|
||||
xstate->signature_skipped = 6;
|
||||
xread(fd, magic.b32, sizeof(magic.b32[0]));
|
||||
if (magic.b32[0] == XZ_MAGIC2) {
|
||||
xstate->xformer = unpack_xz_stream;
|
||||
|
@ -224,18 +220,8 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
|
|||
*/
|
||||
// USE_FOR_MMU(xstate->xformer = copy_stream;)
|
||||
// USE_FOR_NOMMU(xstate->xformer_prog = "cat";)
|
||||
/* fall through to seeking bck over bytes we read earlier */
|
||||
|
||||
USE_FOR_NOMMU(found_magic:)
|
||||
/* NOMMU version of fork_transformer execs
|
||||
* an external unzipper that wants
|
||||
* file position at the start of the file.
|
||||
*/
|
||||
xlseek(fd, offset, SEEK_CUR);
|
||||
|
||||
USE_FOR_MMU(found_magic:)
|
||||
/* In MMU case, if magic was found, seeking back is not necessary */
|
||||
|
||||
found_magic:
|
||||
return xstate;
|
||||
}
|
||||
|
||||
|
@ -254,6 +240,12 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed)
|
|||
# if BB_MMU
|
||||
fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
|
||||
# else
|
||||
/* NOMMU version of fork_transformer execs
|
||||
* an external unzipper that wants
|
||||
* file position at the start of the file.
|
||||
*/
|
||||
xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
|
||||
xstate->signature_skipped = 0;
|
||||
fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
|
||||
# endif
|
||||
free(xstate);
|
||||
|
@ -296,14 +288,22 @@ int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed)
|
|||
return -1;
|
||||
|
||||
fd = xstate->src_fd;
|
||||
if (xstate->xformer) {
|
||||
# if BB_MMU
|
||||
fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
|
||||
# else
|
||||
fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
|
||||
# endif
|
||||
if (xstate->xformer) {
|
||||
fork_transformer_with_no_sig(fd, xstate->xformer);
|
||||
} else {
|
||||
/* the file is not compressed */
|
||||
xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
|
||||
xstate->signature_skipped = 0;
|
||||
}
|
||||
/* else: the file is not compressed */
|
||||
# else
|
||||
/* NOMMU can't avoid the seek :( */
|
||||
xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
|
||||
xstate->signature_skipped = 0;
|
||||
if (xstate->xformer) {
|
||||
fork_transformer_with_sig(fd, xstate->xformer, xstate->xformer_prog);
|
||||
} /* else: the file is not compressed */
|
||||
# endif
|
||||
|
||||
free(xstate);
|
||||
return fd;
|
||||
|
@ -331,6 +331,9 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_
|
|||
}
|
||||
} else {
|
||||
/* File is not compressed */
|
||||
//FIXME: avoid seek
|
||||
xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR);
|
||||
xstate->signature_skipped = 0;
|
||||
image = xmalloc_read(xstate->src_fd, maxsz_p);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
//usage: "\n -F Don't store or verify checksum"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "bb_archive.h"
|
||||
#include "liblzo_interface.h"
|
||||
|
||||
|
@ -443,8 +444,8 @@ struct globals {
|
|||
chksum_t chksum_in;
|
||||
chksum_t chksum_out;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define INIT_G() do { } while (0)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
//#define G (*ptr_to_globals)
|
||||
//#define INIT_G() do {
|
||||
// SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));
|
||||
|
@ -640,7 +641,7 @@ static int lzo_get_method(header_t *h)
|
|||
/**********************************************************************/
|
||||
// compress a file
|
||||
/**********************************************************************/
|
||||
static NOINLINE smallint lzo_compress(const header_t *h)
|
||||
static NOINLINE int lzo_compress(const header_t *h)
|
||||
{
|
||||
unsigned block_size = LZO_BLOCK_SIZE;
|
||||
int r = 0; /* LZO_E_OK */
|
||||
|
@ -650,7 +651,6 @@ static NOINLINE smallint lzo_compress(const header_t *h)
|
|||
uint32_t d_adler32 = ADLER32_INIT_VALUE;
|
||||
uint32_t d_crc32 = CRC32_INIT_VALUE;
|
||||
int l;
|
||||
smallint ok = 1;
|
||||
uint8_t *wrk_mem = NULL;
|
||||
|
||||
if (h->method == M_LZO1X_1)
|
||||
|
@ -732,7 +732,7 @@ static NOINLINE smallint lzo_compress(const header_t *h)
|
|||
free(wrk_mem);
|
||||
free(b1);
|
||||
free(b2);
|
||||
return ok;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static FAST_FUNC void lzo_check(
|
||||
|
@ -753,7 +753,7 @@ static FAST_FUNC void lzo_check(
|
|||
/**********************************************************************/
|
||||
// decompress a file
|
||||
/**********************************************************************/
|
||||
static NOINLINE smallint lzo_decompress(const header_t *h)
|
||||
static NOINLINE int lzo_decompress(const header_t *h)
|
||||
{
|
||||
unsigned block_size = LZO_BLOCK_SIZE;
|
||||
int r;
|
||||
|
@ -761,7 +761,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h)
|
|||
uint32_t c_adler32 = ADLER32_INIT_VALUE;
|
||||
uint32_t d_adler32 = ADLER32_INIT_VALUE;
|
||||
uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE;
|
||||
smallint ok = 1;
|
||||
uint8_t *b1;
|
||||
uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size);
|
||||
uint8_t *b2 = NULL;
|
||||
|
@ -865,7 +864,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h)
|
|||
}
|
||||
|
||||
free(b2);
|
||||
return ok;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
@ -897,7 +896,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h)
|
|||
* chksum_out
|
||||
* The rest is identical.
|
||||
*/
|
||||
static const unsigned char lzop_magic[9] = {
|
||||
static const unsigned char lzop_magic[9] ALIGN1 = {
|
||||
0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a
|
||||
};
|
||||
|
||||
|
@ -1050,7 +1049,7 @@ static void lzo_set_method(header_t *h)
|
|||
h->level = level;
|
||||
}
|
||||
|
||||
static smallint do_lzo_compress(void)
|
||||
static int do_lzo_compress(void)
|
||||
{
|
||||
header_t header;
|
||||
|
||||
|
@ -1078,7 +1077,7 @@ static smallint do_lzo_compress(void)
|
|||
/**********************************************************************/
|
||||
// decompress
|
||||
/**********************************************************************/
|
||||
static smallint do_lzo_decompress(void)
|
||||
static int do_lzo_decompress(void)
|
||||
{
|
||||
header_t header;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
//usage: "\n -qpc List config files"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "bb_archive.h"
|
||||
#include "rpm.h"
|
||||
|
||||
|
@ -93,8 +94,8 @@ struct globals {
|
|||
rpm_index **mytags;
|
||||
int tagcount;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define INIT_G() do { } while (0)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
static void extract_cpio(int fd, const char *source_rpm)
|
||||
{
|
||||
|
|
|
@ -146,18 +146,23 @@
|
|||
|
||||
#include <fnmatch.h>
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "bb_archive.h"
|
||||
/* FIXME: Stop using this non-standard feature */
|
||||
#ifndef FNM_LEADING_DIR
|
||||
# define FNM_LEADING_DIR 0
|
||||
#endif
|
||||
|
||||
|
||||
//#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
|
||||
#define DBG(...) ((void)0)
|
||||
#if 0
|
||||
# define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
|
||||
#else
|
||||
# define DBG(...) ((void)0)
|
||||
#endif
|
||||
#define DBG_OPTION_PARSING 0
|
||||
|
||||
|
||||
#define block_buf bb_common_bufsiz1
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
|
||||
#if ENABLE_FEATURE_TAR_CREATE
|
||||
|
@ -855,6 +860,7 @@ enum {
|
|||
IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,)
|
||||
IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
OPTBIT_STRIP_COMPONENTS,
|
||||
OPTBIT_NORECURSION,
|
||||
IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,)
|
||||
OPTBIT_NUMERIC_OWNER,
|
||||
|
@ -879,12 +885,13 @@ enum {
|
|||
OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
|
||||
OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J
|
||||
OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
|
||||
OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
|
||||
OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion
|
||||
OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
|
||||
OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
|
||||
OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
|
||||
OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite
|
||||
OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
|
||||
OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components
|
||||
OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion
|
||||
OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
|
||||
OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
|
||||
OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
|
||||
OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite
|
||||
|
||||
OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS),
|
||||
};
|
||||
|
@ -928,6 +935,7 @@ static const char tar_longopts[] ALIGN1 =
|
|||
# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME
|
||||
"touch\0" No_argument "m"
|
||||
# endif
|
||||
"strip-components\0" Required_argument "\xf9"
|
||||
"no-recursion\0" No_argument "\xfa"
|
||||
# if ENABLE_FEATURE_TAR_TO_COMMAND
|
||||
"to-command\0" Required_argument "\xfb"
|
||||
|
@ -957,6 +965,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
|
||||
llist_t *excludes = NULL;
|
||||
#endif
|
||||
INIT_G();
|
||||
|
||||
/* Initialise default values */
|
||||
tar_handle = init_handle();
|
||||
|
@ -973,15 +982,28 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
"tt:vv:" // count -t,-v
|
||||
IF_FEATURE_TAR_FROM("X::T::") // cumulative lists
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
|
||||
"\xff::" // cumulative lists for --exclude
|
||||
"\xff::" // --exclude=PATTERN is a list
|
||||
#endif
|
||||
IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
|
||||
IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
|
||||
IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive
|
||||
IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
":\xf9+" // --strip-components=NUM
|
||||
#endif
|
||||
;
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
applet_long_options = tar_longopts;
|
||||
#endif
|
||||
#if ENABLE_DESKTOP
|
||||
/* Lie to buildroot when it starts asking stupid questions. */
|
||||
if (argv[1] && strcmp(argv[1], "--version") == 0) {
|
||||
// Output of 'tar --version' examples:
|
||||
// tar (GNU tar) 1.15.1
|
||||
// tar (GNU tar) 1.25
|
||||
// bsdtar 2.8.3 - libarchive 2.8.3
|
||||
puts("tar (busybox) " BB_VER);
|
||||
return 0;
|
||||
}
|
||||
if (argv[1] && argv[1][0] != '-') {
|
||||
/* Compat:
|
||||
* 1st argument without dash handles options with parameters
|
||||
|
@ -1018,10 +1040,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
IF_FEATURE_SEAMLESS_XZ( "J" )
|
||||
IF_FEATURE_SEAMLESS_Z( "Z" )
|
||||
IF_FEATURE_TAR_NOPRESERVE_TIME("m")
|
||||
IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
|
||||
, &base_dir // -C dir
|
||||
, &tar_filename // -f filename
|
||||
IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
|
||||
IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
|
||||
, &tar_handle->tar__strip_components // --strip-components
|
||||
#endif
|
||||
IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command
|
||||
#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
|
||||
, &excludes // --exclude
|
||||
|
@ -1029,11 +1055,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
, &verboseFlag // combined count for -t and -v
|
||||
, &verboseFlag // combined count for -t and -v
|
||||
);
|
||||
//bb_error_msg("opt:%08x", opt);
|
||||
#if DBG_OPTION_PARSING
|
||||
bb_error_msg("opt: 0x%08x", opt);
|
||||
# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o);
|
||||
showopt(OPT_TEST );
|
||||
showopt(OPT_EXTRACT );
|
||||
showopt(OPT_BASEDIR );
|
||||
showopt(OPT_TARNAME );
|
||||
showopt(OPT_2STDOUT );
|
||||
showopt(OPT_NOPRESERVE_OWNER);
|
||||
showopt(OPT_P );
|
||||
showopt(OPT_VERBOSE );
|
||||
showopt(OPT_KEEP_OLD );
|
||||
showopt(OPT_CREATE );
|
||||
showopt(OPT_DEREFERENCE );
|
||||
showopt(OPT_BZIP2 );
|
||||
showopt(OPT_LZMA );
|
||||
showopt(OPT_INCLUDE_FROM );
|
||||
showopt(OPT_EXCLUDE_FROM );
|
||||
showopt(OPT_GZIP );
|
||||
showopt(OPT_XZ );
|
||||
showopt(OPT_COMPRESS );
|
||||
showopt(OPT_NOPRESERVE_TIME );
|
||||
showopt(OPT_STRIP_COMPONENTS);
|
||||
showopt(OPT_NORECURSION );
|
||||
showopt(OPT_2COMMAND );
|
||||
showopt(OPT_NUMERIC_OWNER );
|
||||
showopt(OPT_NOPRESERVE_PERM );
|
||||
showopt(OPT_OVERWRITE );
|
||||
showopt(OPT_ANY_COMPRESS );
|
||||
bb_error_msg("base_dir:'%s'", base_dir);
|
||||
bb_error_msg("tar_filename:'%s'", tar_filename);
|
||||
bb_error_msg("verboseFlag:%d", verboseFlag);
|
||||
bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command);
|
||||
bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components);
|
||||
return 0;
|
||||
# undef showopt
|
||||
#endif
|
||||
argv += optind;
|
||||
|
||||
if (verboseFlag) tar_handle->action_header = header_verbose_list;
|
||||
if (verboseFlag == 1) tar_handle->action_header = header_list;
|
||||
if (verboseFlag)
|
||||
tar_handle->action_header = header_verbose_list;
|
||||
if (verboseFlag == 1)
|
||||
tar_handle->action_header = header_list;
|
||||
|
||||
if (opt & OPT_EXTRACT)
|
||||
tar_handle->action_data = data_extract_all;
|
||||
|
@ -1135,9 +1199,10 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
// /* We need to know whether child (gzip/bzip/etc) exits abnormally */
|
||||
// signal(SIGCHLD, check_errors_in_children);
|
||||
|
||||
#if ENABLE_FEATURE_TAR_CREATE
|
||||
/* Create an archive */
|
||||
if (opt & OPT_CREATE) {
|
||||
#if SEAMLESS_COMPRESSION
|
||||
# if SEAMLESS_COMPRESSION
|
||||
const char *zipMode = NULL;
|
||||
if (opt & OPT_COMPRESS)
|
||||
zipMode = "compress";
|
||||
|
@ -1149,7 +1214,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
zipMode = "lzma";
|
||||
if (opt & OPT_XZ)
|
||||
zipMode = "xz";
|
||||
#endif
|
||||
# endif
|
||||
/* NB: writeTarFile() closes tar_handle->src_fd */
|
||||
return writeTarFile(tar_handle->src_fd, verboseFlag,
|
||||
(opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0)
|
||||
|
@ -1157,6 +1222,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
|
|||
tar_handle->accept,
|
||||
tar_handle->reject, zipMode);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (opt & OPT_ANY_COMPRESS) {
|
||||
USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);)
|
||||
|
|
138
archival/unzip.c
138
archival/unzip.c
|
@ -45,6 +45,12 @@
|
|||
#include "libbb.h"
|
||||
#include "bb_archive.h"
|
||||
|
||||
#if 0
|
||||
# define dbg(...) bb_error_msg(__VA_ARGS__)
|
||||
#else
|
||||
# define dbg(...) ((void)0)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
#if BB_BIG_ENDIAN
|
||||
ZIP_FILEHEADER_MAGIC = 0x504b0304,
|
||||
|
@ -193,15 +199,17 @@ static uint32_t find_cdf_offset(void)
|
|||
unsigned char *p;
|
||||
off_t end;
|
||||
unsigned char *buf = xzalloc(PEEK_FROM_END);
|
||||
uint32_t found;
|
||||
|
||||
end = xlseek(zip_fd, 0, SEEK_END);
|
||||
end -= PEEK_FROM_END;
|
||||
if (end < 0)
|
||||
end = 0;
|
||||
xlseek(zip_fd, end, SEEK_SET);
|
||||
dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end);
|
||||
xlseek(zip_fd, end, SEEK_SET);
|
||||
full_read(zip_fd, buf, PEEK_FROM_END);
|
||||
|
||||
cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
|
||||
found = BAD_CDF_OFFSET;
|
||||
p = buf;
|
||||
while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
|
||||
if (*p != 'P') {
|
||||
|
@ -220,14 +228,25 @@ static uint32_t find_cdf_offset(void)
|
|||
/*
|
||||
* I've seen .ZIP files with seemingly valid CDEs
|
||||
* where cdf_offset points past EOF - ??
|
||||
* Ignore such CDEs:
|
||||
* This check ignores such CDEs:
|
||||
*/
|
||||
if (cde_header.formatted.cdf_offset < end + (p - buf))
|
||||
break;
|
||||
cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
|
||||
if (cde_header.formatted.cdf_offset < end + (p - buf)) {
|
||||
found = cde_header.formatted.cdf_offset;
|
||||
dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x",
|
||||
(unsigned)found, end + (p-3 - buf));
|
||||
dbg(" cdf_offset+cdf_size:0x%x",
|
||||
(unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size)));
|
||||
/*
|
||||
* We do not "break" here because only the last CDE is valid.
|
||||
* I've seen a .zip archive which contained a .zip file,
|
||||
* uncompressed, and taking the first CDE was using
|
||||
* the CDE inside that file!
|
||||
*/
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return cde_header.formatted.cdf_offset;
|
||||
dbg("Found cdf_offset:0x%x", (unsigned)found);
|
||||
return found;
|
||||
};
|
||||
|
||||
static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
|
||||
|
@ -240,15 +259,22 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
|
|||
cdf_offset = find_cdf_offset();
|
||||
|
||||
if (cdf_offset != BAD_CDF_OFFSET) {
|
||||
dbg("Reading CDF at 0x%x", (unsigned)cdf_offset);
|
||||
xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
|
||||
xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
|
||||
FIX_ENDIANNESS_CDF(*cdf_ptr);
|
||||
dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u",
|
||||
(unsigned)cdf_ptr->formatted.file_name_length,
|
||||
(unsigned)cdf_ptr->formatted.extra_field_length,
|
||||
(unsigned)cdf_ptr->formatted.file_comment_length
|
||||
);
|
||||
cdf_offset += 4 + CDF_HEADER_LEN
|
||||
+ cdf_ptr->formatted.file_name_length
|
||||
+ cdf_ptr->formatted.extra_field_length
|
||||
+ cdf_ptr->formatted.file_comment_length;
|
||||
}
|
||||
|
||||
dbg("Returning file position to 0x%"OFF_FMT"x", org);
|
||||
xlseek(zip_fd, org, SEEK_SET);
|
||||
return cdf_offset;
|
||||
};
|
||||
|
@ -461,7 +487,7 @@ int unzip_main(int argc, char **argv)
|
|||
if (overwrite == O_PROMPT)
|
||||
overwrite = O_NEVER;
|
||||
} else {
|
||||
static const char extn[][5] = { ".zip", ".ZIP" };
|
||||
static const char extn[][5] ALIGN1 = { ".zip", ".ZIP" };
|
||||
char *ext = src_fn + strlen(src_fn);
|
||||
int src_fd;
|
||||
|
||||
|
@ -488,11 +514,11 @@ int unzip_main(int argc, char **argv)
|
|||
printf("Archive: %s\n", src_fn);
|
||||
if (listing) {
|
||||
puts(verbose ?
|
||||
" Length Method Size Ratio Date Time CRC-32 Name\n"
|
||||
"-------- ------ ------- ----- ---- ---- ------ ----"
|
||||
" Length Method Size Cmpr Date Time CRC-32 Name\n"
|
||||
"-------- ------ ------- ---- ---------- ----- -------- ----"
|
||||
:
|
||||
" Length Date Time Name\n"
|
||||
" -------- ---- ---- ----"
|
||||
" Length Date Time Name\n"
|
||||
"--------- ---------- ----- ----"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -532,11 +558,14 @@ int unzip_main(int argc, char **argv)
|
|||
/* Check magic number */
|
||||
xread(zip_fd, &magic, 4);
|
||||
/* Central directory? It's at the end, so exit */
|
||||
if (magic == ZIP_CDF_MAGIC)
|
||||
if (magic == ZIP_CDF_MAGIC) {
|
||||
dbg("got ZIP_CDF_MAGIC");
|
||||
break;
|
||||
}
|
||||
#if ENABLE_DESKTOP
|
||||
/* Data descriptor? It was a streaming file, go on */
|
||||
if (magic == ZIP_DD_MAGIC) {
|
||||
dbg("got ZIP_DD_MAGIC");
|
||||
/* skip over duplicate crc32, cmpsize and ucmpsize */
|
||||
unzip_skip(3 * 4);
|
||||
continue;
|
||||
|
@ -544,6 +573,7 @@ int unzip_main(int argc, char **argv)
|
|||
#endif
|
||||
if (magic != ZIP_FILEHEADER_MAGIC)
|
||||
bb_error_msg_and_die("invalid zip magic %08X", (int)magic);
|
||||
dbg("got ZIP_FILEHEADER_MAGIC");
|
||||
|
||||
/* Read the file header */
|
||||
xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN);
|
||||
|
@ -587,6 +617,11 @@ int unzip_main(int argc, char **argv)
|
|||
bb_error_msg_and_die("can't find file table");
|
||||
}
|
||||
#endif
|
||||
dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x",
|
||||
(unsigned)zip_header.formatted.cmpsize,
|
||||
(unsigned)zip_header.formatted.extra_len,
|
||||
(unsigned)zip_header.formatted.ucmpsize
|
||||
);
|
||||
|
||||
/* Read filename */
|
||||
free(dst_fn);
|
||||
|
@ -607,40 +642,55 @@ int unzip_main(int argc, char **argv)
|
|||
} else {
|
||||
if (listing) {
|
||||
/* List entry */
|
||||
unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16);
|
||||
char dtbuf[sizeof("mm-dd-yyyy hh:mm")];
|
||||
sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u",
|
||||
(zip_header.formatted.moddate >> 5) & 0xf, // mm: 0x01e0
|
||||
(zip_header.formatted.moddate) & 0x1f, // dd: 0x001f
|
||||
(zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00
|
||||
(zip_header.formatted.modtime >> 11), // hh: 0xf800
|
||||
(zip_header.formatted.modtime >> 5) & 0x3f // mm: 0x07e0
|
||||
// seconds/2 are not shown, encoded in ----------- 0x001f
|
||||
);
|
||||
if (!verbose) {
|
||||
// " Length Date Time Name\n"
|
||||
// " -------- ---- ---- ----"
|
||||
printf( "%9u %02u-%02u-%02u %02u:%02u %s\n",
|
||||
// " Length Date Time Name\n"
|
||||
// "--------- ---------- ----- ----"
|
||||
printf( "%9u " "%s " "%s\n",
|
||||
(unsigned)zip_header.formatted.ucmpsize,
|
||||
(dostime & 0x01e00000) >> 21,
|
||||
(dostime & 0x001f0000) >> 16,
|
||||
(((dostime & 0xfe000000) >> 25) + 1980) % 100,
|
||||
(dostime & 0x0000f800) >> 11,
|
||||
(dostime & 0x000007e0) >> 5,
|
||||
dtbuf,
|
||||
dst_fn);
|
||||
total_usize += zip_header.formatted.ucmpsize;
|
||||
} else {
|
||||
unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize;
|
||||
if ((int32_t)percents < 0)
|
||||
percents = 0; /* happens if ucmpsize < cmpsize */
|
||||
percents = percents * 100;
|
||||
if (zip_header.formatted.ucmpsize)
|
||||
percents /= zip_header.formatted.ucmpsize;
|
||||
// " Length Method Size Ratio Date Time CRC-32 Name\n"
|
||||
// "-------- ------ ------- ----- ---- ---- ------ ----"
|
||||
printf( "%8u Defl:N" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n",
|
||||
// " Length Method Size Cmpr Date Time CRC-32 Name\n"
|
||||
// "-------- ------ ------- ---- ---------- ----- -------- ----"
|
||||
printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n",
|
||||
(unsigned)zip_header.formatted.ucmpsize,
|
||||
zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */
|
||||
/* TODO: show other methods?
|
||||
* 1 - Shrunk
|
||||
* 2 - Reduced with compression factor 1
|
||||
* 3 - Reduced with compression factor 2
|
||||
* 4 - Reduced with compression factor 3
|
||||
* 5 - Reduced with compression factor 4
|
||||
* 6 - Imploded
|
||||
* 7 - Reserved for Tokenizing compression algorithm
|
||||
* 9 - Deflate64
|
||||
* 10 - PKWARE Data Compression Library Imploding
|
||||
* 11 - Reserved by PKWARE
|
||||
* 12 - BZIP2
|
||||
*/
|
||||
(unsigned)zip_header.formatted.cmpsize,
|
||||
(unsigned)percents,
|
||||
(dostime & 0x01e00000) >> 21,
|
||||
(dostime & 0x001f0000) >> 16,
|
||||
(((dostime & 0xfe000000) >> 25) + 1980) % 100,
|
||||
(dostime & 0x0000f800) >> 11,
|
||||
(dostime & 0x000007e0) >> 5,
|
||||
dtbuf,
|
||||
zip_header.formatted.crc32,
|
||||
dst_fn);
|
||||
total_usize += zip_header.formatted.ucmpsize;
|
||||
total_size += zip_header.formatted.cmpsize;
|
||||
}
|
||||
total_usize += zip_header.formatted.ucmpsize;
|
||||
i = 'n';
|
||||
} else if (dst_fd == STDOUT_FILENO) {
|
||||
/* Extracting to STDOUT */
|
||||
|
@ -743,21 +793,25 @@ int unzip_main(int argc, char **argv)
|
|||
|
||||
if (listing && quiet <= 1) {
|
||||
if (!verbose) {
|
||||
// " Length Date Time Name\n"
|
||||
// " -------- ---- ---- ----"
|
||||
printf( " -------- -------\n"
|
||||
"%9lu" " %u files\n",
|
||||
total_usize, total_entries);
|
||||
// " Length Date Time Name\n"
|
||||
// "--------- ---------- ----- ----"
|
||||
printf( " --------%21s" "-------\n"
|
||||
"%9lu%21s" "%u files\n",
|
||||
"",
|
||||
total_usize, "", total_entries);
|
||||
} else {
|
||||
unsigned long percents = total_usize - total_size;
|
||||
if ((long)percents < 0)
|
||||
percents = 0; /* happens if usize < size */
|
||||
percents = percents * 100;
|
||||
if (total_usize)
|
||||
percents /= total_usize;
|
||||
// " Length Method Size Ratio Date Time CRC-32 Name\n"
|
||||
// "-------- ------ ------- ----- ---- ---- ------ ----"
|
||||
printf( "-------- ------- --- -------\n"
|
||||
"%8lu" "%17lu%4u%% %u files\n",
|
||||
total_usize, total_size, (unsigned)percents,
|
||||
// " Length Method Size Cmpr Date Time CRC-32 Name\n"
|
||||
// "-------- ------ ------- ---- ---------- ----- -------- ----"
|
||||
printf( "-------- ------- ----%28s" "----\n"
|
||||
"%8lu" "%17lu%4u%%%28s" "%u files\n",
|
||||
"",
|
||||
total_usize, total_size, (unsigned)percents, "",
|
||||
total_entries);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ CONFIG_FEATURE_INIT_SCTTY=y
|
|||
CONFIG_FEATURE_INIT_SYSLOG=y
|
||||
CONFIG_FEATURE_EXTRA_QUIET=y
|
||||
CONFIG_FEATURE_INIT_COREDUMPS=y
|
||||
CONFIG_FEATURE_INITRD=y
|
||||
CONFIG_LINUXRC=y
|
||||
CONFIG_HALT=y
|
||||
# CONFIG_FEATURE_CALL_TELINIT is not set
|
||||
CONFIG_TELINIT_PATH=""
|
||||
|
|
|
@ -395,7 +395,7 @@ CONFIG_FEATURE_KILL_DELAY=0
|
|||
# CONFIG_FEATURE_INIT_SYSLOG is not set
|
||||
# CONFIG_FEATURE_EXTRA_QUIET is not set
|
||||
# CONFIG_FEATURE_INIT_COREDUMPS is not set
|
||||
# CONFIG_FEATURE_INITRD is not set
|
||||
# CONFIG_LINUXRC is not set
|
||||
# CONFIG_HALT is not set
|
||||
# CONFIG_FEATURE_CALL_TELINIT is not set
|
||||
CONFIG_TELINIT_PATH=""
|
||||
|
|
|
@ -407,7 +407,7 @@ CONFIG_FEATURE_INIT_SCTTY=y
|
|||
CONFIG_FEATURE_INIT_SYSLOG=y
|
||||
CONFIG_FEATURE_EXTRA_QUIET=y
|
||||
CONFIG_FEATURE_INIT_COREDUMPS=y
|
||||
CONFIG_FEATURE_INITRD=y
|
||||
CONFIG_LINUXRC=y
|
||||
CONFIG_HALT=y
|
||||
# CONFIG_FEATURE_CALL_TELINIT is not set
|
||||
CONFIG_TELINIT_PATH=""
|
||||
|
|
|
@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install"
|
|||
#
|
||||
# Busybox Library Tuning
|
||||
#
|
||||
# CONFIG_FEATURE_SYSTEMD is not set
|
||||
# CONFIG_FEATURE_RTMINMAX is not set
|
||||
CONFIG_PASSWORD_MINLEN=6
|
||||
CONFIG_MD5_SMALL=1
|
||||
|
@ -426,7 +425,7 @@ CONFIG_FEATURE_INIT_SCTTY=y
|
|||
CONFIG_FEATURE_INIT_SYSLOG=y
|
||||
CONFIG_FEATURE_EXTRA_QUIET=y
|
||||
CONFIG_FEATURE_INIT_COREDUMPS=y
|
||||
CONFIG_FEATURE_INITRD=y
|
||||
CONFIG_LINUXRC=y
|
||||
CONFIG_INIT_TERMINAL_TYPE="linux"
|
||||
CONFIG_MESG=y
|
||||
CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y
|
||||
|
|
1142
configs/android_502_defconfig
Normal file
1142
configs/android_502_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -107,7 +107,6 @@ CONFIG_PREFIX="./_install"
|
|||
#
|
||||
# Busybox Library Tuning
|
||||
#
|
||||
# CONFIG_FEATURE_SYSTEMD is not set
|
||||
# CONFIG_FEATURE_RTMINMAX is not set
|
||||
CONFIG_PASSWORD_MINLEN=6
|
||||
CONFIG_MD5_SMALL=1
|
||||
|
@ -449,7 +448,7 @@ CONFIG_FEATURE_INIT_SCTTY=y
|
|||
CONFIG_FEATURE_INIT_SYSLOG=y
|
||||
CONFIG_FEATURE_EXTRA_QUIET=y
|
||||
CONFIG_FEATURE_INIT_COREDUMPS=y
|
||||
CONFIG_FEATURE_INITRD=y
|
||||
CONFIG_LINUXRC=y
|
||||
CONFIG_INIT_TERMINAL_TYPE="linux"
|
||||
CONFIG_MESG=y
|
||||
CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y
|
||||
|
|
|
@ -96,7 +96,6 @@ CONFIG_PREFIX="./_install"
|
|||
#
|
||||
# Busybox Library Tuning
|
||||
#
|
||||
# CONFIG_FEATURE_SYSTEMD is not set
|
||||
# CONFIG_FEATURE_RTMINMAX is not set
|
||||
CONFIG_PASSWORD_MINLEN=6
|
||||
CONFIG_MD5_SMALL=1
|
||||
|
@ -459,7 +458,7 @@ CONFIG_FEATURE_INIT_SCTTY=y
|
|||
CONFIG_FEATURE_INIT_SYSLOG=y
|
||||
CONFIG_FEATURE_EXTRA_QUIET=y
|
||||
CONFIG_FEATURE_INIT_COREDUMPS=y
|
||||
CONFIG_FEATURE_INITRD=y
|
||||
CONFIG_LINUXRC=y
|
||||
CONFIG_INIT_TERMINAL_TYPE="linux"
|
||||
CONFIG_MESG=y
|
||||
CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y
|
||||
|
|
|
@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install"
|
|||
#
|
||||
# Busybox Library Tuning
|
||||
#
|
||||
# CONFIG_FEATURE_SYSTEMD is not set
|
||||
CONFIG_FEATURE_RTMINMAX=y
|
||||
CONFIG_PASSWORD_MINLEN=6
|
||||
CONFIG_MD5_SMALL=1
|
||||
|
@ -426,7 +425,7 @@ CONFIG_FEATURE_KILL_DELAY=0
|
|||
# CONFIG_FEATURE_INIT_SYSLOG is not set
|
||||
# CONFIG_FEATURE_EXTRA_QUIET is not set
|
||||
# CONFIG_FEATURE_INIT_COREDUMPS is not set
|
||||
# CONFIG_FEATURE_INITRD is not set
|
||||
# CONFIG_LINUXRC is not set
|
||||
CONFIG_INIT_TERMINAL_TYPE=""
|
||||
CONFIG_MESG=y
|
||||
CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y
|
||||
|
|
|
@ -422,7 +422,7 @@ CONFIG_FEATURE_KILL_DELAY=0
|
|||
# CONFIG_FEATURE_INIT_SYSLOG is not set
|
||||
# CONFIG_FEATURE_EXTRA_QUIET is not set
|
||||
# CONFIG_FEATURE_INIT_COREDUMPS is not set
|
||||
# CONFIG_FEATURE_INITRD is not set
|
||||
# CONFIG_LINUXRC is not set
|
||||
CONFIG_INIT_TERMINAL_TYPE=""
|
||||
# CONFIG_MESG is not set
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
//usage: "$ dumpkmap > keymap\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
/* From <linux/kd.h> */
|
||||
struct kbentry {
|
||||
|
@ -37,6 +38,7 @@ int dumpkmap_main(int argc UNUSED_PARAM, char **argv)
|
|||
struct kbentry ke;
|
||||
int i, j, fd;
|
||||
#define flags bb_common_bufsiz1
|
||||
setup_common_bufsiz();
|
||||
|
||||
/* When user accidentally runs "dumpkmap FILE"
|
||||
* instead of "dumpkmap >FILE", we'd dump binary stuff to tty.
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
//usage: "Resize the screen"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#define ESC "\033"
|
||||
|
||||
#define old_termios_p ((struct termios*)&bb_common_bufsiz1)
|
||||
#define old_termios_p ((struct termios*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
static void
|
||||
onintr(int sig UNUSED_PARAM)
|
||||
|
@ -33,6 +35,8 @@ int resize_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||
struct winsize w = { 0, 0, 0, 0 };
|
||||
int ret;
|
||||
|
||||
INIT_G();
|
||||
|
||||
/* We use _stderr_ in order to make resize usable
|
||||
* in shell backticks (those redirect stdout away from tty).
|
||||
* NB: other versions of resize open "/dev/tty"
|
||||
|
|
|
@ -543,22 +543,6 @@ config FEATURE_SPLIT_FANCY
|
|||
Supports additional suffixes 'b' for 512 bytes,
|
||||
'g' for 1GiB for the -b option.
|
||||
|
||||
config STAT
|
||||
bool "stat"
|
||||
default y
|
||||
select PLATFORM_LINUX # statfs()
|
||||
help
|
||||
display file or filesystem status.
|
||||
|
||||
config FEATURE_STAT_FORMAT
|
||||
bool "Enable custom formats (-c)"
|
||||
default y
|
||||
depends on STAT
|
||||
help
|
||||
Without this, stat will not support the '-c format' option where
|
||||
users can pass a custom format string for output. This adds about
|
||||
7k to a nonstatic build on amd64.
|
||||
|
||||
config STTY
|
||||
bool "stty"
|
||||
default y
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
//usage: "\n -v Don't use ^x or M-x escapes"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#define CATV_OPT_e (1<<0)
|
||||
#define CATV_OPT_t (1<<1)
|
||||
|
@ -48,6 +49,9 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
|
|||
/* Read from stdin if there's nothing else to do. */
|
||||
if (!argv[0])
|
||||
*--argv = (char*)"-";
|
||||
|
||||
#define read_buf bb_common_bufsiz1
|
||||
setup_common_bufsiz();
|
||||
do {
|
||||
fd = open_or_warn_stdin(*argv);
|
||||
if (fd < 0) {
|
||||
|
@ -57,7 +61,6 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
|
|||
for (;;) {
|
||||
int i, res;
|
||||
|
||||
#define read_buf bb_common_bufsiz1
|
||||
res = read(fd, read_buf, COMMON_BUFSIZE);
|
||||
if (res < 0)
|
||||
retval = EXIT_FAILURE;
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
|
||||
|
||||
//usage:#define chown_trivial_usage
|
||||
//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... OWNER[<.|:>[GROUP]] FILE..."
|
||||
//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..."
|
||||
//usage:#define chown_full_usage "\n\n"
|
||||
//usage: "Change the owner and/or group of each FILE to OWNER and/or GROUP\n"
|
||||
//usage: "Change the owner and/or group of each FILE to USER and/or GRP\n"
|
||||
//usage: "\n -R Recurse"
|
||||
//usage: "\n -h Affect symlinks instead of symlink targets"
|
||||
//usage: IF_DESKTOP(
|
||||
|
@ -112,10 +112,6 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
|
|||
int opt, flags;
|
||||
struct param_t param;
|
||||
|
||||
/* Just -1 might not work: uid_t may be unsigned long */
|
||||
param.ugid.uid = -1L;
|
||||
param.ugid.gid = -1L;
|
||||
|
||||
#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS
|
||||
applet_long_options = chown_longopts;
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
//usage: "Calculate the CRC32 checksums of FILES"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
/* This is a NOEXEC applet. Be very careful! */
|
||||
|
||||
|
@ -32,6 +33,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
|
|||
argv++;
|
||||
#endif
|
||||
|
||||
setup_common_bufsiz();
|
||||
do {
|
||||
int fd = open_or_warn_stdin(*argv ? *argv : bb_msg_standard_input);
|
||||
|
||||
|
@ -43,7 +45,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
|
|||
length = 0;
|
||||
|
||||
#define read_buf bb_common_bufsiz1
|
||||
while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) {
|
||||
while ((bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE)) > 0) {
|
||||
length += bytes_read;
|
||||
crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
//usage: "\n -f Overwrite"
|
||||
//usage: "\n -i Prompt before overwrite"
|
||||
//usage: "\n -l,-s Create (sym)links"
|
||||
//usage: "\n -u Copy only newer files"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "libcoreutils/coreutils.h"
|
||||
|
@ -49,12 +50,10 @@ int cp_main(int argc, char **argv)
|
|||
int flags;
|
||||
int status;
|
||||
enum {
|
||||
OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1),
|
||||
OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),
|
||||
OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),
|
||||
OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),
|
||||
FILEUTILS_CP_OPTNUM = sizeof(FILEUTILS_CP_OPTSTR)-1,
|
||||
#if ENABLE_FEATURE_CP_LONG_OPTIONS
|
||||
OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
|
||||
/*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */
|
||||
OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -76,10 +75,12 @@ int cp_main(int argc, char **argv)
|
|||
"recursive\0" No_argument "R"
|
||||
"symbolic-link\0" No_argument "s"
|
||||
"verbose\0" No_argument "v"
|
||||
"parents\0" No_argument "\xff"
|
||||
"update\0" No_argument "u"
|
||||
"remove-destination\0" No_argument "\xff"
|
||||
"parents\0" No_argument "\xfe"
|
||||
;
|
||||
#endif
|
||||
flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv");
|
||||
flags = getopt32(argv, FILEUTILS_CP_OPTSTR);
|
||||
/* Options of cp from GNU coreutils 6.10:
|
||||
* -a, --archive
|
||||
* -f, --force
|
||||
|
@ -94,6 +95,11 @@ int cp_main(int argc, char **argv)
|
|||
* -d same as --no-dereference --preserve=links
|
||||
* -p same as --preserve=mode,ownership,timestamps
|
||||
* -c same as --preserve=context
|
||||
* -u, --update
|
||||
* copy only when the SOURCE file is newer than the destination
|
||||
* file or when the destination file is missing
|
||||
* --remove-destination
|
||||
* remove each existing destination file before attempting to open
|
||||
* --parents
|
||||
* use full source file name under DIRECTORY
|
||||
* NOT SUPPORTED IN BBOX:
|
||||
|
@ -106,8 +112,6 @@ int cp_main(int argc, char **argv)
|
|||
* preserve attributes (default: mode,ownership,timestamps),
|
||||
* if possible additional attributes: security context,links,all
|
||||
* --no-preserve=ATTR_LIST
|
||||
* --remove-destination
|
||||
* remove each existing destination file before attempting to open
|
||||
* --sparse=WHEN
|
||||
* control creation of sparse files
|
||||
* --strip-trailing-slashes
|
||||
|
@ -118,9 +122,6 @@ int cp_main(int argc, char **argv)
|
|||
* copy all SOURCE arguments into DIRECTORY
|
||||
* -T, --no-target-directory
|
||||
* treat DEST as a normal file
|
||||
* -u, --update
|
||||
* copy only when the SOURCE file is newer than the destination
|
||||
* file or when the destination file is missing
|
||||
* -x, --one-file-system
|
||||
* stay on this file system
|
||||
* -Z, --context=CONTEXT
|
||||
|
@ -156,11 +157,16 @@ int cp_main(int argc, char **argv)
|
|||
return EXIT_FAILURE;
|
||||
|
||||
#if ENABLE_FEATURE_CP_LONG_OPTIONS
|
||||
//bb_error_msg("flags:%x FILEUTILS_RMDEST:%x OPT_parents:%x",
|
||||
// flags, FILEUTILS_RMDEST, OPT_parents);
|
||||
if (flags & OPT_parents) {
|
||||
if (!(d_flags & 2)) {
|
||||
bb_error_msg_and_die("with --parents, the destination must be a directory");
|
||||
}
|
||||
}
|
||||
if (flags & FILEUTILS_RMDEST) {
|
||||
flags |= FILEUTILS_FORCE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ...if neither is a directory... */
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
//usage: "Wed Apr 12 18:52:41 MDT 2000\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#if ENABLE_FEATURE_DATE_NANO
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
@ -368,6 +369,7 @@ int date_main(int argc UNUSED_PARAM, char **argv)
|
|||
#endif
|
||||
|
||||
#define date_buf bb_common_bufsiz1
|
||||
setup_common_bufsiz();
|
||||
if (*fmt_dt2str == '\0') {
|
||||
/* With no format string, just print a blank line */
|
||||
date_buf[0] = '\0';
|
||||
|
@ -377,7 +379,7 @@ int date_main(int argc UNUSED_PARAM, char **argv)
|
|||
fmt_dt2str = (char*)"%Y.%m.%d-%H:%M:%S";
|
||||
}
|
||||
/* Generate output string */
|
||||
strftime(date_buf, sizeof(date_buf), fmt_dt2str, &tm_time);
|
||||
strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time);
|
||||
}
|
||||
puts(date_buf);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
//usage:#define dd_trivial_usage
|
||||
//usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n"
|
||||
//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]")
|
||||
//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]")
|
||||
//usage:#define dd_full_usage "\n\n"
|
||||
//usage: "Copy a file with converting and formatting\n"
|
||||
//usage: "\n if=FILE Read from FILE instead of stdin"
|
||||
|
@ -76,6 +76,7 @@
|
|||
//usage: "\n conv=sync Pad blocks with zeros"
|
||||
//usage: "\n conv=fsync Physically write data out before finishing"
|
||||
//usage: "\n conv=swab Swap every pair of bytes"
|
||||
//usage: "\n iflag=skip_bytes skip=N is in bytes"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_DD_STATUS(
|
||||
//usage: "\n status=noxfer Suppress rate output"
|
||||
|
@ -90,6 +91,7 @@
|
|||
//usage: "4+0 records out\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
/* This is a NOEXEC applet. Be very careful! */
|
||||
|
||||
|
@ -107,8 +109,9 @@ struct globals {
|
|||
#endif
|
||||
int flags;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
/* we have to zero it out because of NOEXEC */ \
|
||||
memset(&G, 0, sizeof(G)); \
|
||||
} while (0)
|
||||
|
@ -122,11 +125,15 @@ enum {
|
|||
FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS,
|
||||
FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS,
|
||||
/* end of conv flags */
|
||||
FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
|
||||
FLAG_COUNT = 1 << 6,
|
||||
FLAG_STATUS = 1 << 7,
|
||||
FLAG_STATUS_NONE = 1 << 7,
|
||||
FLAG_STATUS_NOXFER = 1 << 8,
|
||||
/* start of input flags */
|
||||
FLAG_IFLAG_SHIFT = 5,
|
||||
FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
|
||||
/* end of input flags */
|
||||
FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
|
||||
FLAG_COUNT = 1 << 7,
|
||||
FLAG_STATUS = 1 << 8,
|
||||
FLAG_STATUS_NONE = 1 << 9,
|
||||
FLAG_STATUS_NOXFER = 1 << 10,
|
||||
};
|
||||
|
||||
static void dd_output_status(int UNUSED_PARAM cur_signal)
|
||||
|
@ -203,18 +210,47 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
|
|||
# define XATOU_SFX xatoul_sfx
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_DD_IBS_OBS
|
||||
static int parse_comma_flags(char *val, const char *words, const char *error_in)
|
||||
{
|
||||
int flags = 0;
|
||||
while (1) {
|
||||
int n;
|
||||
char *arg;
|
||||
/* find ',', replace them with NUL so we can use val for
|
||||
* index_in_strings() without copying.
|
||||
* We rely on val being non-null, else strchr would fault.
|
||||
*/
|
||||
arg = strchr(val, ',');
|
||||
if (arg)
|
||||
*arg = '\0';
|
||||
n = index_in_strings(words, val);
|
||||
if (n < 0)
|
||||
bb_error_msg_and_die(bb_msg_invalid_arg_to, val, error_in);
|
||||
flags |= (1 << n);
|
||||
if (!arg) /* no ',' left, so this was the last specifier */
|
||||
break;
|
||||
*arg = ','; /* to preserve ps listing */
|
||||
val = arg + 1; /* skip this keyword and ',' */
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int dd_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
static const char keywords[] ALIGN1 =
|
||||
"bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0")
|
||||
#if ENABLE_FEATURE_DD_IBS_OBS
|
||||
"ibs\0""obs\0""conv\0"
|
||||
"ibs\0""obs\0""conv\0""iflag\0"
|
||||
#endif
|
||||
;
|
||||
#if ENABLE_FEATURE_DD_IBS_OBS
|
||||
static const char conv_words[] ALIGN1 =
|
||||
"notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
|
||||
static const char iflag_words[] ALIGN1 =
|
||||
"skip_bytes\0";
|
||||
#endif
|
||||
#if ENABLE_FEATURE_DD_STATUS
|
||||
static const char status_words[] ALIGN1 =
|
||||
|
@ -232,6 +268,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
|
|||
OP_ibs,
|
||||
OP_obs,
|
||||
OP_conv,
|
||||
OP_iflag,
|
||||
/* Must be in the same order as FLAG_XXX! */
|
||||
OP_conv_notrunc = 0,
|
||||
OP_conv_sync,
|
||||
|
@ -251,6 +288,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
|
|||
//ibm from ASCII to alternate EBCDIC
|
||||
/* Partially implemented: */
|
||||
//swab swap every pair of input bytes: will abort on non-even reads
|
||||
OP_iflag_skip_bytes,
|
||||
#endif
|
||||
};
|
||||
smallint exitcode = EXIT_FAILURE;
|
||||
|
@ -315,24 +353,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
|
|||
/*continue;*/
|
||||
}
|
||||
if (what == OP_conv) {
|
||||
while (1) {
|
||||
int n;
|
||||
/* find ',', replace them with NUL so we can use val for
|
||||
* index_in_strings() without copying.
|
||||
* We rely on val being non-null, else strchr would fault.
|
||||
*/
|
||||
arg = strchr(val, ',');
|
||||
if (arg)
|
||||
*arg = '\0';
|
||||
n = index_in_strings(conv_words, val);
|
||||
if (n < 0)
|
||||
bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv");
|
||||
G.flags |= (1 << n);
|
||||
if (!arg) /* no ',' left, so this was the last specifier */
|
||||
break;
|
||||
/* *arg = ','; - to preserve ps listing? */
|
||||
val = arg + 1; /* skip this keyword and ',' */
|
||||
}
|
||||
G.flags |= parse_comma_flags(val, conv_words, "conv");
|
||||
/*continue;*/
|
||||
}
|
||||
if (what == OP_iflag) {
|
||||
G.flags |= parse_comma_flags(val, iflag_words, "iflag") << FLAG_IFLAG_SHIFT;
|
||||
/*continue;*/
|
||||
}
|
||||
#endif
|
||||
|
@ -368,7 +393,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
|
|||
int n;
|
||||
n = index_in_strings(status_words, val);
|
||||
if (n < 0)
|
||||
bb_error_msg_and_die(bb_msg_invalid_arg, val, "status");
|
||||
bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "status");
|
||||
G.flags |= FLAG_STATUS << n;
|
||||
/*continue;*/
|
||||
}
|
||||
|
@ -421,9 +446,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
|
|||
outfile = bb_msg_standard_output;
|
||||
}
|
||||
if (skip) {
|
||||
if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
|
||||
size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs;
|
||||
if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) {
|
||||
do {
|
||||
ssize_t n = safe_read(ifd, ibuf, ibs);
|
||||
ssize_t n = safe_read(ifd, ibuf, blocksz);
|
||||
if (n < 0)
|
||||
goto die_infile;
|
||||
if (n == 0)
|
||||
|
|
|
@ -41,7 +41,7 @@ enum {
|
|||
static void convert(char *fn, int conv_type)
|
||||
{
|
||||
FILE *in, *out;
|
||||
int i;
|
||||
int ch;
|
||||
char *temp_fn = temp_fn; /* for compiler */
|
||||
char *resolved_fn = resolved_fn;
|
||||
|
||||
|
@ -49,28 +49,30 @@ static void convert(char *fn, int conv_type)
|
|||
out = stdout;
|
||||
if (fn != NULL) {
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
resolved_fn = xmalloc_follow_symlinks(fn);
|
||||
if (resolved_fn == NULL)
|
||||
bb_simple_perror_msg_and_die(fn);
|
||||
in = xfopen_for_read(resolved_fn);
|
||||
fstat(fileno(in), &st);
|
||||
xfstat(fileno(in), &st, resolved_fn);
|
||||
|
||||
temp_fn = xasprintf("%sXXXXXX", resolved_fn);
|
||||
i = xmkstemp(temp_fn);
|
||||
if (fchmod(i, st.st_mode) == -1)
|
||||
fd = xmkstemp(temp_fn);
|
||||
if (fchmod(fd, st.st_mode) == -1)
|
||||
bb_simple_perror_msg_and_die(temp_fn);
|
||||
fchown(fd, st.st_uid, st.st_gid);
|
||||
|
||||
out = xfdopen_for_write(i);
|
||||
out = xfdopen_for_write(fd);
|
||||
}
|
||||
|
||||
while ((i = fgetc(in)) != EOF) {
|
||||
if (i == '\r')
|
||||
while ((ch = fgetc(in)) != EOF) {
|
||||
if (ch == '\r')
|
||||
continue;
|
||||
if (i == '\n')
|
||||
if (ch == '\n')
|
||||
if (conv_type == CT_UNIX2DOS)
|
||||
fputc('\r', out);
|
||||
fputc(i, out);
|
||||
fputc(ch, out);
|
||||
}
|
||||
|
||||
if (fn != NULL) {
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
//usage: "2417 .\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
enum {
|
||||
OPT_a_files_too = (1 << 0),
|
||||
|
@ -75,7 +76,7 @@ enum {
|
|||
|
||||
struct globals {
|
||||
#if ENABLE_FEATURE_HUMAN_READABLE
|
||||
unsigned long disp_hr;
|
||||
unsigned long disp_unit;
|
||||
#else
|
||||
unsigned disp_k;
|
||||
#endif
|
||||
|
@ -85,22 +86,31 @@ struct globals {
|
|||
int du_depth;
|
||||
dev_t dir_dev;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define INIT_G() do { } while (0)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
|
||||
/* FIXME? coreutils' du rounds sizes up:
|
||||
* for example, 1025k file is shown as "2" by du -m.
|
||||
* We round to nearest.
|
||||
*/
|
||||
static void print(unsigned long long size, const char *filename)
|
||||
{
|
||||
/* TODO - May not want to defer error checking here. */
|
||||
#if ENABLE_FEATURE_HUMAN_READABLE
|
||||
# if ENABLE_DESKTOP
|
||||
/* ~30 bytes of code for extra comtat:
|
||||
* coreutils' du rounds sizes up:
|
||||
* for example, 1025k file is shown as "2" by du -m.
|
||||
* We round to nearest if human-readable [too hard to fix],
|
||||
* else (fixed scale such as -m), we round up. To that end,
|
||||
* add yet another half of the unit before displaying:
|
||||
*/
|
||||
if (G.disp_unit)
|
||||
size += (G.disp_unit-1) / (unsigned)(512 * 2);
|
||||
# endif
|
||||
printf("%s\t%s\n",
|
||||
/* size x 512 / G.disp_hr, show one fractional,
|
||||
* use suffixes if G.disp_hr == 0 */
|
||||
make_human_readable_str(size, 512, G.disp_hr),
|
||||
/* size x 512 / G.disp_unit.
|
||||
* If G.disp_unit == 0, show one fractional
|
||||
* and use suffixes
|
||||
*/
|
||||
make_human_readable_str(size, 512, G.disp_unit),
|
||||
filename);
|
||||
#else
|
||||
if (G.disp_k) {
|
||||
|
@ -199,10 +209,10 @@ int du_main(int argc UNUSED_PARAM, char **argv)
|
|||
INIT_G();
|
||||
|
||||
#if ENABLE_FEATURE_HUMAN_READABLE
|
||||
IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;)
|
||||
IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;)
|
||||
IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 1024;)
|
||||
IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 512;)
|
||||
if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
|
||||
G.disp_hr = 512;
|
||||
G.disp_unit = 512;
|
||||
#else
|
||||
IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)
|
||||
/* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */
|
||||
|
@ -220,13 +230,13 @@ int du_main(int argc UNUSED_PARAM, char **argv)
|
|||
opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
|
||||
argv += optind;
|
||||
if (opt & OPT_h_for_humans) {
|
||||
G.disp_hr = 0;
|
||||
G.disp_unit = 0;
|
||||
}
|
||||
if (opt & OPT_m_mbytes) {
|
||||
G.disp_hr = 1024*1024;
|
||||
G.disp_unit = 1024*1024;
|
||||
}
|
||||
if (opt & OPT_k_kbytes) {
|
||||
G.disp_hr = 1024;
|
||||
G.disp_unit = 1024;
|
||||
}
|
||||
#else
|
||||
opt_complementary = "H-L:L-H:s-d:d-s:d+";
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
//usage: "of characters matched or 0."
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "xregex.h"
|
||||
|
||||
#if ENABLE_EXPR_MATH_SUPPORT_64
|
||||
|
@ -99,8 +100,8 @@ typedef struct valinfo VALUE;
|
|||
struct globals {
|
||||
char **args;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define INIT_G() do { } while (0)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
/* forward declarations */
|
||||
static VALUE *eval(void);
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
//usage: )
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "unicode.h"
|
||||
|
||||
|
||||
|
@ -365,8 +366,9 @@ struct globals {
|
|||
time_t current_time_t;
|
||||
#endif
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
/* we have to zero it out because of NOEXEC */ \
|
||||
memset(&G, 0, sizeof(G)); \
|
||||
IF_FEATURE_AUTOWIDTH(G_terminal_width = TERMINAL_WIDTH;) \
|
||||
|
@ -668,7 +670,7 @@ static void display_files(struct dnode **dn, unsigned nfiles)
|
|||
if (column_width < len)
|
||||
column_width = len;
|
||||
}
|
||||
column_width += 1 +
|
||||
column_width += 2 +
|
||||
IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + )
|
||||
((G.all_fmt & LIST_INO) ? 8 : 0) +
|
||||
((G.all_fmt & LIST_BLOCKS) ? 5 : 0);
|
||||
|
@ -696,8 +698,8 @@ static void display_files(struct dnode **dn, unsigned nfiles)
|
|||
if (i < nfiles) {
|
||||
if (column > 0) {
|
||||
nexttab -= column;
|
||||
printf("%*s ", nexttab, "");
|
||||
column += nexttab + 1;
|
||||
printf("%*s", nexttab, "");
|
||||
column += nexttab;
|
||||
}
|
||||
nexttab = column + column_width;
|
||||
column += display_single(dn[i]);
|
||||
|
@ -1105,7 +1107,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
|||
|
||||
#if ENABLE_FEATURE_AUTOWIDTH
|
||||
/* obtain the terminal width */
|
||||
get_terminal_width_height(STDIN_FILENO, &G_terminal_width, NULL);
|
||||
G_terminal_width = get_terminal_width(STDIN_FILENO);
|
||||
/* go one less... */
|
||||
G_terminal_width--;
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
|
||||
/* #include "libbb.h" - done in od.c */
|
||||
#include "common_bufsiz.h"
|
||||
#define assert(a) ((void)0)
|
||||
|
||||
|
||||
|
@ -66,7 +67,7 @@ enum {
|
|||
/* -S was -s and also had optional parameter */ \
|
||||
/* but in coreutils 6.3 it was renamed and now has */ \
|
||||
/* _mandatory_ parameter */ \
|
||||
&str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block)
|
||||
&str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block)
|
||||
|
||||
|
||||
/* Check for 0x7f is a coreutils 6.3 addition */
|
||||
|
@ -174,38 +175,53 @@ struct ERR_width_bytes_has_bad_size {
|
|||
char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1];
|
||||
};
|
||||
|
||||
static smallint exit_code;
|
||||
struct globals {
|
||||
smallint exit_code;
|
||||
|
||||
static unsigned string_min;
|
||||
unsigned string_min;
|
||||
|
||||
/* An array of specs describing how to format each input block. */
|
||||
static size_t n_specs;
|
||||
static struct tspec *spec;
|
||||
/* An array of specs describing how to format each input block. */
|
||||
unsigned n_specs;
|
||||
struct tspec *spec;
|
||||
|
||||
/* Function that accepts an address and an optional following char,
|
||||
and prints the address and char to stdout. */
|
||||
static void (*format_address)(off_t, char);
|
||||
/* The difference between the old-style pseudo starting address and
|
||||
the number of bytes to skip. */
|
||||
/* Function that accepts an address and an optional following char,
|
||||
and prints the address and char to stdout. */
|
||||
void (*format_address)(off_t, char);
|
||||
|
||||
/* The difference between the old-style pseudo starting address and
|
||||
the number of bytes to skip. */
|
||||
#if ENABLE_LONG_OPTS
|
||||
static off_t pseudo_offset;
|
||||
#else
|
||||
enum { pseudo_offset = 0 };
|
||||
off_t pseudo_offset;
|
||||
# define G_pseudo_offset G.pseudo_offset
|
||||
#endif
|
||||
/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
|
||||
input is formatted. */
|
||||
/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
|
||||
input is formatted. */
|
||||
|
||||
/* The number of input bytes formatted per output line. It must be
|
||||
a multiple of the least common multiple of the sizes associated with
|
||||
the specified output types. It should be as large as possible, but
|
||||
no larger than 16 -- unless specified with the -w option. */
|
||||
static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */
|
||||
/* The number of input bytes formatted per output line. It must be
|
||||
a multiple of the least common multiple of the sizes associated with
|
||||
the specified output types. It should be as large as possible, but
|
||||
no larger than 16 -- unless specified with the -w option. */
|
||||
unsigned bytes_per_block; /* have to use unsigned, not size_t */
|
||||
|
||||
/* A NULL-terminated list of the file-arguments from the command line. */
|
||||
static const char *const *file_list;
|
||||
/* A NULL-terminated list of the file-arguments from the command line. */
|
||||
const char *const *file_list;
|
||||
|
||||
/* The input stream associated with the current file. */
|
||||
FILE *in_stream;
|
||||
|
||||
bool not_first;
|
||||
bool prev_pair_equal;
|
||||
} FIX_ALIASING;
|
||||
#if !ENABLE_LONG_OPTS
|
||||
enum { G_pseudo_offset = 0 };
|
||||
#endif
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
|
||||
G.bytes_per_block = 32; \
|
||||
} while (0)
|
||||
|
||||
/* The input stream associated with the current file. */
|
||||
static FILE *in_stream;
|
||||
|
||||
#define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
|
||||
static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {
|
||||
|
@ -476,17 +492,17 @@ static void
|
|||
open_next_file(void)
|
||||
{
|
||||
while (1) {
|
||||
if (!*file_list)
|
||||
if (!*G.file_list)
|
||||
return;
|
||||
in_stream = fopen_or_warn_stdin(*file_list++);
|
||||
if (in_stream) {
|
||||
G.in_stream = fopen_or_warn_stdin(*G.file_list++);
|
||||
if (G.in_stream) {
|
||||
break;
|
||||
}
|
||||
exit_code = 1;
|
||||
G.exit_code = 1;
|
||||
}
|
||||
|
||||
if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
|
||||
setbuf(in_stream, NULL);
|
||||
setbuf(G.in_stream, NULL);
|
||||
}
|
||||
|
||||
/* Test whether there have been errors on in_stream, and close it if
|
||||
|
@ -499,16 +515,16 @@ open_next_file(void)
|
|||
static void
|
||||
check_and_close(void)
|
||||
{
|
||||
if (in_stream) {
|
||||
if (ferror(in_stream)) {
|
||||
bb_error_msg("%s: read error", (in_stream == stdin)
|
||||
if (G.in_stream) {
|
||||
if (ferror(G.in_stream)) {
|
||||
bb_error_msg("%s: read error", (G.in_stream == stdin)
|
||||
? bb_msg_standard_input
|
||||
: file_list[-1]
|
||||
: G.file_list[-1]
|
||||
);
|
||||
exit_code = 1;
|
||||
G.exit_code = 1;
|
||||
}
|
||||
fclose_if_not_stdin(in_stream);
|
||||
in_stream = NULL;
|
||||
fclose_if_not_stdin(G.in_stream);
|
||||
G.in_stream = NULL;
|
||||
}
|
||||
|
||||
if (ferror(stdout)) {
|
||||
|
@ -744,9 +760,9 @@ decode_format_string(const char *s)
|
|||
|
||||
assert(s != next);
|
||||
s = next;
|
||||
spec = xrealloc_vector(spec, 4, n_specs);
|
||||
memcpy(&spec[n_specs], &tspec, sizeof(spec[0]));
|
||||
n_specs++;
|
||||
G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
|
||||
memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
|
||||
G.n_specs++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,7 +779,7 @@ skip(off_t n_skip)
|
|||
if (n_skip == 0)
|
||||
return;
|
||||
|
||||
while (in_stream) { /* !EOF */
|
||||
while (G.in_stream) { /* !EOF */
|
||||
struct stat file_stats;
|
||||
|
||||
/* First try seeking. For large offsets, this extra work is
|
||||
|
@ -781,15 +797,15 @@ skip(off_t n_skip)
|
|||
If the number of bytes left to skip is at least
|
||||
as large as the size of the current file, we can
|
||||
decrement n_skip and go on to the next file. */
|
||||
if (fstat(fileno(in_stream), &file_stats) == 0
|
||||
if (fstat(fileno(G.in_stream), &file_stats) == 0
|
||||
&& S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
|
||||
) {
|
||||
if (file_stats.st_size < n_skip) {
|
||||
n_skip -= file_stats.st_size;
|
||||
/* take "check & close / open_next" route */
|
||||
} else {
|
||||
if (fseeko(in_stream, n_skip, SEEK_CUR) != 0)
|
||||
exit_code = 1;
|
||||
if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
|
||||
G.exit_code = 1;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -802,7 +818,7 @@ skip(off_t n_skip)
|
|||
while (n_skip > 0) {
|
||||
if (n_skip < n_bytes_to_read)
|
||||
n_bytes_to_read = n_skip;
|
||||
n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream);
|
||||
n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
|
||||
n_skip -= n_bytes_read;
|
||||
if (n_bytes_read != n_bytes_to_read)
|
||||
break; /* EOF on this file or error */
|
||||
|
@ -855,7 +871,7 @@ static void
|
|||
format_address_label(off_t address, char c)
|
||||
{
|
||||
format_address_std(address, ' ');
|
||||
format_address_paren(address + pseudo_offset, c);
|
||||
format_address_paren(address + G_pseudo_offset, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -886,36 +902,34 @@ static void
|
|||
write_block(off_t current_offset, size_t n_bytes,
|
||||
const char *prev_block, const char *curr_block)
|
||||
{
|
||||
static char first = 1;
|
||||
static char prev_pair_equal = 0;
|
||||
size_t i;
|
||||
unsigned i;
|
||||
|
||||
if (!(option_mask32 & OPT_v)
|
||||
&& !first
|
||||
&& n_bytes == bytes_per_block
|
||||
&& memcmp(prev_block, curr_block, bytes_per_block) == 0
|
||||
&& G.not_first
|
||||
&& n_bytes == G.bytes_per_block
|
||||
&& memcmp(prev_block, curr_block, G.bytes_per_block) == 0
|
||||
) {
|
||||
if (prev_pair_equal) {
|
||||
if (G.prev_pair_equal) {
|
||||
/* The two preceding blocks were equal, and the current
|
||||
block is the same as the last one, so print nothing. */
|
||||
} else {
|
||||
puts("*");
|
||||
prev_pair_equal = 1;
|
||||
G.prev_pair_equal = 1;
|
||||
}
|
||||
} else {
|
||||
first = 0;
|
||||
prev_pair_equal = 0;
|
||||
for (i = 0; i < n_specs; i++) {
|
||||
G.not_first = 1;
|
||||
G.prev_pair_equal = 0;
|
||||
for (i = 0; i < G.n_specs; i++) {
|
||||
if (i == 0)
|
||||
format_address(current_offset, '\0');
|
||||
G.format_address(current_offset, '\0');
|
||||
else
|
||||
printf("%*s", address_pad_len_char - '0', "");
|
||||
(*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
|
||||
if (spec[i].hexl_mode_trailer) {
|
||||
(*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
|
||||
if (G.spec[i].hexl_mode_trailer) {
|
||||
/* space-pad out to full line width, then dump the trailer */
|
||||
unsigned datum_width = width_bytes[spec[i].size];
|
||||
unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width;
|
||||
unsigned field_width = spec[i].field_width + 1;
|
||||
unsigned datum_width = width_bytes[G.spec[i].size];
|
||||
unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
|
||||
unsigned field_width = G.spec[i].field_width + 1;
|
||||
printf("%*s", blank_fields * field_width, "");
|
||||
dump_hexl_mode_trailer(n_bytes, curr_block);
|
||||
}
|
||||
|
@ -927,19 +941,19 @@ write_block(off_t current_offset, size_t n_bytes,
|
|||
static void
|
||||
read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
|
||||
{
|
||||
assert(0 < n && n <= bytes_per_block);
|
||||
assert(0 < n && n <= G.bytes_per_block);
|
||||
|
||||
*n_bytes_in_buffer = 0;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
while (in_stream != NULL) { /* EOF. */
|
||||
while (G.in_stream != NULL) { /* EOF. */
|
||||
size_t n_needed;
|
||||
size_t n_read;
|
||||
|
||||
n_needed = n - *n_bytes_in_buffer;
|
||||
n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream);
|
||||
n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
|
||||
*n_bytes_in_buffer += n_read;
|
||||
if (n_read == n_needed)
|
||||
break;
|
||||
|
@ -958,8 +972,8 @@ get_lcm(void)
|
|||
size_t i;
|
||||
int l_c_m = 1;
|
||||
|
||||
for (i = 0; i < n_specs; i++)
|
||||
l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]);
|
||||
for (i = 0; i < G.n_specs; i++)
|
||||
l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
|
||||
return l_c_m;
|
||||
}
|
||||
|
||||
|
@ -980,8 +994,8 @@ dump(off_t current_offset, off_t end_offset)
|
|||
int idx;
|
||||
size_t n_bytes_read;
|
||||
|
||||
block[0] = xmalloc(2 * bytes_per_block);
|
||||
block[1] = block[0] + bytes_per_block;
|
||||
block[0] = xmalloc(2 * G.bytes_per_block);
|
||||
block[1] = block[0] + G.bytes_per_block;
|
||||
|
||||
idx = 0;
|
||||
if (option_mask32 & OPT_N) {
|
||||
|
@ -991,21 +1005,21 @@ dump(off_t current_offset, off_t end_offset)
|
|||
n_bytes_read = 0;
|
||||
break;
|
||||
}
|
||||
n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block);
|
||||
n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
|
||||
read_block(n_needed, block[idx], &n_bytes_read);
|
||||
if (n_bytes_read < bytes_per_block)
|
||||
if (n_bytes_read < G.bytes_per_block)
|
||||
break;
|
||||
assert(n_bytes_read == bytes_per_block);
|
||||
assert(n_bytes_read == G.bytes_per_block);
|
||||
write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
|
||||
current_offset += n_bytes_read;
|
||||
idx ^= 1;
|
||||
}
|
||||
} else {
|
||||
while (1) {
|
||||
read_block(bytes_per_block, block[idx], &n_bytes_read);
|
||||
if (n_bytes_read < bytes_per_block)
|
||||
read_block(G.bytes_per_block, block[idx], &n_bytes_read);
|
||||
if (n_bytes_read < G.bytes_per_block)
|
||||
break;
|
||||
assert(n_bytes_read == bytes_per_block);
|
||||
assert(n_bytes_read == G.bytes_per_block);
|
||||
write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
|
||||
current_offset += n_bytes_read;
|
||||
idx ^= 1;
|
||||
|
@ -1028,7 +1042,7 @@ dump(off_t current_offset, off_t end_offset)
|
|||
current_offset += n_bytes_read;
|
||||
}
|
||||
|
||||
format_address(current_offset, '\n');
|
||||
G.format_address(current_offset, '\n');
|
||||
|
||||
if ((option_mask32 & OPT_N) && current_offset >= end_offset)
|
||||
check_and_close();
|
||||
|
@ -1059,16 +1073,16 @@ dump(off_t current_offset, off_t end_offset)
|
|||
static void
|
||||
dump_strings(off_t address, off_t end_offset)
|
||||
{
|
||||
unsigned bufsize = MAX(100, string_min);
|
||||
unsigned bufsize = MAX(100, G.string_min);
|
||||
unsigned char *buf = xmalloc(bufsize);
|
||||
|
||||
while (1) {
|
||||
size_t i;
|
||||
int c;
|
||||
|
||||
/* See if the next 'string_min' chars are all printing chars. */
|
||||
/* See if the next 'G.string_min' chars are all printing chars. */
|
||||
tryline:
|
||||
if ((option_mask32 & OPT_N) && (end_offset - string_min <= address))
|
||||
if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
|
||||
break;
|
||||
i = 0;
|
||||
while (!(option_mask32 & OPT_N) || address < end_offset) {
|
||||
|
@ -1077,8 +1091,8 @@ dump_strings(off_t address, off_t end_offset)
|
|||
buf = xrealloc(buf, bufsize);
|
||||
}
|
||||
|
||||
while (in_stream) { /* !EOF */
|
||||
c = fgetc(in_stream);
|
||||
while (G.in_stream) { /* !EOF */
|
||||
c = fgetc(G.in_stream);
|
||||
if (c != EOF)
|
||||
goto got_char;
|
||||
check_and_close();
|
||||
|
@ -1095,12 +1109,12 @@ dump_strings(off_t address, off_t end_offset)
|
|||
buf[i++] = c; /* String continues; store it all. */
|
||||
}
|
||||
|
||||
if (i < string_min) /* Too short! */
|
||||
if (i < G.string_min) /* Too short! */
|
||||
goto tryline;
|
||||
|
||||
/* If we get here, the string is all printable and NUL-terminated */
|
||||
buf[i] = 0;
|
||||
format_address(address - i - 1, ' ');
|
||||
G.format_address(address - i - 1, ' ');
|
||||
|
||||
for (i = 0; (c = buf[i]); i++) {
|
||||
switch (c) {
|
||||
|
@ -1118,7 +1132,7 @@ dump_strings(off_t address, off_t end_offset)
|
|||
}
|
||||
|
||||
/* We reach this point only if we search through
|
||||
(max_bytes_to_format - string_min) bytes before reaching EOF. */
|
||||
(max_bytes_to_format - G.string_min) bytes before reaching EOF. */
|
||||
check_and_close();
|
||||
ret:
|
||||
free(buf);
|
||||
|
@ -1190,8 +1204,10 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
/* The maximum number of bytes that will be formatted. */
|
||||
off_t max_bytes_to_format = 0;
|
||||
|
||||
spec = NULL;
|
||||
format_address = format_address_std;
|
||||
INIT_G();
|
||||
|
||||
/*G.spec = NULL; - already is */
|
||||
G.format_address = format_address_std;
|
||||
address_base_char = 'o';
|
||||
address_pad_len_char = '7';
|
||||
|
||||
|
@ -1217,7 +1233,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
bb_error_msg_and_die("bad output address radix "
|
||||
"'%c' (must be [doxn])", str_A[0]);
|
||||
pos = p - doxn;
|
||||
if (pos == 3) format_address = format_address_none;
|
||||
if (pos == 3) G.format_address = format_address_none;
|
||||
address_base_char = doxn_address_base_char[pos];
|
||||
address_pad_len_char = doxn_address_pad_len_char[pos];
|
||||
}
|
||||
|
@ -1240,11 +1256,11 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
if (opt & OPT_x) decode_format_string("x2");
|
||||
if (opt & OPT_s) decode_format_string("d2");
|
||||
if (opt & OPT_S) {
|
||||
string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
|
||||
G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
|
||||
}
|
||||
|
||||
// Bloat:
|
||||
//if ((option_mask32 & OPT_S) && n_specs > 0)
|
||||
//if ((option_mask32 & OPT_S) && G.n_specs > 0)
|
||||
// bb_error_msg_and_die("no type may be specified when dumping strings");
|
||||
|
||||
/* If the --traditional option is used, there may be from
|
||||
|
@ -1300,14 +1316,14 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
}
|
||||
|
||||
if (pseudo_start >= 0) {
|
||||
if (format_address == format_address_none) {
|
||||
if (G.format_address == format_address_none) {
|
||||
address_base_char = 'o';
|
||||
address_pad_len_char = '7';
|
||||
format_address = format_address_paren;
|
||||
G.format_address = format_address_paren;
|
||||
} else {
|
||||
format_address = format_address_label;
|
||||
G.format_address = format_address_label;
|
||||
}
|
||||
pseudo_offset = pseudo_start - n_bytes_to_skip;
|
||||
G_pseudo_offset = pseudo_start - n_bytes_to_skip;
|
||||
}
|
||||
}
|
||||
/* else: od --traditional (without args) */
|
||||
|
@ -1320,45 +1336,45 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
bb_error_msg_and_die("SKIP + SIZE is too large");
|
||||
}
|
||||
|
||||
if (n_specs == 0) {
|
||||
if (G.n_specs == 0) {
|
||||
decode_format_string("o2");
|
||||
/*n_specs = 1; - done by decode_format_string */
|
||||
/*G.n_specs = 1; - done by decode_format_string */
|
||||
}
|
||||
|
||||
/* If no files were listed on the command line,
|
||||
set the global pointer FILE_LIST so that it
|
||||
references the null-terminated list of one name: "-". */
|
||||
file_list = bb_argv_dash;
|
||||
G.file_list = bb_argv_dash;
|
||||
if (argv[0]) {
|
||||
/* Set the global pointer FILE_LIST so that it
|
||||
references the first file-argument on the command-line. */
|
||||
file_list = (char const *const *) argv;
|
||||
G.file_list = (char const *const *) argv;
|
||||
}
|
||||
|
||||
/* Open the first input file */
|
||||
open_next_file();
|
||||
/* Skip over any unwanted header bytes */
|
||||
skip(n_bytes_to_skip);
|
||||
if (!in_stream)
|
||||
if (!G.in_stream)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* Compute output block length */
|
||||
l_c_m = get_lcm();
|
||||
|
||||
if (opt & OPT_w) { /* -w: width */
|
||||
if (!bytes_per_block || bytes_per_block % l_c_m != 0) {
|
||||
if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) {
|
||||
bb_error_msg("warning: invalid width %u; using %d instead",
|
||||
(unsigned)bytes_per_block, l_c_m);
|
||||
bytes_per_block = l_c_m;
|
||||
(unsigned)G.bytes_per_block, l_c_m);
|
||||
G.bytes_per_block = l_c_m;
|
||||
}
|
||||
} else {
|
||||
bytes_per_block = l_c_m;
|
||||
G.bytes_per_block = l_c_m;
|
||||
if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
|
||||
bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
|
||||
G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < n_specs; i++) {
|
||||
for (i = 0; i < G.n_specs; i++) {
|
||||
printf("%d: fmt=\"%s\" width=%d\n",
|
||||
i, spec[i].fmt_string, width_bytes[spec[i].size]);
|
||||
}
|
||||
|
@ -1372,5 +1388,5 @@ int od_main(int argc UNUSED_PARAM, char **argv)
|
|||
if (fclose(stdin))
|
||||
bb_perror_msg_and_die(bb_msg_standard_input);
|
||||
|
||||
return exit_code;
|
||||
return G.exit_code;
|
||||
}
|
||||
|
|
|
@ -131,8 +131,8 @@ static double my_xstrtod(const char *arg)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Handles %b */
|
||||
static void print_esc_string(const char *str)
|
||||
/* Handles %b; return 1 if output is to be short-circuited by \c */
|
||||
static int print_esc_string(const char *str)
|
||||
{
|
||||
char c;
|
||||
while ((c = *str) != '\0') {
|
||||
|
@ -145,6 +145,9 @@ static void print_esc_string(const char *str)
|
|||
str++;
|
||||
}
|
||||
}
|
||||
else if (*str == 'c') {
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
/* optimization: don't force arg to be on-stack,
|
||||
* use another variable for that. */
|
||||
|
@ -155,6 +158,8 @@ static void print_esc_string(const char *str)
|
|||
}
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_direc(char *format, unsigned fmt_length,
|
||||
|
@ -280,7 +285,8 @@ static char **print_formatted(char *f, char **argv, int *conv_err)
|
|||
}
|
||||
if (*f == 'b') {
|
||||
if (*argv) {
|
||||
print_esc_string(*argv);
|
||||
if (print_esc_string(*argv))
|
||||
return saved_argv; /* causes main() to exit */
|
||||
++argv;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -14,23 +14,23 @@
|
|||
|
||||
//usage:#define sort_trivial_usage
|
||||
//usage: "[-nru"
|
||||
//usage: IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR")
|
||||
//usage: IF_FEATURE_SORT_BIG("gMcszbdfiokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR")
|
||||
//usage: "] [FILE]..."
|
||||
//usage:#define sort_full_usage "\n\n"
|
||||
//usage: "Sort lines of text\n"
|
||||
//usage: IF_FEATURE_SORT_BIG(
|
||||
//usage: "\n -b Ignore leading blanks"
|
||||
//usage: "\n -o FILE Output to FILE"
|
||||
//usage: "\n -c Check whether input is sorted"
|
||||
//usage: "\n -d Dictionary order (blank or alphanumeric only)"
|
||||
//usage: "\n -b Ignore leading blanks"
|
||||
//usage: "\n -f Ignore case"
|
||||
//usage: "\n -g General numerical sort"
|
||||
//usage: "\n -i Ignore unprintable characters"
|
||||
//usage: "\n -d Dictionary order (blank or alphanumeric only)"
|
||||
//usage: "\n -g General numerical sort"
|
||||
//usage: "\n -M Sort month"
|
||||
//usage: )
|
||||
//-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G)
|
||||
//usage: "\n -n Sort numbers"
|
||||
//usage: IF_FEATURE_SORT_BIG(
|
||||
//usage: "\n -o Output to file"
|
||||
//usage: "\n -t CHAR Field separator"
|
||||
//usage: "\n -k N[,M] Sort by Nth field"
|
||||
//usage: )
|
||||
|
@ -41,7 +41,10 @@
|
|||
//usage: "\n -u Suppress duplicate lines"
|
||||
//usage: IF_FEATURE_SORT_BIG(
|
||||
//usage: "\n -z Lines are terminated by NUL, not newline"
|
||||
//usage: "\n -mST Ignored for GNU compatibility")
|
||||
////usage: "\n -m Ignored for GNU compatibility"
|
||||
////usage: "\n -S BUFSZ Ignored for GNU compatibility"
|
||||
////usage: "\n -T TMPDIR Ignored for GNU compatibility"
|
||||
//usage: )
|
||||
//usage:
|
||||
//usage:#define sort_example_usage
|
||||
//usage: "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n"
|
||||
|
@ -106,7 +109,9 @@ static struct sort_key {
|
|||
|
||||
static char *get_key(char *str, struct sort_key *key, int flags)
|
||||
{
|
||||
int start = 0, end = 0, len, j;
|
||||
int start = start; /* for compiler */
|
||||
int end;
|
||||
int len, j;
|
||||
unsigned i;
|
||||
|
||||
/* Special case whole string, so we don't have to make a copy */
|
||||
|
@ -123,12 +128,15 @@ static char *get_key(char *str, struct sort_key *key, int flags)
|
|||
end = len;
|
||||
/* Loop through fields */
|
||||
else {
|
||||
unsigned char ch = 0;
|
||||
|
||||
end = 0;
|
||||
for (i = 1; i < key->range[2*j] + j; i++) {
|
||||
if (key_separator) {
|
||||
/* Skip body of key and separator */
|
||||
while (str[end]) {
|
||||
if (str[end++] == key_separator)
|
||||
while ((ch = str[end]) != '\0') {
|
||||
end++;
|
||||
if (ch == key_separator)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -136,7 +144,7 @@ static char *get_key(char *str, struct sort_key *key, int flags)
|
|||
while (isspace(str[end]))
|
||||
end++;
|
||||
/* Skip body of key */
|
||||
while (str[end]) {
|
||||
while (str[end] != '\0') {
|
||||
if (isspace(str[end]))
|
||||
break;
|
||||
end++;
|
||||
|
@ -144,23 +152,29 @@ static char *get_key(char *str, struct sort_key *key, int flags)
|
|||
}
|
||||
}
|
||||
/* Remove last delim: "abc:def:" => "abc:def" */
|
||||
if (key_separator && j && end != 0)
|
||||
if (j && ch) {
|
||||
//if (str[end-1] != key_separator)
|
||||
// bb_error_msg(_and_die("BUG! "
|
||||
// "str[start:%d,end:%d]:'%.*s'",
|
||||
// start, end, (int)(end-start), &str[start]);
|
||||
end--;
|
||||
}
|
||||
}
|
||||
if (!j) start = end;
|
||||
}
|
||||
/* Strip leading whitespace if necessary */
|
||||
//XXX: skip_whitespace()
|
||||
if (flags & FLAG_b)
|
||||
/* not using skip_whitespace() for speed */
|
||||
while (isspace(str[start])) start++;
|
||||
/* Strip trailing whitespace if necessary */
|
||||
if (flags & FLAG_bb)
|
||||
while (end > start && isspace(str[end-1])) end--;
|
||||
/* Handle offsets on start and end */
|
||||
/* -kSTART,N.ENDCHAR: honor ENDCHAR (1-based) */
|
||||
if (key->range[3]) {
|
||||
end += key->range[3] - 1;
|
||||
end = key->range[3];
|
||||
if (end > len) end = len;
|
||||
}
|
||||
/* -kN.STARTCHAR[,...]: honor STARTCHAR (1-based) */
|
||||
if (key->range[1]) {
|
||||
start += key->range[1] - 1;
|
||||
if (start > len) start = len;
|
||||
|
@ -281,7 +295,7 @@ static int compare_keys(const void *xarg, const void *yarg)
|
|||
else if (!yy)
|
||||
retval = 1;
|
||||
else
|
||||
retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon;
|
||||
retval = dx - thyme.tm_mon;
|
||||
break;
|
||||
}
|
||||
/* Full floating point version of -n */
|
||||
|
@ -307,8 +321,8 @@ static int compare_keys(const void *xarg, const void *yarg)
|
|||
|
||||
/* Perform fallback sort if necessary */
|
||||
if (!retval && !(option_mask32 & FLAG_s)) {
|
||||
retval = strcmp(*(char **)xarg, *(char **)yarg);
|
||||
flags = option_mask32;
|
||||
retval = strcmp(*(char **)xarg, *(char **)yarg);
|
||||
}
|
||||
|
||||
if (flags & FLAG_r)
|
||||
|
@ -336,7 +350,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
char *line, **lines;
|
||||
char *str_ignored, *str_o, *str_t;
|
||||
llist_t *lst_k = NULL;
|
||||
int i, flag;
|
||||
int i;
|
||||
int linecount;
|
||||
unsigned opts;
|
||||
|
||||
|
@ -359,7 +373,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
/* note: below this point we use option_mask32, not opts,
|
||||
* since that reduces register pressure and makes code smaller */
|
||||
|
||||
/* parse sort key */
|
||||
/* Parse sort key */
|
||||
while (lst_k) {
|
||||
enum {
|
||||
FLAG_allowed_for_k =
|
||||
|
@ -386,17 +400,18 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
key->range[2*i+1] = str2u(&str_k);
|
||||
}
|
||||
while (*str_k) {
|
||||
const char *temp2;
|
||||
int flag;
|
||||
const char *idx;
|
||||
|
||||
if (*str_k == ',' && !i++) {
|
||||
str_k++;
|
||||
break;
|
||||
} /* no else needed: fall through to syntax error
|
||||
because comma isn't in OPT_STR */
|
||||
temp2 = strchr(OPT_STR, *str_k);
|
||||
if (!temp2)
|
||||
idx = strchr(OPT_STR, *str_k);
|
||||
if (!idx)
|
||||
bb_error_msg_and_die("unknown key option");
|
||||
flag = 1 << (temp2 - OPT_STR);
|
||||
flag = 1 << (idx - OPT_STR);
|
||||
if (flag & ~FLAG_allowed_for_k)
|
||||
bb_error_msg_and_die("unknown sort type");
|
||||
/* b after ',' means strip _trailing_ space */
|
||||
|
@ -430,10 +445,10 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
} while (*++argv);
|
||||
|
||||
#if ENABLE_FEATURE_SORT_BIG
|
||||
/* if no key, perform alphabetic sort */
|
||||
/* If no key, perform alphabetic sort */
|
||||
if (!key_list)
|
||||
add_key()->range[0] = 1;
|
||||
/* handle -c */
|
||||
/* Handle -c */
|
||||
if (option_mask32 & FLAG_c) {
|
||||
int j = (option_mask32 & FLAG_u) ? -1 : 0;
|
||||
for (i = 1; i < linecount; i++) {
|
||||
|
@ -447,20 +462,21 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
#endif
|
||||
/* Perform the actual sort */
|
||||
qsort(lines, linecount, sizeof(lines[0]), compare_keys);
|
||||
/* handle -u */
|
||||
|
||||
/* Handle -u */
|
||||
if (option_mask32 & FLAG_u) {
|
||||
flag = 0;
|
||||
int j = 0;
|
||||
/* coreutils 6.3 drop lines for which only key is the same */
|
||||
/* -- disabling last-resort compare... */
|
||||
option_mask32 |= FLAG_s;
|
||||
for (i = 1; i < linecount; i++) {
|
||||
if (compare_keys(&lines[flag], &lines[i]) == 0)
|
||||
if (compare_keys(&lines[j], &lines[i]) == 0)
|
||||
free(lines[i]);
|
||||
else
|
||||
lines[++flag] = lines[i];
|
||||
lines[++j] = lines[i];
|
||||
}
|
||||
if (linecount)
|
||||
linecount = flag+1;
|
||||
linecount = j+1;
|
||||
}
|
||||
|
||||
/* Print it */
|
||||
|
@ -469,9 +485,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
|
|||
if (option_mask32 & FLAG_o)
|
||||
xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO);
|
||||
#endif
|
||||
flag = (option_mask32 & FLAG_z) ? '\0' : '\n';
|
||||
for (i = 0; i < linecount; i++)
|
||||
printf("%s%c", lines[i], flag);
|
||||
{
|
||||
int ch = (option_mask32 & FLAG_z) ? '\0' : '\n';
|
||||
for (i = 0; i < linecount; i++)
|
||||
printf("%s%c", lines[i], ch);
|
||||
}
|
||||
|
||||
fflush_stdout_and_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//usage: "$ cat TODO | split -a 2 -l 2 TODO_\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#if ENABLE_FEATURE_SPLIT_FANCY
|
||||
static const struct suffix_mult split_suffixes[] = {
|
||||
|
@ -78,6 +79,8 @@ int split_main(int argc UNUSED_PARAM, char **argv)
|
|||
ssize_t bytes_read, to_write;
|
||||
char *src;
|
||||
|
||||
setup_common_bufsiz();
|
||||
|
||||
opt_complementary = "?2:a+"; /* max 2 args; -a N */
|
||||
opt = getopt32(argv, "l:b:a:", &count_p, &count_p, &suffix_len);
|
||||
|
||||
|
|
|
@ -12,54 +12,83 @@
|
|||
*
|
||||
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||
*/
|
||||
//config:config STAT
|
||||
//config: bool "stat"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: display file or filesystem status.
|
||||
//config:
|
||||
//config:config FEATURE_STAT_FORMAT
|
||||
//config: bool "Enable custom formats (-c)"
|
||||
//config: default y
|
||||
//config: depends on STAT
|
||||
//config: help
|
||||
//config: Without this, stat will not support the '-c format' option where
|
||||
//config: users can pass a custom format string for output. This adds about
|
||||
//config: 7k to a nonstatic build on amd64.
|
||||
//config:
|
||||
//config:config FEATURE_STAT_FILESYSTEM
|
||||
//config: bool "Enable display of filesystem status (-f)"
|
||||
//config: default y
|
||||
//config: depends on STAT
|
||||
//config: select PLATFORM_LINUX # statfs()
|
||||
//config: help
|
||||
//config: Without this, stat will not support the '-f' option to display
|
||||
//config: information about filesystem status.
|
||||
|
||||
|
||||
//usage:#define stat_trivial_usage
|
||||
//usage: "[OPTIONS] FILE..."
|
||||
//usage:#define stat_full_usage "\n\n"
|
||||
//usage: "Display file (default) or filesystem status\n"
|
||||
//usage: "Display file"
|
||||
//usage: IF_FEATURE_STAT_FILESYSTEM(" (default) or filesystem")
|
||||
//usage: " status\n"
|
||||
//usage: IF_FEATURE_STAT_FORMAT(
|
||||
//usage: "\n -c fmt Use the specified format"
|
||||
//usage: "\n -c FMT Use the specified format"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_STAT_FILESYSTEM(
|
||||
//usage: "\n -f Display filesystem status"
|
||||
//usage: )
|
||||
//usage: "\n -L Follow links"
|
||||
//usage: "\n -t Display info in terse form"
|
||||
//usage: "\n -t Terse display"
|
||||
//usage: IF_SELINUX(
|
||||
//usage: "\n -Z Print security context"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_STAT_FORMAT(
|
||||
//usage: "\n\nValid format sequences for files:\n"
|
||||
//usage: "\n\nFMT sequences"IF_FEATURE_STAT_FILESYSTEM(" for files")":\n"
|
||||
//usage: " %a Access rights in octal\n"
|
||||
//usage: " %A Access rights in human readable form\n"
|
||||
//usage: " %b Number of blocks allocated (see %B)\n"
|
||||
//usage: " %B The size in bytes of each block reported by %b\n"
|
||||
//usage: " %B Size in bytes of each block reported by %b\n"
|
||||
//usage: " %d Device number in decimal\n"
|
||||
//usage: " %D Device number in hex\n"
|
||||
//usage: " %f Raw mode in hex\n"
|
||||
//usage: " %F File type\n"
|
||||
//usage: " %g Group ID of owner\n"
|
||||
//usage: " %G Group name of owner\n"
|
||||
//usage: " %g Group ID\n"
|
||||
//usage: " %G Group name\n"
|
||||
//usage: " %h Number of hard links\n"
|
||||
//usage: " %i Inode number\n"
|
||||
//usage: " %n File name\n"
|
||||
//usage: " %N File name, with -> TARGET if symlink\n"
|
||||
//usage: " %o I/O block size\n"
|
||||
//usage: " %s Total size, in bytes\n"
|
||||
//usage: " %s Total size in bytes\n"
|
||||
//usage: " %t Major device type in hex\n"
|
||||
//usage: " %T Minor device type in hex\n"
|
||||
//usage: " %u User ID of owner\n"
|
||||
//usage: " %U User name of owner\n"
|
||||
//usage: " %u User ID\n"
|
||||
//usage: " %U User name\n"
|
||||
//usage: " %x Time of last access\n"
|
||||
//usage: " %X Time of last access as seconds since Epoch\n"
|
||||
//usage: " %y Time of last modification\n"
|
||||
//usage: " %Y Time of last modification as seconds since Epoch\n"
|
||||
//usage: " %z Time of last change\n"
|
||||
//usage: " %Z Time of last change as seconds since Epoch\n"
|
||||
//usage: "\nValid format sequences for file systems:\n"
|
||||
//usage: IF_FEATURE_STAT_FILESYSTEM(
|
||||
//usage: "\nFMT sequences for file systems:\n"
|
||||
//usage: " %a Free blocks available to non-superuser\n"
|
||||
//usage: " %b Total data blocks in file system\n"
|
||||
//usage: " %c Total file nodes in file system\n"
|
||||
//usage: " %d Free file nodes in file system\n"
|
||||
//usage: " %f Free blocks in file system\n"
|
||||
//usage: " %b Total data blocks\n"
|
||||
//usage: " %c Total file nodes\n"
|
||||
//usage: " %d Free file nodes\n"
|
||||
//usage: " %f Free blocks\n"
|
||||
//usage: IF_SELINUX(
|
||||
//usage: " %C Security context in selinux\n"
|
||||
//usage: )
|
||||
|
@ -71,13 +100,17 @@
|
|||
//usage: " %t Type in hex\n"
|
||||
//usage: " %T Type in human readable form"
|
||||
//usage: )
|
||||
//usage: )
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#define OPT_FILESYS (1 << 0)
|
||||
#define OPT_TERSE (1 << 1)
|
||||
#define OPT_DEREFERENCE (1 << 2)
|
||||
#define OPT_SELINUX (1 << 3)
|
||||
enum {
|
||||
OPT_TERSE = (1 << 0),
|
||||
OPT_DEREFERENCE = (1 << 1),
|
||||
OPT_FILESYS = (1 << 2) * ENABLE_FEATURE_STAT_FILESYSTEM,
|
||||
OPT_SELINUX = (1 << (2+ENABLE_FEATURE_STAT_FILESYSTEM)) * ENABLE_SELINUX,
|
||||
};
|
||||
|
||||
#if ENABLE_FEATURE_STAT_FORMAT
|
||||
typedef bool (*statfunc_ptr)(const char *, const char *);
|
||||
|
@ -126,12 +159,13 @@ static const char *human_time(time_t t)
|
|||
|
||||
/*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/
|
||||
#define buf bb_common_bufsiz1
|
||||
|
||||
strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &t), ".000000000");
|
||||
setup_common_bufsiz();
|
||||
strcpy(strftime_YYYYMMDDHHMMSS(buf, COMMON_BUFSIZE, &t), ".000000000");
|
||||
return buf;
|
||||
#undef buf
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_STAT_FILESYSTEM
|
||||
/* Return the type of the specified file system.
|
||||
* Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
|
||||
* Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
|
||||
|
@ -202,6 +236,7 @@ static unsigned long long get_f_fsid(const struct statfs *statfsbuf)
|
|||
while (--sz > 0);
|
||||
return r;
|
||||
}
|
||||
#endif /* FEATURE_STAT_FILESYSTEM */
|
||||
|
||||
#if ENABLE_FEATURE_STAT_FORMAT
|
||||
static void strcatc(char *str, char c)
|
||||
|
@ -217,6 +252,7 @@ static void printfs(char *pformat, const char *msg)
|
|||
printf(pformat, msg);
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_STAT_FILESYSTEM
|
||||
/* print statfs info */
|
||||
static void FAST_FUNC print_statfs(char *pformat, const char m,
|
||||
const char *const filename, const void *data
|
||||
|
@ -263,6 +299,7 @@ static void FAST_FUNC print_statfs(char *pformat, const char m,
|
|||
printf(pformat, m);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* print stat info */
|
||||
static void FAST_FUNC print_stat(char *pformat, const char m,
|
||||
|
@ -423,6 +460,7 @@ static void print_it(const char *masterformat,
|
|||
}
|
||||
#endif /* FEATURE_STAT_FORMAT */
|
||||
|
||||
#if ENABLE_FEATURE_STAT_FILESYSTEM
|
||||
/* Stat the file system and print what we find. */
|
||||
#if !ENABLE_FEATURE_STAT_FORMAT
|
||||
#define do_statfs(filename, format) do_statfs(filename)
|
||||
|
@ -538,6 +576,7 @@ static bool do_statfs(const char *filename, const char *format)
|
|||
#endif /* FEATURE_STAT_FORMAT */
|
||||
return 1;
|
||||
}
|
||||
#endif /* FEATURE_STAT_FILESYSTEM */
|
||||
|
||||
/* stat the file and print what we find */
|
||||
#if !ENABLE_FEATURE_STAT_FORMAT
|
||||
|
@ -721,12 +760,15 @@ int stat_main(int argc UNUSED_PARAM, char **argv)
|
|||
statfunc_ptr statfunc = do_stat;
|
||||
|
||||
opt_complementary = "-1"; /* min one arg */
|
||||
opts = getopt32(argv, "ftL"
|
||||
opts = getopt32(argv, "tL"
|
||||
IF_FEATURE_STAT_FILESYSTEM("f")
|
||||
IF_SELINUX("Z")
|
||||
IF_FEATURE_STAT_FORMAT("c:", &format)
|
||||
);
|
||||
#if ENABLE_FEATURE_STAT_FILESYSTEM
|
||||
if (opts & OPT_FILESYS) /* -f */
|
||||
statfunc = do_statfs;
|
||||
#endif
|
||||
#if ENABLE_SELINUX
|
||||
if (opts & OPT_SELINUX) {
|
||||
selinux_or_die();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
//usage: "\n [SETTING] See manpage"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#ifndef _POSIX_VDISABLE
|
||||
# define _POSIX_VDISABLE ((unsigned char) 0)
|
||||
|
@ -317,7 +318,7 @@ enum {
|
|||
#define MI_ENTRY(N,T,F,B,M) N "\0"
|
||||
|
||||
/* Mode names given on command line */
|
||||
static const char mode_name[] =
|
||||
static const char mode_name[] ALIGN1 =
|
||||
MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
|
||||
MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
|
||||
MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
|
||||
|
@ -680,7 +681,7 @@ enum {
|
|||
#define CI_ENTRY(n,s,o) n "\0"
|
||||
|
||||
/* Name given on command line */
|
||||
static const char control_name[] =
|
||||
static const char control_name[] ALIGN1 =
|
||||
CI_ENTRY("intr", CINTR, VINTR )
|
||||
CI_ENTRY("quit", CQUIT, VQUIT )
|
||||
CI_ENTRY("erase", CERASE, VERASE )
|
||||
|
@ -722,7 +723,7 @@ static const char control_name[] =
|
|||
#undef CI_ENTRY
|
||||
#define CI_ENTRY(n,s,o) { s, o },
|
||||
|
||||
static const struct control_info control_info[] = {
|
||||
static const struct control_info control_info[] ALIGN2 = {
|
||||
/* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */
|
||||
CI_ENTRY("intr", CINTR, VINTR )
|
||||
CI_ENTRY("quit", CQUIT, VQUIT )
|
||||
|
@ -775,7 +776,7 @@ struct globals {
|
|||
unsigned current_col;
|
||||
char buf[10];
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
G.device_name = bb_msg_standard_input; \
|
||||
G.max_col = 80; \
|
||||
|
@ -1403,7 +1404,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
|
|||
perror_on_device_and_die("%s");
|
||||
|
||||
if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
|
||||
get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
|
||||
G.max_col = get_terminal_width(STDOUT_FILENO);
|
||||
output_func(&mode, display_all);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
//usage: "\n -s Use System V sum algorithm (512byte blocks)"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
|
||||
|
||||
|
@ -30,18 +31,20 @@ enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
|
|||
/* Return 1 if successful. */
|
||||
static unsigned sum_file(const char *file, unsigned type)
|
||||
{
|
||||
#define buf bb_common_bufsiz1
|
||||
unsigned long long total_bytes = 0;
|
||||
int fd, r;
|
||||
/* The sum of all the input bytes, modulo (UINT_MAX + 1). */
|
||||
unsigned s = 0;
|
||||
|
||||
#define buf bb_common_bufsiz1
|
||||
setup_common_bufsiz();
|
||||
|
||||
fd = open_or_warn_stdin(file);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
size_t bytes_read = safe_read(fd, buf, BUFSIZ);
|
||||
size_t bytes_read = safe_read(fd, buf, COMMON_BUFSIZE);
|
||||
|
||||
if ((ssize_t)bytes_read <= 0) {
|
||||
r = (fd && close(fd) != 0);
|
||||
|
|
|
@ -49,13 +49,14 @@
|
|||
//usage: "nameserver 10.0.0.1\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
struct globals {
|
||||
bool from_top;
|
||||
bool exitcode;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define INIT_G() do { } while (0)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
static void tail_xprint_header(const char *fmt, const char *filename)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
//usage: "Hello\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
int tee_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int tee_main(int argc, char **argv)
|
||||
|
@ -37,6 +38,7 @@ int tee_main(int argc, char **argv)
|
|||
#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
|
||||
ssize_t c;
|
||||
# define buf bb_common_bufsiz1
|
||||
setup_common_bufsiz();
|
||||
#else
|
||||
int c;
|
||||
#endif
|
||||
|
@ -79,7 +81,7 @@ int tee_main(int argc, char **argv)
|
|||
/* names[0] will be filled later */
|
||||
|
||||
#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
|
||||
while ((c = safe_read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
|
||||
while ((c = safe_read(STDIN_FILENO, buf, COMMON_BUFSIZE)) > 0) {
|
||||
fp = files;
|
||||
do
|
||||
fwrite(buf, 1, c, *fp);
|
||||
|
|
|
@ -91,7 +91,6 @@ static void map(char *pvector,
|
|||
* Character classes, e.g. [:upper:] ==> A...Z
|
||||
* Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?)
|
||||
* not supported:
|
||||
* \ooo-\ooo - octal ranges
|
||||
* [x*N] - repeat char x N times
|
||||
* [x*] - repeat char x until it fills STRING2:
|
||||
* # echo qwe123 | /usr/bin/tr 123456789 '[d]'
|
||||
|
@ -99,7 +98,7 @@ static void map(char *pvector,
|
|||
* # echo qwe123 | /usr/bin/tr 123456789 '[d*]'
|
||||
* qweddd
|
||||
*/
|
||||
static unsigned expand(const char *arg, char **buffer_p)
|
||||
static unsigned expand(char *arg, char **buffer_p)
|
||||
{
|
||||
char *buffer = *buffer_p;
|
||||
unsigned pos = 0;
|
||||
|
@ -113,9 +112,17 @@ static unsigned expand(const char *arg, char **buffer_p)
|
|||
*buffer_p = buffer = xrealloc(buffer, size);
|
||||
}
|
||||
if (*arg == '\\') {
|
||||
const char *z;
|
||||
arg++;
|
||||
buffer[pos++] = bb_process_escape_sequence(&arg);
|
||||
continue;
|
||||
z = arg;
|
||||
ac = bb_process_escape_sequence(&z);
|
||||
arg = (char *)z;
|
||||
arg--;
|
||||
*arg = ac;
|
||||
/*
|
||||
* fall through, there may be a range.
|
||||
* If not, current char will be treated anyway.
|
||||
*/
|
||||
}
|
||||
if (arg[1] == '-') { /* "0-9..." */
|
||||
ac = arg[2];
|
||||
|
@ -124,9 +131,15 @@ static unsigned expand(const char *arg, char **buffer_p)
|
|||
continue; /* next iter will copy '-' and stop */
|
||||
}
|
||||
i = (unsigned char) *arg;
|
||||
arg += 3; /* skip 0-9 or 0-\ */
|
||||
if (ac == '\\') {
|
||||
const char *z;
|
||||
z = arg;
|
||||
ac = bb_process_escape_sequence(&z);
|
||||
arg = (char *)z;
|
||||
}
|
||||
while (i <= ac) /* ok: i is unsigned _int_ */
|
||||
buffer[pos++] = i++;
|
||||
arg += 3; /* skip 0-9 */
|
||||
continue;
|
||||
}
|
||||
if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV)
|
||||
|
|
|
@ -40,7 +40,7 @@ int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||
int truncate_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
unsigned opts;
|
||||
int flags = O_RDWR;
|
||||
int flags = O_WRONLY | O_NONBLOCK;
|
||||
int ret = EXIT_SUCCESS;
|
||||
char *size_str;
|
||||
off_t size;
|
||||
|
@ -64,7 +64,7 @@ int truncate_main(int argc UNUSED_PARAM, char **argv)
|
|||
|
||||
argv += optind;
|
||||
while (*argv) {
|
||||
int fd = open(*argv, flags);
|
||||
int fd = open(*argv, flags, 0666);
|
||||
if (fd < 0) {
|
||||
if (errno != ENOENT || !(opts & OPT_NOCREATE)) {
|
||||
bb_perror_msg("%s: open", *argv);
|
||||
|
|
|
@ -7,79 +7,4 @@ menu "Debian Utilities"
|
|||
|
||||
INSERT
|
||||
|
||||
config MKTEMP
|
||||
bool "mktemp"
|
||||
default y
|
||||
help
|
||||
mktemp is used to create unique temporary files
|
||||
|
||||
config PIPE_PROGRESS
|
||||
bool "pipe_progress"
|
||||
default y
|
||||
help
|
||||
Display a dot to indicate pipe activity.
|
||||
|
||||
config RUN_PARTS
|
||||
bool "run-parts"
|
||||
default y
|
||||
help
|
||||
run-parts is a utility designed to run all the scripts in a directory.
|
||||
|
||||
It is useful to set up a directory like cron.daily, where you need to
|
||||
execute all the scripts in that directory.
|
||||
|
||||
In this implementation of run-parts some features (such as report
|
||||
mode) are not implemented.
|
||||
|
||||
Unless you know that run-parts is used in some of your scripts
|
||||
you can safely say N here.
|
||||
|
||||
config FEATURE_RUN_PARTS_LONG_OPTIONS
|
||||
bool "Enable long options"
|
||||
default y
|
||||
depends on RUN_PARTS && LONG_OPTS
|
||||
help
|
||||
Support long options for the run-parts applet.
|
||||
|
||||
config FEATURE_RUN_PARTS_FANCY
|
||||
bool "Support additional arguments"
|
||||
default y
|
||||
depends on RUN_PARTS
|
||||
help
|
||||
Support additional options:
|
||||
-l --list print the names of the all matching files (not
|
||||
limited to executables), but don't actually run them.
|
||||
|
||||
config START_STOP_DAEMON
|
||||
bool "start-stop-daemon"
|
||||
default y
|
||||
help
|
||||
start-stop-daemon is used to control the creation and
|
||||
termination of system-level processes, usually the ones
|
||||
started during the startup of the system.
|
||||
|
||||
config FEATURE_START_STOP_DAEMON_FANCY
|
||||
bool "Support additional arguments"
|
||||
default y
|
||||
depends on START_STOP_DAEMON
|
||||
help
|
||||
Support additional arguments.
|
||||
-o|--oknodo ignored since we exit with 0 anyway
|
||||
-v|--verbose
|
||||
-N|--nicelevel N
|
||||
|
||||
config FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
||||
bool "Enable long options"
|
||||
default y
|
||||
depends on START_STOP_DAEMON && LONG_OPTS
|
||||
help
|
||||
Support long options for the start-stop-daemon applet.
|
||||
|
||||
config WHICH
|
||||
bool "which"
|
||||
default y
|
||||
help
|
||||
which is used to find programs in your PATH and
|
||||
print out their pathnames.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -7,8 +7,3 @@
|
|||
lib-y:=
|
||||
|
||||
INSERT
|
||||
lib-$(CONFIG_MKTEMP) += mktemp.o
|
||||
lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o
|
||||
lib-$(CONFIG_RUN_PARTS) += run_parts.o
|
||||
lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
|
||||
lib-$(CONFIG_WHICH) += which.o
|
||||
|
|
|
@ -30,6 +30,15 @@
|
|||
* a directory: $TMPDIR, if set; else the directory specified via
|
||||
* -p; else /tmp [deprecated]
|
||||
*/
|
||||
//config:config MKTEMP
|
||||
//config: bool "mktemp"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: mktemp is used to create unique temporary files
|
||||
|
||||
//applet:IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o
|
||||
|
||||
//usage:#define mktemp_trivial_usage
|
||||
//usage: "[-dt] [-p DIR] [TEMPLATE]"
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
*
|
||||
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||
*/
|
||||
//config:config PIPE_PROGRESS
|
||||
//config: bool "pipe_progress"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: Display a dot to indicate pipe activity.
|
||||
|
||||
//applet:IF_PIPE_PROGRESS(APPLET(pipe_progress, BB_DIR_BIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o
|
||||
|
||||
//usage:#define pipe_progress_trivial_usage NOUSAGE_STR
|
||||
//usage:#define pipe_progress_full_usage ""
|
||||
|
|
|
@ -22,6 +22,40 @@
|
|||
* report mode. As the original run-parts support only long options, I've
|
||||
* broken compatibility because the BusyBox policy doesn't allow them.
|
||||
*/
|
||||
//config:config RUN_PARTS
|
||||
//config: bool "run-parts"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: run-parts is a utility designed to run all the scripts in a directory.
|
||||
//config:
|
||||
//config: It is useful to set up a directory like cron.daily, where you need to
|
||||
//config: execute all the scripts in that directory.
|
||||
//config:
|
||||
//config: In this implementation of run-parts some features (such as report
|
||||
//config: mode) are not implemented.
|
||||
//config:
|
||||
//config: Unless you know that run-parts is used in some of your scripts
|
||||
//config: you can safely say N here.
|
||||
//config:
|
||||
//config:config FEATURE_RUN_PARTS_LONG_OPTIONS
|
||||
//config: bool "Enable long options"
|
||||
//config: default y
|
||||
//config: depends on RUN_PARTS && LONG_OPTS
|
||||
//config: help
|
||||
//config: Support long options for the run-parts applet.
|
||||
//config:
|
||||
//config:config FEATURE_RUN_PARTS_FANCY
|
||||
//config: bool "Support additional arguments"
|
||||
//config: default y
|
||||
//config: depends on RUN_PARTS
|
||||
//config: help
|
||||
//config: Support additional options:
|
||||
//config: -l --list print the names of the all matching files (not
|
||||
//config: limited to executables), but don't actually run them.
|
||||
|
||||
//applet:IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts))
|
||||
|
||||
//kbuild:lib-$(CONFIG_RUN_PARTS) += run_parts.o
|
||||
|
||||
//usage:#define run_parts_trivial_usage
|
||||
//usage: "[-a ARG]... [-u UMASK] "
|
||||
|
@ -55,17 +89,18 @@
|
|||
//usage: "+ shutdown -h +4m"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
struct globals {
|
||||
char **names;
|
||||
int cur;
|
||||
char *cmd[2 /* using 1 provokes compiler warning */];
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define names (G.names)
|
||||
#define cur (G.cur )
|
||||
#define cmd (G.cmd )
|
||||
#define INIT_G() do { } while (0)
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 };
|
||||
|
||||
|
|
|
@ -56,6 +56,34 @@ Misc options:
|
|||
-q,--quiet Quiet
|
||||
-v,--verbose Verbose
|
||||
*/
|
||||
//config:config START_STOP_DAEMON
|
||||
//config: bool "start-stop-daemon"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: start-stop-daemon is used to control the creation and
|
||||
//config: termination of system-level processes, usually the ones
|
||||
//config: started during the startup of the system.
|
||||
//config:
|
||||
//config:config FEATURE_START_STOP_DAEMON_FANCY
|
||||
//config: bool "Support additional arguments"
|
||||
//config: default y
|
||||
//config: depends on START_STOP_DAEMON
|
||||
//config: help
|
||||
//config: Support additional arguments.
|
||||
//config: -o|--oknodo ignored since we exit with 0 anyway
|
||||
//config: -v|--verbose
|
||||
//config: -N|--nicelevel N
|
||||
//config:
|
||||
//config:config FEATURE_START_STOP_DAEMON_LONG_OPTIONS
|
||||
//config: bool "Enable long options"
|
||||
//config: default y
|
||||
//config: depends on START_STOP_DAEMON && LONG_OPTS
|
||||
//config: help
|
||||
//config: Support long options for the start-stop-daemon applet.
|
||||
|
||||
//applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon))
|
||||
|
||||
//kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
|
||||
|
||||
//usage:#define start_stop_daemon_trivial_usage
|
||||
//usage: "[OPTIONS] [-S|-K] ... [-- ARGS...]"
|
||||
|
@ -125,6 +153,7 @@ Misc options:
|
|||
/* Override ENABLE_FEATURE_PIDFILE */
|
||||
#define WANT_PIDFILE 1
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
struct pid_list {
|
||||
struct pid_list *next;
|
||||
|
@ -163,7 +192,7 @@ struct globals {
|
|||
int user_id;
|
||||
smallint signal_nr;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define userspec (G.userspec )
|
||||
#define cmdname (G.cmdname )
|
||||
#define execname (G.execname )
|
||||
|
@ -171,6 +200,7 @@ struct globals {
|
|||
#define user_id (G.user_id )
|
||||
#define signal_nr (G.signal_nr )
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
user_id = -1; \
|
||||
signal_nr = 15; \
|
||||
} while (0)
|
||||
|
@ -511,15 +541,15 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
|
|||
write_pidfile(pidfile);
|
||||
}
|
||||
if (opt & OPT_c) {
|
||||
struct bb_uidgid_t ugid = { -1, -1 };
|
||||
struct bb_uidgid_t ugid;
|
||||
parse_chown_usergroup_or_die(&ugid, chuid);
|
||||
if (ugid.uid != (uid_t) -1) {
|
||||
if (ugid.uid != (uid_t) -1L) {
|
||||
struct passwd *pw = xgetpwuid(ugid.uid);
|
||||
if (ugid.gid != (gid_t) -1)
|
||||
if (ugid.gid != (gid_t) -1L)
|
||||
pw->pw_gid = ugid.gid;
|
||||
/* initgroups, setgid, setuid: */
|
||||
change_identity(pw);
|
||||
} else if (ugid.gid != (gid_t) -1) {
|
||||
} else if (ugid.gid != (gid_t) -1L) {
|
||||
xsetgid(ugid.gid);
|
||||
setgroups(1, &ugid.gid);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,16 @@
|
|||
*
|
||||
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
||||
*/
|
||||
//config:config WHICH
|
||||
//config: bool "which"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: which is used to find programs in your PATH and
|
||||
//config: print out their pathnames.
|
||||
|
||||
//applet:IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_WHICH) += which.o
|
||||
|
||||
//usage:#define which_trivial_usage
|
||||
//usage: "[COMMAND]..."
|
||||
|
|
|
@ -178,6 +178,7 @@ dd POSIX options:
|
|||
conv=noerror | yes | |
|
||||
conv=notrunc | yes | |
|
||||
conv=sync | yes | |
|
||||
iflag=skip_bytes| yes | |
|
||||
dd Busybox specific options:
|
||||
conv=fsync
|
||||
|
||||
|
|
|
@ -7,12 +7,6 @@ menu "Linux Ext2 FS Progs"
|
|||
|
||||
INSERT
|
||||
|
||||
config CHATTR
|
||||
bool "chattr"
|
||||
default y
|
||||
help
|
||||
chattr changes the file attributes on a second extended file system.
|
||||
|
||||
### config E2FSCK
|
||||
### bool "e2fsck"
|
||||
### default y
|
||||
|
@ -22,21 +16,6 @@ config CHATTR
|
|||
### The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also
|
||||
### provided.
|
||||
|
||||
config FSCK
|
||||
bool "fsck"
|
||||
default y
|
||||
help
|
||||
fsck is used to check and optionally repair one or more filesystems.
|
||||
In actuality, fsck is simply a front-end for the various file system
|
||||
checkers (fsck.fstype) available under Linux.
|
||||
|
||||
config LSATTR
|
||||
bool "lsattr"
|
||||
default y
|
||||
select PLATFORM_LINUX
|
||||
help
|
||||
lsattr lists the file attributes on a second extended file system.
|
||||
|
||||
### config MKE2FS
|
||||
### bool "mke2fs"
|
||||
### default y
|
||||
|
@ -44,13 +23,6 @@ config LSATTR
|
|||
### mke2fs is used to create an ext2/ext3 filesystem. The normal compat
|
||||
### symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided.
|
||||
|
||||
config TUNE2FS
|
||||
bool "tune2fs"
|
||||
default n # off: it is too limited compared to upstream version
|
||||
help
|
||||
tune2fs allows the system administrator to adjust various tunable
|
||||
filesystem parameters on Linux ext2/ext3 filesystems.
|
||||
|
||||
### config E2LABEL
|
||||
### bool "e2label"
|
||||
### default y
|
||||
|
|
|
@ -7,9 +7,3 @@
|
|||
lib-y:=
|
||||
|
||||
INSERT
|
||||
|
||||
lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o
|
||||
lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o
|
||||
|
||||
lib-$(CONFIG_FSCK) += fsck.o
|
||||
lib-$(CONFIG_TUNE2FS) += tune2fs.o
|
||||
|
|
|
@ -9,24 +9,22 @@
|
|||
* This file can be redistributed under the terms of the GNU General
|
||||
* Public License
|
||||
*/
|
||||
//config:config CHATTR
|
||||
//config: bool "chattr"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: chattr changes the file attributes on a second extended file system.
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
* 93/11/13 - Replace stat() calls by lstat() to avoid loops
|
||||
* 94/02/27 - Integrated in Ted's distribution
|
||||
* 98/12/29 - Ignore symlinks when working recursively (G M Sipe)
|
||||
* 98/12/29 - Display version info only when -V specified (G M Sipe)
|
||||
*/
|
||||
//applet:IF_CHATTR(APPLET(chattr, BB_DIR_BIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o
|
||||
|
||||
//usage:#define chattr_trivial_usage
|
||||
//usage: "[-R] [-+=AacDdijsStTu] [-v VERSION] [FILE]..."
|
||||
//usage:#define chattr_full_usage "\n\n"
|
||||
//usage: "Change file attributes on an ext2 fs\n"
|
||||
//usage: "Change ext2 file attributes\n"
|
||||
//usage: "\nModifiers:"
|
||||
//usage: "\n - Remove attributes"
|
||||
//usage: "\n + Add attributes"
|
||||
//usage: "\n = Set attributes"
|
||||
//usage: "\n -,+,= Remove/add/set attributes"
|
||||
//usage: "\nAttributes:"
|
||||
//usage: "\n A Don't track atime"
|
||||
//usage: "\n a Append mode only"
|
||||
|
@ -36,11 +34,11 @@
|
|||
//usage: "\n i Cannot be modified (immutable)"
|
||||
//usage: "\n j Write all data to journal first"
|
||||
//usage: "\n s Zero disk storage when deleted"
|
||||
//usage: "\n S Write file contents synchronously"
|
||||
//usage: "\n S Write synchronously"
|
||||
//usage: "\n t Disable tail-merging of partial blocks with other files"
|
||||
//usage: "\n u Allow file to be undeleted"
|
||||
//usage: "\n -R Recurse"
|
||||
//usage: "\n -v Set the file's version/generation number"
|
||||
//usage: "\n -v VER Set version/generation number"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "e2fs_lib.h"
|
||||
|
|
|
@ -149,14 +149,14 @@ const uint32_t e2attr_flags_value[] = {
|
|||
EXT2_TOPDIR_FL
|
||||
};
|
||||
|
||||
const char e2attr_flags_sname[] =
|
||||
const char e2attr_flags_sname[] ALIGN1 =
|
||||
#ifdef ENABLE_COMPRESSION
|
||||
"BZXE"
|
||||
#endif
|
||||
"I"
|
||||
"suSDiadAcjtT";
|
||||
|
||||
static const char e2attr_flags_lname[] =
|
||||
static const char e2attr_flags_lname[] ALIGN1 =
|
||||
#ifdef ENABLE_COMPRESSION
|
||||
"Compressed_File" "\0"
|
||||
"Compressed_Dirty_File" "\0"
|
||||
|
|
280
e2fsprogs/fsck.c
280
e2fsprogs/fsck.c
|
@ -33,9 +33,20 @@
|
|||
* spawns actual fsck.something for each filesystem to check.
|
||||
* It doesn't guess filesystem types from on-disk format.
|
||||
*/
|
||||
//config:config FSCK
|
||||
//config: bool "fsck"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: fsck is used to check and optionally repair one or more filesystems.
|
||||
//config: In actuality, fsck is simply a front-end for the various file system
|
||||
//config: checkers (fsck.fstype) available under Linux.
|
||||
|
||||
//applet:IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_FSCK) += fsck.o
|
||||
|
||||
//usage:#define fsck_trivial_usage
|
||||
//usage: "[-ANPRTV] [-C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..."
|
||||
//usage: "[-ANPRTV] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..."
|
||||
//usage:#define fsck_full_usage "\n\n"
|
||||
//usage: "Check and repair filesystems\n"
|
||||
//usage: "\n -A Walk /etc/fstab and check all filesystems"
|
||||
|
@ -44,10 +55,12 @@
|
|||
//usage: "\n -R With -A, skip the root filesystem"
|
||||
//usage: "\n -T Don't show title on startup"
|
||||
//usage: "\n -V Verbose"
|
||||
//usage: "\n -C n Write status information to specified filedescriptor"
|
||||
//DO_PROGRESS_INDICATOR is off:
|
||||
////usage: "\n -C FD Write status information to specified file descriptor"
|
||||
//usage: "\n -t TYPE List of filesystem types to check"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
/* "progress indicator" code is somewhat buggy and ext[23] specific.
|
||||
* We should be filesystem agnostic. IOW: there should be a well-defined
|
||||
|
@ -125,35 +138,43 @@ static const char really_wanted[] ALIGN1 =
|
|||
|
||||
#define BASE_MD "/dev/md"
|
||||
|
||||
static char **args;
|
||||
static int num_args;
|
||||
static int verbose;
|
||||
struct globals {
|
||||
char **args;
|
||||
int num_args;
|
||||
int verbose;
|
||||
|
||||
#define FS_TYPE_FLAG_NORMAL 0
|
||||
#define FS_TYPE_FLAG_OPT 1
|
||||
#define FS_TYPE_FLAG_NEGOPT 2
|
||||
static char **fs_type_list;
|
||||
static uint8_t *fs_type_flag;
|
||||
static smallint fs_type_negated;
|
||||
char **fs_type_list;
|
||||
uint8_t *fs_type_flag;
|
||||
smallint fs_type_negated;
|
||||
|
||||
static smallint noexecute;
|
||||
static smallint serialize;
|
||||
static smallint skip_root;
|
||||
/* static smallint like_mount; */
|
||||
static smallint parallel_root;
|
||||
static smallint force_all_parallel;
|
||||
smallint noexecute;
|
||||
smallint serialize;
|
||||
smallint skip_root;
|
||||
/* smallint like_mount; */
|
||||
smallint parallel_root;
|
||||
smallint force_all_parallel;
|
||||
smallint kill_sent;
|
||||
|
||||
#if DO_PROGRESS_INDICATOR
|
||||
static smallint progress;
|
||||
static int progress_fd;
|
||||
smallint progress;
|
||||
int progress_fd;
|
||||
#endif
|
||||
|
||||
static int num_running;
|
||||
static int max_running;
|
||||
static char *fstype;
|
||||
static struct fs_info *filesys_info;
|
||||
static struct fs_info *filesys_last;
|
||||
static struct fsck_instance *instance_list;
|
||||
int num_running;
|
||||
int max_running;
|
||||
char *fstype;
|
||||
struct fs_info *filesys_info;
|
||||
struct fs_info *filesys_last;
|
||||
struct fsck_instance *instance_list;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Return the "base device" given a particular device; this is used to
|
||||
|
@ -302,11 +323,11 @@ static struct fs_info *create_fs_device(const char *device, const char *mntpnt,
|
|||
/*fs->flags = 0; */
|
||||
/*fs->next = NULL; */
|
||||
|
||||
if (!filesys_info)
|
||||
filesys_info = fs;
|
||||
if (!G.filesys_info)
|
||||
G.filesys_info = fs;
|
||||
else
|
||||
filesys_last->next = fs;
|
||||
filesys_last = fs;
|
||||
G.filesys_last->next = fs;
|
||||
G.filesys_last = fs;
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
@ -316,6 +337,7 @@ static void load_fs_info(const char *filename)
|
|||
{
|
||||
FILE *fstab;
|
||||
struct mntent mte;
|
||||
char buf[1024];
|
||||
|
||||
fstab = setmntent(filename, "r");
|
||||
if (!fstab) {
|
||||
|
@ -324,8 +346,8 @@ static void load_fs_info(const char *filename)
|
|||
}
|
||||
|
||||
// Loop through entries
|
||||
while (getmntent_r(fstab, &mte, bb_common_bufsiz1, COMMON_BUFSIZE)) {
|
||||
//bb_info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir,
|
||||
while (getmntent_r(fstab, &mte, buf, sizeof(buf))) {
|
||||
//bb_error_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir,
|
||||
// mte.mnt_type, mte.mnt_opts,
|
||||
// mte.mnt_passno);
|
||||
create_fs_device(mte.mnt_fsname, mte.mnt_dir,
|
||||
|
@ -340,7 +362,7 @@ static struct fs_info *lookup(char *filesys)
|
|||
{
|
||||
struct fs_info *fs;
|
||||
|
||||
for (fs = filesys_info; fs; fs = fs->next) {
|
||||
for (fs = G.filesys_info; fs; fs = fs->next) {
|
||||
if (strcmp(filesys, fs->device) == 0
|
||||
|| (fs->mountpt && strcmp(filesys, fs->mountpt) == 0)
|
||||
)
|
||||
|
@ -355,7 +377,7 @@ static int progress_active(void)
|
|||
{
|
||||
struct fsck_instance *inst;
|
||||
|
||||
for (inst = instance_list; inst; inst = inst->next) {
|
||||
for (inst = G.instance_list; inst; inst = inst->next) {
|
||||
if (inst->flags & FLAG_DONE)
|
||||
continue;
|
||||
if (inst->flags & FLAG_PROGRESS)
|
||||
|
@ -371,19 +393,17 @@ static int progress_active(void)
|
|||
*/
|
||||
static void kill_all_if_got_signal(void)
|
||||
{
|
||||
static smallint kill_sent;
|
||||
|
||||
struct fsck_instance *inst;
|
||||
|
||||
if (!bb_got_signal || kill_sent)
|
||||
if (!bb_got_signal || G.kill_sent)
|
||||
return;
|
||||
|
||||
for (inst = instance_list; inst; inst = inst->next) {
|
||||
for (inst = G.instance_list; inst; inst = inst->next) {
|
||||
if (inst->flags & FLAG_DONE)
|
||||
continue;
|
||||
kill(inst->pid, SIGTERM);
|
||||
}
|
||||
kill_sent = 1;
|
||||
G.kill_sent = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,9 +418,9 @@ static int wait_one(int flags)
|
|||
struct fsck_instance *inst, *prev;
|
||||
pid_t pid;
|
||||
|
||||
if (!instance_list)
|
||||
if (!G.instance_list)
|
||||
return -1;
|
||||
/* if (noexecute) { already returned -1; } */
|
||||
/* if (G.noexecute) { already returned -1; } */
|
||||
|
||||
while (1) {
|
||||
pid = waitpid(-1, &status, flags);
|
||||
|
@ -418,7 +438,7 @@ static int wait_one(int flags)
|
|||
continue;
|
||||
}
|
||||
prev = NULL;
|
||||
inst = instance_list;
|
||||
inst = G.instance_list;
|
||||
do {
|
||||
if (inst->pid == pid)
|
||||
goto child_died;
|
||||
|
@ -428,9 +448,8 @@ static int wait_one(int flags)
|
|||
}
|
||||
child_died:
|
||||
|
||||
if (WIFEXITED(status))
|
||||
status = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status)) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (WIFSIGNALED(status)) {
|
||||
sig = WTERMSIG(status);
|
||||
status = EXIT_UNCORRECTED;
|
||||
if (sig != SIGINT) {
|
||||
|
@ -439,16 +458,12 @@ static int wait_one(int flags)
|
|||
inst->prog, inst->device, sig);
|
||||
status = EXIT_ERROR;
|
||||
}
|
||||
} else {
|
||||
printf("%s %s: status is %x, should never happen\n",
|
||||
inst->prog, inst->device, status);
|
||||
status = EXIT_ERROR;
|
||||
}
|
||||
|
||||
#if DO_PROGRESS_INDICATOR
|
||||
if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) {
|
||||
struct fsck_instance *inst2;
|
||||
for (inst2 = instance_list; inst2; inst2 = inst2->next) {
|
||||
for (inst2 = G.instance_list; inst2; inst2 = inst2->next) {
|
||||
if (inst2->flags & FLAG_DONE)
|
||||
continue;
|
||||
if (strcmp(inst2->type, "ext2") != 0
|
||||
|
@ -475,11 +490,11 @@ static int wait_one(int flags)
|
|||
if (prev)
|
||||
prev->next = inst->next;
|
||||
else
|
||||
instance_list = inst->next;
|
||||
if (verbose > 1)
|
||||
G.instance_list = inst->next;
|
||||
if (G.verbose > 1)
|
||||
printf("Finished with %s (exit status %d)\n",
|
||||
inst->device, status);
|
||||
num_running--;
|
||||
G.num_running--;
|
||||
free_instance(inst);
|
||||
|
||||
return status;
|
||||
|
@ -515,51 +530,51 @@ static void execute(const char *type, const char *device,
|
|||
struct fsck_instance *inst;
|
||||
pid_t pid;
|
||||
|
||||
args[0] = xasprintf("fsck.%s", type);
|
||||
G.args[0] = xasprintf("fsck.%s", type);
|
||||
|
||||
#if DO_PROGRESS_INDICATOR
|
||||
if (progress && !progress_active()) {
|
||||
if (strcmp(type, "ext2") == 0
|
||||
|| strcmp(type, "ext3") == 0
|
||||
) {
|
||||
args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */
|
||||
G.args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */
|
||||
inst->flags |= FLAG_PROGRESS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
args[num_args - 2] = (char*)device;
|
||||
/* args[num_args - 1] = NULL; - already is */
|
||||
G.args[G.num_args - 2] = (char*)device;
|
||||
/* G.args[G.num_args - 1] = NULL; - already is */
|
||||
|
||||
if (verbose || noexecute) {
|
||||
printf("[%s (%d) -- %s]", args[0], num_running,
|
||||
if (G.verbose || G.noexecute) {
|
||||
printf("[%s (%d) -- %s]", G.args[0], G.num_running,
|
||||
mntpt ? mntpt : device);
|
||||
for (i = 0; args[i]; i++)
|
||||
printf(" %s", args[i]);
|
||||
for (i = 0; G.args[i]; i++)
|
||||
printf(" %s", G.args[i]);
|
||||
bb_putchar('\n');
|
||||
}
|
||||
|
||||
/* Fork and execute the correct program. */
|
||||
pid = -1;
|
||||
if (!noexecute) {
|
||||
pid = spawn(args);
|
||||
if (!G.noexecute) {
|
||||
pid = spawn(G.args);
|
||||
if (pid < 0)
|
||||
bb_simple_perror_msg(args[0]);
|
||||
bb_simple_perror_msg(G.args[0]);
|
||||
}
|
||||
|
||||
#if DO_PROGRESS_INDICATOR
|
||||
free(args[XXX]);
|
||||
free(G.args[XXX]);
|
||||
#endif
|
||||
|
||||
/* No child, so don't record an instance */
|
||||
if (pid <= 0) {
|
||||
free(args[0]);
|
||||
free(G.args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
inst = xzalloc(sizeof(*inst));
|
||||
inst->pid = pid;
|
||||
inst->prog = args[0];
|
||||
inst->prog = G.args[0];
|
||||
inst->device = xstrdup(device);
|
||||
inst->base_device = base_device(device);
|
||||
#if DO_PROGRESS_INDICATOR
|
||||
|
@ -568,8 +583,8 @@ static void execute(const char *type, const char *device,
|
|||
|
||||
/* Add to the list of running fsck's.
|
||||
* (was adding to the end, but adding to the front is simpler...) */
|
||||
inst->next = instance_list;
|
||||
instance_list = inst;
|
||||
inst->next = G.instance_list;
|
||||
G.instance_list = inst;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -588,27 +603,27 @@ static void fsck_device(struct fs_info *fs /*, int interactive */)
|
|||
|
||||
if (strcmp(fs->type, "auto") != 0) {
|
||||
type = fs->type;
|
||||
if (verbose > 2)
|
||||
bb_info_msg("using filesystem type '%s' %s",
|
||||
if (G.verbose > 2)
|
||||
printf("using filesystem type '%s' %s\n",
|
||||
type, "from fstab");
|
||||
} else if (fstype
|
||||
&& (fstype[0] != 'n' || fstype[1] != 'o') /* != "no" */
|
||||
&& !is_prefixed_with(fstype, "opts=")
|
||||
&& !is_prefixed_with(fstype, "loop")
|
||||
&& !strchr(fstype, ',')
|
||||
} else if (G.fstype
|
||||
&& (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */
|
||||
&& !is_prefixed_with(G.fstype, "opts=")
|
||||
&& !is_prefixed_with(G.fstype, "loop")
|
||||
&& !strchr(G.fstype, ',')
|
||||
) {
|
||||
type = fstype;
|
||||
if (verbose > 2)
|
||||
bb_info_msg("using filesystem type '%s' %s",
|
||||
type = G.fstype;
|
||||
if (G.verbose > 2)
|
||||
printf("using filesystem type '%s' %s\n",
|
||||
type, "from -t");
|
||||
} else {
|
||||
type = "auto";
|
||||
if (verbose > 2)
|
||||
bb_info_msg("using filesystem type '%s' %s",
|
||||
if (G.verbose > 2)
|
||||
printf("using filesystem type '%s' %s\n",
|
||||
type, "(default)");
|
||||
}
|
||||
|
||||
num_running++;
|
||||
G.num_running++;
|
||||
execute(type, fs->device, fs->mountpt /*, interactive */);
|
||||
}
|
||||
|
||||
|
@ -621,13 +636,13 @@ static int device_already_active(char *device)
|
|||
struct fsck_instance *inst;
|
||||
char *base;
|
||||
|
||||
if (force_all_parallel)
|
||||
if (G.force_all_parallel)
|
||||
return 0;
|
||||
|
||||
#ifdef BASE_MD
|
||||
/* Don't check a soft raid disk with any other disk */
|
||||
if (instance_list
|
||||
&& (is_prefixed_with(instance_list->device, BASE_MD)
|
||||
if (G.instance_list
|
||||
&& (is_prefixed_with(G.instance_list->device, BASE_MD)
|
||||
|| is_prefixed_with(device, BASE_MD))
|
||||
) {
|
||||
return 1;
|
||||
|
@ -640,9 +655,9 @@ static int device_already_active(char *device)
|
|||
* already active if there are any fsck instances running.
|
||||
*/
|
||||
if (!base)
|
||||
return (instance_list != NULL);
|
||||
return (G.instance_list != NULL);
|
||||
|
||||
for (inst = instance_list; inst; inst = inst->next) {
|
||||
for (inst = G.instance_list; inst; inst = inst->next) {
|
||||
if (!inst->base_device || !strcmp(base, inst->base_device)) {
|
||||
free(base);
|
||||
return 1;
|
||||
|
@ -687,17 +702,17 @@ static int fs_match(struct fs_info *fs)
|
|||
int n, ret, checked_type;
|
||||
char *cp;
|
||||
|
||||
if (!fs_type_list)
|
||||
if (!G.fs_type_list)
|
||||
return 1;
|
||||
|
||||
ret = 0;
|
||||
checked_type = 0;
|
||||
n = 0;
|
||||
while (1) {
|
||||
cp = fs_type_list[n];
|
||||
cp = G.fs_type_list[n];
|
||||
if (!cp)
|
||||
break;
|
||||
switch (fs_type_flag[n]) {
|
||||
switch (G.fs_type_flag[n]) {
|
||||
case FS_TYPE_FLAG_NORMAL:
|
||||
checked_type++;
|
||||
if (strcmp(cp, fs->type) == 0)
|
||||
|
@ -717,7 +732,7 @@ static int fs_match(struct fs_info *fs)
|
|||
if (checked_type == 0)
|
||||
return 1;
|
||||
|
||||
return (fs_type_negated ? !ret : ret);
|
||||
return (G.fs_type_negated ? !ret : ret);
|
||||
}
|
||||
|
||||
/* Check if we should ignore this filesystem. */
|
||||
|
@ -753,7 +768,7 @@ static int check_all(void)
|
|||
smallint pass_done;
|
||||
int passno;
|
||||
|
||||
if (verbose)
|
||||
if (G.verbose)
|
||||
puts("Checking all filesystems");
|
||||
|
||||
/*
|
||||
|
@ -761,17 +776,17 @@ static int check_all(void)
|
|||
* which should be ignored as done, and resolve any "auto"
|
||||
* filesystem types (done as a side-effect of calling ignore()).
|
||||
*/
|
||||
for (fs = filesys_info; fs; fs = fs->next)
|
||||
for (fs = G.filesys_info; fs; fs = fs->next)
|
||||
if (ignore(fs))
|
||||
fs->flags |= FLAG_DONE;
|
||||
|
||||
/*
|
||||
* Find and check the root filesystem.
|
||||
*/
|
||||
if (!parallel_root) {
|
||||
for (fs = filesys_info; fs; fs = fs->next) {
|
||||
if (!G.parallel_root) {
|
||||
for (fs = G.filesys_info; fs; fs = fs->next) {
|
||||
if (LONE_CHAR(fs->mountpt, '/')) {
|
||||
if (!skip_root && !ignore(fs)) {
|
||||
if (!G.skip_root && !ignore(fs)) {
|
||||
fsck_device(fs /*, 1*/);
|
||||
status |= wait_many(FLAG_WAIT_ALL);
|
||||
if (status > EXIT_NONDESTRUCT)
|
||||
|
@ -787,8 +802,8 @@ static int check_all(void)
|
|||
* filesystem listed twice.
|
||||
* "Skip root" will skip _all_ root entries.
|
||||
*/
|
||||
if (skip_root)
|
||||
for (fs = filesys_info; fs; fs = fs->next)
|
||||
if (G.skip_root)
|
||||
for (fs = G.filesys_info; fs; fs = fs->next)
|
||||
if (LONE_CHAR(fs->mountpt, '/'))
|
||||
fs->flags |= FLAG_DONE;
|
||||
|
||||
|
@ -798,7 +813,7 @@ static int check_all(void)
|
|||
not_done_yet = 0;
|
||||
pass_done = 1;
|
||||
|
||||
for (fs = filesys_info; fs; fs = fs->next) {
|
||||
for (fs = G.filesys_info; fs; fs = fs->next) {
|
||||
if (bb_got_signal)
|
||||
break;
|
||||
if (fs->flags & FLAG_DONE)
|
||||
|
@ -824,7 +839,7 @@ static int check_all(void)
|
|||
/*
|
||||
* Spawn off the fsck process
|
||||
*/
|
||||
fsck_device(fs /*, serialize*/);
|
||||
fsck_device(fs /*, G.serialize*/);
|
||||
fs->flags |= FLAG_DONE;
|
||||
|
||||
/*
|
||||
|
@ -832,8 +847,8 @@ static int check_all(void)
|
|||
* have a limit on the number of fsck's extant
|
||||
* at one time, apply that limit.
|
||||
*/
|
||||
if (serialize
|
||||
|| (max_running && (num_running >= max_running))
|
||||
if (G.serialize
|
||||
|| (G.num_running >= G.max_running)
|
||||
) {
|
||||
pass_done = 0;
|
||||
break;
|
||||
|
@ -841,12 +856,12 @@ static int check_all(void)
|
|||
}
|
||||
if (bb_got_signal)
|
||||
break;
|
||||
if (verbose > 1)
|
||||
if (G.verbose > 1)
|
||||
printf("--waiting-- (pass %d)\n", passno);
|
||||
status |= wait_many(pass_done ? FLAG_WAIT_ALL :
|
||||
FLAG_WAIT_ATLEAST_ONE);
|
||||
if (pass_done) {
|
||||
if (verbose > 1)
|
||||
if (G.verbose > 1)
|
||||
puts("----------------------------------");
|
||||
passno++;
|
||||
} else
|
||||
|
@ -874,9 +889,9 @@ static void compile_fs_type(char *fs_type)
|
|||
s++;
|
||||
}
|
||||
|
||||
fs_type_list = xzalloc(num * sizeof(fs_type_list[0]));
|
||||
fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0]));
|
||||
fs_type_negated = -1; /* not yet known is it negated or not */
|
||||
G.fs_type_list = xzalloc(num * sizeof(G.fs_type_list[0]));
|
||||
G.fs_type_flag = xzalloc(num * sizeof(G.fs_type_flag[0]));
|
||||
G.fs_type_negated = -1; /* not yet known is it negated or not */
|
||||
|
||||
num = 0;
|
||||
s = fs_type;
|
||||
|
@ -898,18 +913,18 @@ static void compile_fs_type(char *fs_type)
|
|||
if (is_prefixed_with(s, "opts=")) {
|
||||
s += 5;
|
||||
loop_special_case:
|
||||
fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT;
|
||||
G.fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT;
|
||||
} else {
|
||||
if (fs_type_negated == -1)
|
||||
fs_type_negated = negate;
|
||||
if (fs_type_negated != negate)
|
||||
if (G.fs_type_negated == -1)
|
||||
G.fs_type_negated = negate;
|
||||
if (G.fs_type_negated != negate)
|
||||
bb_error_msg_and_die(
|
||||
"either all or none of the filesystem types passed to -t must be prefixed "
|
||||
"with 'no' or '!'");
|
||||
}
|
||||
comma = strchr(s, ',');
|
||||
fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s);
|
||||
if (!comma)
|
||||
comma = strchrnul(s, ',');
|
||||
G.fs_type_list[num++] = xstrndup(s, comma-s);
|
||||
if (*comma == '\0')
|
||||
break;
|
||||
s = comma + 1;
|
||||
}
|
||||
|
@ -917,8 +932,8 @@ static void compile_fs_type(char *fs_type)
|
|||
|
||||
static char **new_args(void)
|
||||
{
|
||||
args = xrealloc_vector(args, 2, num_args);
|
||||
return &args[num_args++];
|
||||
G.args = xrealloc_vector(G.args, 2, G.num_args);
|
||||
return &G.args[G.num_args++];
|
||||
}
|
||||
|
||||
int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
|
@ -935,6 +950,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
smallint doall;
|
||||
smallint notitle;
|
||||
|
||||
INIT_G();
|
||||
|
||||
/* we want wait() to be interruptible */
|
||||
signal_no_SA_RESTART_empty_mask(SIGINT, record_signo);
|
||||
signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo);
|
||||
|
@ -944,8 +961,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
opts_for_fsck = doall = notitle = 0;
|
||||
devices = NULL;
|
||||
num_devices = 0;
|
||||
new_args(); /* args[0] = NULL, will be replaced by fsck.<type> */
|
||||
/* instance_list = NULL; - in bss, so already zeroed */
|
||||
new_args(); /* G.args[0] = NULL, will be replaced by fsck.<type> */
|
||||
/* G.instance_list = NULL; - in bss, so already zeroed */
|
||||
|
||||
while (*++argv) {
|
||||
int j;
|
||||
|
@ -994,13 +1011,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
goto next_arg;
|
||||
#endif
|
||||
case 'V':
|
||||
verbose++;
|
||||
G.verbose++;
|
||||
break;
|
||||
case 'N':
|
||||
noexecute = 1;
|
||||
G.noexecute = 1;
|
||||
break;
|
||||
case 'R':
|
||||
skip_root = 1;
|
||||
G.skip_root = 1;
|
||||
break;
|
||||
case 'T':
|
||||
notitle = 1;
|
||||
|
@ -1009,13 +1026,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
like_mount = 1;
|
||||
break; */
|
||||
case 'P':
|
||||
parallel_root = 1;
|
||||
G.parallel_root = 1;
|
||||
break;
|
||||
case 's':
|
||||
serialize = 1;
|
||||
G.serialize = 1;
|
||||
break;
|
||||
case 't':
|
||||
if (fstype)
|
||||
if (G.fstype)
|
||||
bb_show_usage();
|
||||
if (arg[++j])
|
||||
tmp = &arg[j];
|
||||
|
@ -1023,8 +1040,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
tmp = *argv;
|
||||
else
|
||||
bb_show_usage();
|
||||
fstype = xstrdup(tmp);
|
||||
compile_fs_type(fstype);
|
||||
G.fstype = xstrdup(tmp);
|
||||
compile_fs_type(G.fstype);
|
||||
goto next_arg;
|
||||
case '?':
|
||||
bb_show_usage();
|
||||
|
@ -1045,12 +1062,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
}
|
||||
}
|
||||
if (getenv("FSCK_FORCE_ALL_PARALLEL"))
|
||||
force_all_parallel = 1;
|
||||
G.force_all_parallel = 1;
|
||||
tmp = getenv("FSCK_MAX_INST");
|
||||
G.max_running = INT_MAX;
|
||||
if (tmp)
|
||||
max_running = xatoi(tmp);
|
||||
new_args(); /* args[num_args - 2] will be replaced by <device> */
|
||||
new_args(); /* args[num_args - 1] is the last, NULL element */
|
||||
G.max_running = xatoi(tmp);
|
||||
new_args(); /* G.args[G.num_args - 2] will be replaced by <device> */
|
||||
new_args(); /* G.args[G.num_args - 1] is the last, NULL element */
|
||||
|
||||
if (!notitle)
|
||||
puts("fsck (busybox "BB_VER", "BB_BT")");
|
||||
|
@ -1062,10 +1080,10 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
fstab = "/etc/fstab";
|
||||
load_fs_info(fstab);
|
||||
|
||||
/*interactive = (num_devices == 1) | serialize;*/
|
||||
/*interactive = (num_devices == 1) | G.serialize;*/
|
||||
|
||||
if (num_devices == 0)
|
||||
/*interactive =*/ serialize = doall = 1;
|
||||
/*interactive =*/ G.serialize = doall = 1;
|
||||
if (doall)
|
||||
return check_all();
|
||||
|
||||
|
@ -1081,13 +1099,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
|
|||
fs = create_fs_device(devices[i], "", "auto", NULL, -1);
|
||||
fsck_device(fs /*, interactive */);
|
||||
|
||||
if (serialize
|
||||
|| (max_running && (num_running >= max_running))
|
||||
if (G.serialize
|
||||
|| (G.num_running >= G.max_running)
|
||||
) {
|
||||
int exit_status = wait_one(0);
|
||||
if (exit_status >= 0)
|
||||
status |= exit_status;
|
||||
if (verbose > 1)
|
||||
if (G.verbose > 1)
|
||||
puts("----------------------------------");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,24 +9,26 @@
|
|||
* This file can be redistributed under the terms of the GNU General
|
||||
* Public License
|
||||
*/
|
||||
//config:config LSATTR
|
||||
//config: bool "lsattr"
|
||||
//config: default y
|
||||
//config: select PLATFORM_LINUX
|
||||
//config: help
|
||||
//config: lsattr lists the file attributes on a second extended file system.
|
||||
|
||||
/*
|
||||
* History:
|
||||
* 93/10/30 - Creation
|
||||
* 93/11/13 - Replace stat() calls by lstat() to avoid loops
|
||||
* 94/02/27 - Integrated in Ted's distribution
|
||||
* 98/12/29 - Display version info only when -V specified (G M Sipe)
|
||||
*/
|
||||
//applet:IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o
|
||||
|
||||
//usage:#define lsattr_trivial_usage
|
||||
//usage: "[-Radlv] [FILE]..."
|
||||
//usage:#define lsattr_full_usage "\n\n"
|
||||
//usage: "List file attributes on an ext2 fs\n"
|
||||
//usage: "List ext2 file attributes\n"
|
||||
//usage: "\n -R Recurse"
|
||||
//usage: "\n -a Don't hide entries starting with ."
|
||||
//usage: "\n -d List directory entries instead of contents"
|
||||
//usage: "\n -l List long flag names"
|
||||
//usage: "\n -v List the file's version/generation number"
|
||||
//usage: "\n -v List version/generation number"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "e2fs_lib.h"
|
||||
|
|
|
@ -6,6 +6,33 @@
|
|||
*
|
||||
* Licensed under GPLv2, see file LICENSE in this source tree.
|
||||
*/
|
||||
//config:config TUNE2FS
|
||||
//config: bool "tune2fs"
|
||||
//config: default n # off: it is too limited compared to upstream version
|
||||
//config: help
|
||||
//config: tune2fs allows the system administrator to adjust various tunable
|
||||
//config: filesystem parameters on Linux ext2/ext3 filesystems.
|
||||
|
||||
//applet:IF_TUNE2FS(APPLET(tune2fs, BB_DIR_SBIN, BB_SUID_DROP))
|
||||
|
||||
//kbuild:lib-$(CONFIG_TUNE2FS) += tune2fs.o
|
||||
|
||||
//usage:#define tune2fs_trivial_usage
|
||||
//usage: "[-c MAX_MOUNT_COUNT] "
|
||||
////usage: "[-e errors-behavior] [-g group] "
|
||||
//usage: "[-i DAYS] "
|
||||
////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] "
|
||||
////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] "
|
||||
////usage: "[-r reserved-blocks-count] [-u user] "
|
||||
//usage: "[-C MOUNT_COUNT] "
|
||||
//usage: "[-L LABEL] "
|
||||
////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] "
|
||||
////usage: "[-T last-check-time] [-U UUID] "
|
||||
//usage: "BLOCKDEV"
|
||||
//usage:
|
||||
//usage:#define tune2fs_full_usage "\n\n"
|
||||
//usage: "Adjust filesystem options on ext[23] filesystems"
|
||||
|
||||
#include "libbb.h"
|
||||
#include <linux/fs.h>
|
||||
#include "bb_e2fs_defs.h"
|
||||
|
@ -27,22 +54,6 @@ do { \
|
|||
#define FETCH_LE32(field) \
|
||||
(sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size())
|
||||
|
||||
//usage:#define tune2fs_trivial_usage
|
||||
//usage: "[-c MAX_MOUNT_COUNT] "
|
||||
////usage: "[-e errors-behavior] [-g group] "
|
||||
//usage: "[-i DAYS] "
|
||||
////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] "
|
||||
////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] "
|
||||
////usage: "[-r reserved-blocks-count] [-u user] "
|
||||
//usage: "[-C MOUNT_COUNT] "
|
||||
//usage: "[-L LABEL] "
|
||||
////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] "
|
||||
////usage: "[-T last-check-time] [-U UUID] "
|
||||
//usage: "BLOCKDEV"
|
||||
//usage:
|
||||
//usage:#define tune2fs_full_usage "\n\n"
|
||||
//usage: "Adjust filesystem options on ext[23] filesystems"
|
||||
|
||||
enum {
|
||||
OPT_L = 1 << 0, // label
|
||||
OPT_c = 1 << 1, // max mount count
|
||||
|
|
|
@ -125,6 +125,7 @@
|
|||
//usage: "\n -w Ignore all whitespace"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
#if 0
|
||||
# define dbg_error_msg(...) bb_error_msg(__VA_ARGS__)
|
||||
|
@ -748,6 +749,7 @@ static int diffreg(char *file[2])
|
|||
fp[i] = fdopen(fd, "r");
|
||||
}
|
||||
|
||||
setup_common_bufsiz();
|
||||
while (1) {
|
||||
const size_t sz = COMMON_BUFSIZE / 2;
|
||||
char *const buf0 = bb_common_bufsiz1;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
//usage:#define ed_full_usage ""
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
|
||||
typedef struct LINE {
|
||||
struct LINE *next;
|
||||
|
@ -35,8 +36,8 @@ typedef struct LINE {
|
|||
#define searchString bb_common_bufsiz1
|
||||
|
||||
enum {
|
||||
USERSIZE = sizeof(searchString) > 1024 ? 1024
|
||||
: sizeof(searchString) - 1, /* max line length typed in by user */
|
||||
USERSIZE = COMMON_BUFSIZE > 1024 ? 1024
|
||||
: COMMON_BUFSIZE - 1, /* max line length typed in by user */
|
||||
INITBUF_SIZE = 1024, /* initial buffer size */
|
||||
};
|
||||
|
||||
|
@ -66,6 +67,7 @@ struct globals {
|
|||
#define lines (G.lines )
|
||||
#define marks (G.marks )
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -372,10 +372,6 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
|
|||
xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO);
|
||||
}
|
||||
}
|
||||
if (argv[0]) {
|
||||
oldname = xstrdup(argv[0]);
|
||||
newname = xstrdup(argv[0]);
|
||||
}
|
||||
|
||||
// Loop through the lines in the patch
|
||||
for(;;) {
|
||||
|
@ -486,10 +482,10 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
|
|||
// or if new hunk is empty (zero context) after patching
|
||||
if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) {
|
||||
name = reverse ? newname : oldname;
|
||||
empty++;
|
||||
empty = 1;
|
||||
}
|
||||
|
||||
// handle -p path truncation.
|
||||
// Handle -p path truncation.
|
||||
for (i = 0, s = name; *s;) {
|
||||
if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i)
|
||||
break;
|
||||
|
@ -500,6 +496,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
|
|||
i++;
|
||||
name = s;
|
||||
}
|
||||
// If "patch FILE_TO_PATCH", completely ignore name from patch
|
||||
if (argv[0])
|
||||
name = argv[0];
|
||||
|
||||
if (empty) {
|
||||
// File is empty after the patches have been applied
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
//usage: "bar\n"
|
||||
|
||||
#include "libbb.h"
|
||||
#include "common_bufsiz.h"
|
||||
#include "xregex.h"
|
||||
|
||||
#if 0
|
||||
|
@ -113,7 +114,7 @@ typedef struct sed_cmd_s {
|
|||
int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($). -2-N = +N */
|
||||
int end_line_orig;
|
||||
|
||||
FILE *sw_file; /* File (sw) command writes to, -1 for none. */
|
||||
FILE *sw_file; /* File (sw) command writes to, NULL for none. */
|
||||
char *string; /* Data string for (saicytb) commands. */
|
||||
|
||||
unsigned which_match; /* (s) Which match to replace (0 for all) */
|
||||
|
@ -161,11 +162,10 @@ struct globals {
|
|||
int len; /* Space allocated */
|
||||
} pipeline;
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
struct BUG_G_too_big {
|
||||
char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
|
||||
};
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
|
||||
G.sed_cmd_tail = &G.sed_cmd_head; \
|
||||
} while (0)
|
||||
|
||||
|
@ -181,7 +181,7 @@ static void sed_free_and_close_stuff(void)
|
|||
sed_cmd_t *sed_cmd_next = sed_cmd->next;
|
||||
|
||||
if (sed_cmd->sw_file)
|
||||
xprint_and_close_file(sed_cmd->sw_file);
|
||||
fclose(sed_cmd->sw_file);
|
||||
|
||||
if (sed_cmd->beg_match) {
|
||||
regfree(sed_cmd->beg_match);
|
||||
|
@ -218,23 +218,33 @@ static void cleanup_outname(void)
|
|||
|
||||
/* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */
|
||||
|
||||
static void parse_escapes(char *dest, const char *string, int len, char from, char to)
|
||||
static unsigned parse_escapes(char *dest, const char *string, int len, char from, char to)
|
||||
{
|
||||
char *d = dest;
|
||||
int i = 0;
|
||||
|
||||
if (len == -1)
|
||||
len = strlen(string);
|
||||
|
||||
while (i < len) {
|
||||
if (string[i] == '\\') {
|
||||
if (!to || string[i+1] == from) {
|
||||
*dest++ = to ? to : string[i+1];
|
||||
if ((*d = to ? to : string[i+1]) == '\0')
|
||||
return d - dest;
|
||||
i += 2;
|
||||
d++;
|
||||
continue;
|
||||
}
|
||||
*dest++ = string[i++];
|
||||
i++; /* skip backslash in string[] */
|
||||
*d++ = '\\';
|
||||
/* fall through: copy next char verbatim */
|
||||
}
|
||||
/* TODO: is it safe wrt a string with trailing '\\' ? */
|
||||
*dest++ = string[i++];
|
||||
if ((*d = string[i++]) == '\0')
|
||||
return d - dest;
|
||||
d++;
|
||||
}
|
||||
*dest = '\0';
|
||||
*d = '\0';
|
||||
return d - dest;
|
||||
}
|
||||
|
||||
static char *copy_parsing_escapes(const char *string, int len)
|
||||
|
@ -245,9 +255,8 @@ static char *copy_parsing_escapes(const char *string, int len)
|
|||
/* sed recognizes \n */
|
||||
/* GNU sed also recognizes \t and \r */
|
||||
for (s = "\nn\tt\rr"; *s; s += 2) {
|
||||
parse_escapes(dest, string, len, s[1], s[0]);
|
||||
len = parse_escapes(dest, string, len, s[1], s[0]);
|
||||
string = dest;
|
||||
len = strlen(dest);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
@ -428,8 +437,11 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
|
|||
/* Write to file */
|
||||
case 'w':
|
||||
{
|
||||
char *temp;
|
||||
idx += parse_file_cmd(/*sed_cmd,*/ substr+idx, &temp);
|
||||
char *fname;
|
||||
idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname);
|
||||
sed_cmd->sw_file = xfopen_for_write(fname);
|
||||
sed_cmd->sw_last_char = '\n';
|
||||
free(fname);
|
||||
break;
|
||||
}
|
||||
/* Ignore case (gnu exension) */
|
||||
|
@ -470,7 +482,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
|
|||
*/
|
||||
static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
|
||||
{
|
||||
static const char cmd_letters[] = "saicrw:btTydDgGhHlnNpPqx={}";
|
||||
static const char cmd_letters[] ALIGN1 = "saicrw:btTydDgGhHlnNpPqx={}";
|
||||
enum {
|
||||
IDX_s = 0,
|
||||
IDX_a,
|
||||
|
@ -501,9 +513,11 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
|
|||
IDX_rbrace,
|
||||
IDX_nul
|
||||
};
|
||||
struct chk { char chk[sizeof(cmd_letters)-1 == IDX_nul ? 1 : -1]; };
|
||||
unsigned idx;
|
||||
|
||||
unsigned idx = strchrnul(cmd_letters, sed_cmd->cmd) - cmd_letters;
|
||||
BUILD_BUG_ON(sizeof(cmd_letters)-1 != IDX_nul);
|
||||
|
||||
idx = strchrnul(cmd_letters, sed_cmd->cmd) - cmd_letters;
|
||||
|
||||
/* handle (s)ubstitution command */
|
||||
if (idx == IDX_s) {
|
||||
|
@ -511,6 +525,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
|
|||
}
|
||||
/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
|
||||
else if (idx <= IDX_c) { /* a,i,c */
|
||||
unsigned len;
|
||||
|
||||
if (idx < IDX_c) { /* a,i */
|
||||
if (sed_cmd->end_line || sed_cmd->end_match)
|
||||
bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd);
|
||||
|
@ -524,10 +540,11 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
|
|||
break;
|
||||
cmdstr++;
|
||||
}
|
||||
sed_cmd->string = xstrdup(cmdstr);
|
||||
len = strlen(cmdstr);
|
||||
sed_cmd->string = copy_parsing_escapes(cmdstr, len);
|
||||
cmdstr += len;
|
||||
/* "\anychar" -> "anychar" */
|
||||
parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), '\0', '\0');
|
||||
cmdstr += strlen(cmdstr);
|
||||
parse_escapes(sed_cmd->string, sed_cmd->string, -1, '\0', '\0');
|
||||
}
|
||||
/* handle file cmds: (r)ead */
|
||||
else if (idx <= IDX_w) { /* r,w */
|
||||
|
@ -559,8 +576,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
|
|||
|
||||
cmdstr += parse_regex_delim(cmdstr, &match, &replace)+1;
|
||||
/* \n already parsed, but \delimiter needs unescaping. */
|
||||
parse_escapes(match, match, strlen(match), i, i);
|
||||
parse_escapes(replace, replace, strlen(replace), i, i);
|
||||
parse_escapes(match, match, -1, i, i);
|
||||
parse_escapes(replace, replace, -1, i, i);
|
||||
|
||||
sed_cmd->string = xzalloc((strlen(match) + 1) * 2);
|
||||
for (i = 0; match[i] && replace[i]; i++) {
|
||||
|
@ -939,13 +956,22 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
|
|||
*last_puts_char = lpc;
|
||||
}
|
||||
|
||||
static void flush_append(char *last_puts_char, char last_gets_char)
|
||||
static void flush_append(char *last_puts_char)
|
||||
{
|
||||
char *data;
|
||||
|
||||
/* Output appended lines. */
|
||||
while ((data = (char *)llist_pop(&G.append_head))) {
|
||||
puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char);
|
||||
while ((data = (char *)llist_pop(&G.append_head)) != NULL) {
|
||||
/* Append command does not respect "nonterminated-ness"
|
||||
* of last line. Try this:
|
||||
* $ echo -n "woot" | sed -e '/woot/a woo' -
|
||||
* woot
|
||||
* woo
|
||||
* (both lines are terminated with \n)
|
||||
* Therefore we do not propagate "last_gets_char" here,
|
||||
* pass '\n' instead:
|
||||
*/
|
||||
puts_maybe_newline(data, G.nonstdout, last_puts_char, '\n');
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
@ -953,13 +979,13 @@ static void flush_append(char *last_puts_char, char last_gets_char)
|
|||
/* Get next line of input from G.input_file_list, flushing append buffer and
|
||||
* noting if we ran out of files without a newline on the last line we read.
|
||||
*/
|
||||
static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets_char)
|
||||
static char *get_next_line(char *gets_char, char *last_puts_char)
|
||||
{
|
||||
char *temp = NULL;
|
||||
int len;
|
||||
char gc;
|
||||
|
||||
flush_append(last_puts_char, last_gets_char);
|
||||
flush_append(last_puts_char);
|
||||
|
||||
/* will be returned if last line in the file
|
||||
* doesn't end with either '\n' or '\0' */
|
||||
|
@ -1037,7 +1063,7 @@ static void process_files(void)
|
|||
int substituted;
|
||||
|
||||
/* Prime the pump */
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char, '\n' /*last_gets_char*/);
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char);
|
||||
|
||||
/* Go through every line in each file */
|
||||
again:
|
||||
|
@ -1051,7 +1077,7 @@ static void process_files(void)
|
|||
|
||||
/* Read one line in advance so we can act on the last line,
|
||||
* the '$' address */
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char);
|
||||
linenum++;
|
||||
|
||||
/* For every line, go through all the commands */
|
||||
|
@ -1278,7 +1304,7 @@ static void process_files(void)
|
|||
free(pattern_space);
|
||||
pattern_space = next_line;
|
||||
last_gets_char = next_gets_char;
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char);
|
||||
substituted = 0;
|
||||
linenum++;
|
||||
break;
|
||||
|
@ -1314,7 +1340,7 @@ static void process_files(void)
|
|||
pattern_space[len] = '\n';
|
||||
strcpy(pattern_space + len+1, next_line);
|
||||
last_gets_char = next_gets_char;
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
|
||||
next_line = get_next_line(&next_gets_char, &last_puts_char);
|
||||
linenum++;
|
||||
break;
|
||||
}
|
||||
|
@ -1418,7 +1444,7 @@ static void process_files(void)
|
|||
|
||||
/* Delete and such jump here. */
|
||||
discard_line:
|
||||
flush_append(&last_puts_char, last_gets_char);
|
||||
flush_append(&last_puts_char /*,last_gets_char*/);
|
||||
free(pattern_space);
|
||||
|
||||
goto again;
|
||||
|
@ -1504,12 +1530,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
|
|||
while (opt_f) { // -f
|
||||
char *line;
|
||||
FILE *cmdfile;
|
||||
cmdfile = xfopen_for_read(llist_pop(&opt_f));
|
||||
cmdfile = xfopen_stdin(llist_pop(&opt_f));
|
||||
while ((line = xmalloc_fgetline(cmdfile)) != NULL) {
|
||||
add_cmd(line);
|
||||
free(line);
|
||||
}
|
||||
fclose(cmdfile);
|
||||
fclose_if_not_stdin(cmdfile);
|
||||
}
|
||||
/* if we didn't get a pattern from -e or -f, use argv[0] */
|
||||
if (!(opt & 0x30)) {
|
||||
|
|
|
@ -251,7 +251,7 @@ enum {
|
|||
// cmds modifying text[]
|
||||
// vda: removed "aAiIs" as they switch us into insert mode
|
||||
// and remembering input for replay after them makes no sense
|
||||
static const char modifying_cmds[] = "cCdDJoOpPrRxX<>~";
|
||||
static const char modifying_cmds[] ALIGN1 = "cCdDJoOpPrRxX<>~";
|
||||
#endif
|
||||
|
||||
enum {
|
||||
|
|
|
@ -5,49 +5,55 @@
|
|||
# Requires the programs (ar, tar, gzip, and the pager more or less).
|
||||
#
|
||||
usage() {
|
||||
echo "Usage: undeb -c package.deb <Print control file info>"
|
||||
echo " undeb -l package.deb <List contents of deb package>"
|
||||
echo " undeb -x package.deb /foo/boo <Extract deb package to this directory,"
|
||||
echo " put . for current directory>"
|
||||
exit
|
||||
cat <<EOF
|
||||
Usage: undeb -c package.deb <Print control file info>
|
||||
undeb -l package.deb <List contents of deb package>
|
||||
undeb -x package.deb /foo/boo <Extract deb package to this directory,
|
||||
put . for current directory>
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
deb=$2
|
||||
|
||||
exist() {
|
||||
if [ "$deb" = "" ]; then
|
||||
usage
|
||||
elif [ ! -s "$deb" ]; then
|
||||
echo "Can't find $deb!"
|
||||
exit
|
||||
fi
|
||||
if [ -z "${deb}" ]; then
|
||||
usage
|
||||
elif [ ! -s "${deb}" ]; then
|
||||
echo "Can't find ${deb}!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
usage
|
||||
if [ -z "$1" ]; then
|
||||
usage
|
||||
elif [ "$1" = "-l" ]; then
|
||||
exist
|
||||
type more >/dev/null 2>&1 && pager=more
|
||||
type less >/dev/null 2>&1 && pager=less
|
||||
[ "$pager" = "" ] && echo "No pager found!" && exit
|
||||
(ar -p $deb control.tar.gz | tar -xzO *control ; echo -e "\nPress enter to scroll, q to Quit!\n" ; ar -p $deb data.tar.gz | tar -tzv) | $pager
|
||||
exit
|
||||
exist
|
||||
type more >/dev/null 2>&1 && pager=more
|
||||
type less >/dev/null 2>&1 && pager=less
|
||||
[ -z "${pager}" ] && echo "No pager found!" && exit 1
|
||||
(
|
||||
ar -p "${deb}" control.tar.gz | tar -xzO *control
|
||||
printf "\nPress enter to scroll, q to Quit!\n\n"
|
||||
ar -p "${deb}" data.tar.gz | tar -tzv
|
||||
) | ${pager}
|
||||
exit
|
||||
elif [ "$1" = "-c" ]; then
|
||||
exist
|
||||
ar -p $deb control.tar.gz | tar -xzO *control
|
||||
exit
|
||||
exist
|
||||
ar -p "${deb}" control.tar.gz | tar -xzO *control
|
||||
exit
|
||||
elif [ "$1" = "-x" ]; then
|
||||
exist
|
||||
if [ "$3" = "" ]; then
|
||||
usage
|
||||
elif [ ! -d "$3" ]; then
|
||||
echo "No such directory $3!"
|
||||
exit
|
||||
fi
|
||||
ar -p $deb data.tar.gz | tar -xzvpf - -C $3 || exit
|
||||
echo
|
||||
echo "Extracted $deb to $3!"
|
||||
exit
|
||||
exist
|
||||
if [ -z "$3" ]; then
|
||||
usage
|
||||
elif [ ! -d "$3" ]; then
|
||||
echo "No such directory $3!"
|
||||
exit 1
|
||||
fi
|
||||
ar -p "${deb}" data.tar.gz | tar -xzvpf - -C "$3" || exit
|
||||
echo
|
||||
echo "Extracted ${deb} to $3!"
|
||||
exit
|
||||
else
|
||||
usage
|
||||
usage
|
||||
fi
|
||||
|
|
|
@ -5,44 +5,49 @@
|
|||
# Requires the programs (cpio, gzip, and the pager more or less).
|
||||
#
|
||||
usage() {
|
||||
echo "Usage: unrpm -l package.rpm <List contents of rpm package>"
|
||||
echo " unrpm -x package.rpm /foo/boo <Extract rpm package to this directory,"
|
||||
echo " put . for current directory>"
|
||||
exit
|
||||
cat <<EOF
|
||||
Usage: unrpm -l package.rpm <List contents of rpm package>
|
||||
unrpm -x package.rpm /foo/boo <Extract rpm package to this directory,
|
||||
put . for current directory>
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
rpm=$2
|
||||
|
||||
exist() {
|
||||
if [ "$rpm" = "" ]; then
|
||||
usage
|
||||
elif [ ! -s "$rpm" ]; then
|
||||
echo "Can't find $rpm!"
|
||||
exit
|
||||
fi
|
||||
if [ -z "${rpm}" ]; then
|
||||
usage
|
||||
elif [ ! -s "${rpm}" ]; then
|
||||
echo "Can't find ${rpm}!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
usage
|
||||
if [ -z "$1" ]; then
|
||||
usage
|
||||
elif [ "$1" = "-l" ]; then
|
||||
exist
|
||||
type more >/dev/null 2>&1 && pager=more
|
||||
type less >/dev/null 2>&1 && pager=less
|
||||
[ "$pager" = "" ] && echo "No pager found!" && exit
|
||||
(echo -e "\nPress enter to scroll, q to Quit!\n" ; rpm2cpio $rpm | cpio -tv --quiet) | $pager
|
||||
exit
|
||||
exist
|
||||
type more >/dev/null 2>&1 && pager=more
|
||||
type less >/dev/null 2>&1 && pager=less
|
||||
[ "$pager" = "" ] && echo "No pager found!" && exit
|
||||
(
|
||||
printf "\nPress enter to scroll, q to Quit!\n\n"
|
||||
rpm2cpio "${rpm}" | cpio -tv --quiet
|
||||
) | ${pager}
|
||||
exit
|
||||
elif [ "$1" = "-x" ]; then
|
||||
exist
|
||||
if [ "$3" = "" ]; then
|
||||
usage
|
||||
elif [ ! -d "$3" ]; then
|
||||
echo "No such directory $3!"
|
||||
exit
|
||||
fi
|
||||
rpm2cpio $rpm | (umask 0 ; cd $3 ; cpio -idmuv) || exit
|
||||
echo
|
||||
echo "Extracted $rpm to $3!"
|
||||
exit
|
||||
exist
|
||||
if [ -z "$3" ]; then
|
||||
usage
|
||||
elif [ ! -d "$3" ]; then
|
||||
echo "No such directory $3!"
|
||||
exit 1
|
||||
fi
|
||||
rpm2cpio "${rpm}" | (umask 0 ; cd "$3" ; cpio -idmuv) || exit
|
||||
echo
|
||||
echo "Extracted ${rpm} to $3!"
|
||||
exit
|
||||
else
|
||||
usage
|
||||
usage
|
||||
fi
|
||||
|
|
|
@ -36,10 +36,10 @@ service accordingly. In effect, it allows you to unplug/plug-to-different-networ
|
|||
and have your IP properly re-negotiated at once.
|
||||
|
||||
var_service/dhcp_if_pinger -
|
||||
Uses var_service/dhcp_if's data (/var/service/dhcp_if/dhcp_if.out file)
|
||||
to determine router IP. Pings it. If ping fails, restarts /var/service/dhcp_if
|
||||
service. Basically, an example of watchdog service for networks
|
||||
which are not reliable and need babysitting.
|
||||
Uses var_service/dhcp_if's data to determine router IP. Pings it.
|
||||
If ping fails, restarts /var/service/dhcp_if service.
|
||||
Basically, an example of watchdog service for networks which are not reliable
|
||||
and need babysitting.
|
||||
|
||||
var_service/fw -
|
||||
A *one-shot* service which reconfigures network based on current known state
|
||||
|
|
|
@ -29,6 +29,6 @@ test "$ip" || exit 1
|
|||
{
|
||||
for n in $ntpsrv; do
|
||||
echo "let cfg=cfg+1"
|
||||
echo "ntpip[\$cfg]='$n'";
|
||||
echo "ntpip[\$cfg]='$n'"
|
||||
done
|
||||
} >"$1"
|
||||
|
|
|
@ -36,7 +36,7 @@ service=${PWD##*/}
|
|||
file_ipconf="$service.ipconf"
|
||||
file_ntpconf="$service.ntpconf"
|
||||
dir_ipconf="/var/run/service/fw"
|
||||
dir_ntpconf="/var/run/service/ntp"
|
||||
dir_ntpconf="/var/run/service/ntpd"
|
||||
|
||||
exec >/dev/null
|
||||
#exec >>"$0.out" #debug
|
||||
|
@ -47,7 +47,7 @@ echo "`date`: Params: $*"
|
|||
if test x"$1" != x"bound" && test x"$1" != x"renew" ; then
|
||||
# Reconfigure network with this interface disabled
|
||||
echo "Deconfiguring"
|
||||
rm "$service.out"
|
||||
rm "env.out"
|
||||
rm "$file_ipconf"
|
||||
rm "$file_ntpconf"
|
||||
rm "$dir_ipconf/$file_ipconf"
|
||||
|
@ -57,7 +57,8 @@ if test x"$1" != x"bound" && test x"$1" != x"renew" ; then
|
|||
fi
|
||||
|
||||
# Bound: we've got the lease
|
||||
#env >"$service.out" # debug
|
||||
# Record information for e.g. dhcp_$IF_pinger service
|
||||
env >"env.out"
|
||||
|
||||
./convert2ipconf "$file_ipconf"
|
||||
# Reconfigure routing and firewall if needed
|
||||
|
@ -69,7 +70,7 @@ if test $? != 0; then
|
|||
sv u /var/service/fw
|
||||
fi
|
||||
|
||||
if test -d /var/service/ntp; then
|
||||
if test -d /var/service/ntpd; then
|
||||
./convert2ntpconf "$file_ntpconf"
|
||||
# Reconfigure ntp server addresses if needed
|
||||
diff --brief "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" >/dev/null 2>&1
|
||||
|
@ -77,7 +78,7 @@ if test -d /var/service/ntp; then
|
|||
echo "Reconfiguring ntp"
|
||||
mkdir -p "$dir_ntpconf" 2>/dev/null
|
||||
cp "$file_ntpconf" "$dir_ntpconf/$file_ntpconf"
|
||||
sv t /var/service/ntp
|
||||
sv u /var/service/ntp
|
||||
sv t /var/service/ntpd
|
||||
sv u /var/service/ntpd
|
||||
fi
|
||||
fi
|
||||
|
|
17
examples/var_service/dhcp_if/finish
Executable file
17
examples/var_service/dhcp_if/finish
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
# executed when service is taken down ("sv d .")
|
||||
|
||||
service=${PWD##*/}
|
||||
file_ipconf="$service.ipconf"
|
||||
file_ntpconf="$service.ntpconf"
|
||||
dir_ipconf="/var/run/service/fw"
|
||||
dir_ntpconf="/var/run/service/ntpd"
|
||||
|
||||
# Reconfigure network with this interface disabled
|
||||
echo "Finish: deconfiguring"
|
||||
rm "env.out"
|
||||
rm "$file_ipconf"
|
||||
rm "$file_ntpconf"
|
||||
rm "$dir_ipconf/$file_ipconf"
|
||||
rm "$dir_ntpconf/$file_ntpconf"
|
||||
sv u /var/service/fw
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -1,23 +1,47 @@
|
|||
#!/bin/sh
|
||||
|
||||
delay=67
|
||||
|
||||
# How often to test, seconds
|
||||
ping_time=67
|
||||
# "One ping, must have reply in 1 sec"
|
||||
ping_opts="-c1 -W1 -w1"
|
||||
# If ping failed, how soon to retry
|
||||
retry_time=5
|
||||
# Reinit after this many consecutive ping error
|
||||
max_fail=5
|
||||
# Interface whose DHCP data to use
|
||||
if=${PWD##*/dhcp_}
|
||||
if=${if%%_pinger}
|
||||
|
||||
msg() {
|
||||
echo "`date '+%Y-%m-%d %H:%M:%S'` $*" >>"$0.log"
|
||||
}
|
||||
|
||||
if test -f "$0.log"; then
|
||||
tail -999 "$0.log" >"$0.log.new"
|
||||
mv "$0.log.new" "$0.log"
|
||||
fi
|
||||
|
||||
test -f "/var/service/dhcp_$if/dhcp_$if.out" || exec env - sleep "$delay"
|
||||
. "/var/service/dhcp_$if/dhcp_$if.out"
|
||||
test x"$router" != x"" || exec env - sleep "$delay"
|
||||
test -f "/var/service/dhcp_$if/env.out" || exec env - sleep "$ping_time"
|
||||
|
||||
#echo "`date '+%Y-%m-%d %H:%M:%S'` Testing ping -c3 $router" >>"$0.log"
|
||||
ping -c3 "$router" && exec env - sleep "$delay"
|
||||
. "/var/service/dhcp_$if/env.out"
|
||||
test x"$router" != x"" || exec env - sleep "$ping_time"
|
||||
|
||||
echo "`date '+%Y-%m-%d %H:%M:%S'` Restarting /var/service/dhcp_$if" >>"$0.log"
|
||||
sv t "/var/service/dhcp_$if"
|
||||
#msg "Pinging $router"
|
||||
failcnt=0
|
||||
while true; do
|
||||
ping $ping_opts "$router" && exec env - sleep "$ping_time"
|
||||
: $((failcnt++))
|
||||
msg "Failed to ping $router, fail count:$failcnt"
|
||||
test $failcnt -ge $max_fail && break
|
||||
env - sleep "$retry_time"
|
||||
done
|
||||
|
||||
exec env - sleep "$delay"
|
||||
test -d "/var/service/dhcp_$if" && {
|
||||
msg "Restarting /var/service/dhcp_$if"
|
||||
sv t "/var/service/dhcp_$if"
|
||||
}
|
||||
test -d "/var/service/supplicant_$if" && {
|
||||
msg "Restarting /var/service/supplicant_$if"
|
||||
sv t "/var/service/supplicant_$if"
|
||||
}
|
||||
exec env - sleep "$ping_time"
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -62,7 +62,7 @@ umask 077
|
|||
|
||||
# Make sure rundir/ exists
|
||||
mkdir -p "$rundir" 2>/dev/null
|
||||
chown -R "$user:" "$rundir"
|
||||
chown -R "$user": "$rundir"
|
||||
chmod -R a=rX "$rundir"
|
||||
rm -rf rundir 2>/dev/null
|
||||
ln -s "$rundir" rundir
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -8,6 +8,9 @@ pwd="$PWD"
|
|||
|
||||
if="${PWD##*/ifplugd_}"
|
||||
|
||||
echo "* Upping iface $if"
|
||||
ip link set dev "$if" up
|
||||
|
||||
echo "* Starting ifplugd on $if [$$]"
|
||||
exec \
|
||||
env - PATH="$PATH" \
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
|
@ -15,7 +15,7 @@ default_p_opt="-p 0.$pool -p 1.$pool -p 2.$pool -p 3.$pool"
|
|||
|
||||
# Make sure rundir/ exists
|
||||
mkdir -p "$rundir" 2>/dev/null
|
||||
chown -R "$user:" "$rundir"
|
||||
chown -R "$user": "$rundir"
|
||||
chmod -R a=rX "$rundir"
|
||||
rm -rf rundir 2>/dev/null
|
||||
ln -s "$rundir" rundir
|
||||
|
|
|
@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
|||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm logdir
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
|
|
5
examples/var_service/zcip_if/README
Normal file
5
examples/var_service/zcip_if/README
Normal file
|
@ -0,0 +1,5 @@
|
|||
The real README file is one directory up.
|
||||
|
||||
This directory's run script can have useful comments.
|
||||
If it doesn't but you feel it should, please send a patch
|
||||
to busybox's mailing list.
|
24
examples/var_service/zcip_if/convert2ipconf
Executable file
24
examples/var_service/zcip_if/convert2ipconf
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
# convert:
|
||||
|
||||
#interface=eth1
|
||||
#ip=169.254.x.y
|
||||
|
||||
# into:
|
||||
|
||||
#let cfg=cfg+1
|
||||
#if[$cfg]=...; ip[$cfg]=...; ipmask[$cfg]=.../...; gw[$cfg]=...; net[$cfg]=... dns[$cfg]=...
|
||||
|
||||
exec >/dev/null
|
||||
#exec >"$0.out" # debug
|
||||
exec 2>&1
|
||||
|
||||
test "$interface" || exit 1
|
||||
test "$ip" || exit 1
|
||||
|
||||
{
|
||||
echo "let cfg=cfg+1"
|
||||
test "$interface" && echo "if[\$cfg]='$interface'"
|
||||
test "$ip" && echo "ip[\$cfg]='$ip'"
|
||||
test "$ip" && echo "ipmask[\$cfg]='$ip/16'"
|
||||
} >"$1"
|
13
examples/var_service/zcip_if/finish
Executable file
13
examples/var_service/zcip_if/finish
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
# executed when service is taken down ("sv d .")
|
||||
|
||||
service=${PWD##*/}
|
||||
file_ipconf="$service.ipconf"
|
||||
dir_ipconf="/var/run/service/fw"
|
||||
|
||||
# Reconfigure network with this interface disabled
|
||||
echo "Finish: deconfiguring"
|
||||
rm "env.out"
|
||||
rm "$file_ipconf"
|
||||
rm "$dir_ipconf/$file_ipconf"
|
||||
sv u /var/service/fw
|
21
examples/var_service/zcip_if/log/run
Executable file
21
examples/var_service/zcip_if/log/run
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
user=logger
|
||||
|
||||
logdir="/var/log/service/`(cd ..;basename $PWD)`"
|
||||
mkdir -p "$logdir" 2>/dev/null
|
||||
chown -R "$user": "$logdir"
|
||||
chmod -R go-rwxst,u+rwX "$logdir"
|
||||
rm -rf logdir
|
||||
ln -s "$logdir" logdir
|
||||
|
||||
# make this dir accessible to logger
|
||||
chmod a+rX .
|
||||
|
||||
exec >/dev/null
|
||||
exec 2>&1
|
||||
exec \
|
||||
env - PATH="$PATH" \
|
||||
softlimit \
|
||||
setuidgid "$user" \
|
||||
svlogd -tt "$logdir"
|
4
examples/var_service/zcip_if/p_log
Executable file
4
examples/var_service/zcip_if/p_log
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd log/logdir || exit 1
|
||||
cat @* current | $PAGER
|
20
examples/var_service/zcip_if/run
Executable file
20
examples/var_service/zcip_if/run
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
exec 2>&1
|
||||
exec </dev/null
|
||||
|
||||
pwd="$PWD"
|
||||
|
||||
if="${PWD##*/zcip_}"
|
||||
|
||||
echo "* Upping iface $if"
|
||||
ip link set dev "$if" up
|
||||
|
||||
echo "* Starting zcip"
|
||||
exec \
|
||||
env - PATH="$PATH" \
|
||||
softlimit \
|
||||
setuidgid root \
|
||||
zcip -fvv \
|
||||
"$if" \
|
||||
"$pwd/zcip_handler"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user