diff options
author | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:28:08 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:58:55 +0100 |
commit | 613f46218c53c8cabdbf0435653e74e0e0e91e1c (patch) | |
tree | ca06a7e7a3e4c861441acb4ea20648d7827fa6ae /libbb | |
parent | a0c61c9492723dd31681f878f9c68c92817a476d (diff) | |
parent | 237bedd499c58034a1355484d6d4d906f0180308 (diff) | |
download | busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.gz busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.bz2 busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Kbuild.src | 1 | ||||
-rw-r--r-- | libbb/appletlib.c | 63 | ||||
-rw-r--r-- | libbb/copy_file.c | 21 | ||||
-rw-r--r-- | libbb/getopt32.c | 82 | ||||
-rw-r--r-- | libbb/parse_config.c | 4 | ||||
-rw-r--r-- | libbb/time.c | 1 |
6 files changed, 119 insertions, 53 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 0e14e351e..39d9d907d 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -148,6 +148,7 @@ lib-$(CONFIG_FTPD) += correct_password.o | |||
148 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o | 148 | lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o |
149 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o | 149 | lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o |
150 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o | 150 | lib-$(CONFIG_CRYPTPW) += pw_encrypt.o |
151 | lib-$(CONFIG_MKPASSWD) += pw_encrypt.o | ||
151 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o | 152 | lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o |
152 | lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o | 153 | lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o |
153 | lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o | 154 | lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index c528c8a2c..28adf2740 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -52,7 +52,6 @@ | |||
52 | 52 | ||
53 | #include "usage_compressed.h" | 53 | #include "usage_compressed.h" |
54 | 54 | ||
55 | |||
56 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE | 55 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE |
57 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | 56 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; |
58 | #else | 57 | #else |
@@ -730,7 +729,7 @@ static void install_links(const char *busybox, | |||
730 | } | 729 | } |
731 | } | 730 | } |
732 | # endif | 731 | # endif |
733 | # else | 732 | # elif ENABLE_BUSYBOX |
734 | static void install_links(const char *busybox UNUSED_PARAM, | 733 | static void install_links(const char *busybox UNUSED_PARAM, |
735 | int use_symbolic_links UNUSED_PARAM, | 734 | int use_symbolic_links UNUSED_PARAM, |
736 | char *custom_install_dir UNUSED_PARAM) | 735 | char *custom_install_dir UNUSED_PARAM) |
@@ -738,6 +737,9 @@ static void install_links(const char *busybox UNUSED_PARAM, | |||
738 | } | 737 | } |
739 | # endif | 738 | # endif |
740 | 739 | ||
740 | # if ENABLE_BUSYBOX | ||
741 | static void run_applet_and_exit(const char *name, char **argv) NORETURN; | ||
742 | |||
741 | /* If we were called as "busybox..." */ | 743 | /* If we were called as "busybox..." */ |
742 | static int busybox_main(char **argv) | 744 | static int busybox_main(char **argv) |
743 | { | 745 | { |
@@ -828,10 +830,10 @@ static int busybox_main(char **argv) | |||
828 | const char *a = applet_names; | 830 | const char *a = applet_names; |
829 | dup2(1, 2); | 831 | dup2(1, 2); |
830 | while (*a) { | 832 | while (*a) { |
831 | # if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32 | 833 | # if ENABLE_FEATURE_INSTALLER && !ENABLE_PLATFORM_MINGW32 |
832 | if (argv[1][6]) /* --list-full? */ | 834 | if (argv[1][6]) /* --list-full? */ |
833 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | 835 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); |
834 | # endif | 836 | # endif |
835 | full_write2_str(a); | 837 | full_write2_str(a); |
836 | full_write2_str("\n"); | 838 | full_write2_str("\n"); |
837 | i++; | 839 | i++; |
@@ -889,14 +891,10 @@ static int busybox_main(char **argv) | |||
889 | * "#!/bin/busybox"-style wrappers */ | 891 | * "#!/bin/busybox"-style wrappers */ |
890 | applet_name = bb_get_last_path_component_nostrip(argv[0]); | 892 | applet_name = bb_get_last_path_component_nostrip(argv[0]); |
891 | run_applet_and_exit(applet_name, argv); | 893 | run_applet_and_exit(applet_name, argv); |
892 | |||
893 | /*bb_error_msg_and_die("applet not found"); - sucks in printf */ | ||
894 | full_write2_str(applet_name); | ||
895 | full_write2_str(": applet not found\n"); | ||
896 | /* POSIX: "If a command is not found, the exit status shall be 127" */ | ||
897 | exit(127); | ||
898 | } | 894 | } |
895 | # endif | ||
899 | 896 | ||
897 | # if NUM_APPLETS > 0 | ||
900 | void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | 898 | void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) |
901 | { | 899 | { |
902 | int argc = 1; | 900 | int argc = 1; |
@@ -914,15 +912,15 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | |||
914 | * "true" and "false" are also special. | 912 | * "true" and "false" are also special. |
915 | */ | 913 | */ |
916 | if (1 | 914 | if (1 |
917 | #if defined APPLET_NO_test | 915 | # if defined APPLET_NO_test |
918 | && applet_no != APPLET_NO_test | 916 | && applet_no != APPLET_NO_test |
919 | #endif | 917 | # endif |
920 | #if defined APPLET_NO_true | 918 | # if defined APPLET_NO_true |
921 | && applet_no != APPLET_NO_true | 919 | && applet_no != APPLET_NO_true |
922 | #endif | 920 | # endif |
923 | #if defined APPLET_NO_false | 921 | # if defined APPLET_NO_false |
924 | && applet_no != APPLET_NO_false | 922 | && applet_no != APPLET_NO_false |
925 | #endif | 923 | # endif |
926 | ) { | 924 | ) { |
927 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { | 925 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { |
928 | /* Make "foo --help" exit with 0: */ | 926 | /* Make "foo --help" exit with 0: */ |
@@ -934,17 +932,28 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) | |||
934 | check_suid(applet_no); | 932 | check_suid(applet_no); |
935 | exit(applet_main[applet_no](argc, argv)); | 933 | exit(applet_main[applet_no](argc, argv)); |
936 | } | 934 | } |
935 | # endif /* NUM_APPLETS > 0 */ | ||
937 | 936 | ||
938 | void FAST_FUNC run_applet_and_exit(const char *name, char **argv) | 937 | static NORETURN void run_applet_and_exit(const char *name, char **argv) |
939 | { | 938 | { |
940 | int applet; | 939 | # if ENABLE_BUSYBOX |
941 | |||
942 | if (is_prefixed_with(name, "busybox")) | 940 | if (is_prefixed_with(name, "busybox")) |
943 | exit(busybox_main(argv)); | 941 | exit(busybox_main(argv)); |
942 | # endif | ||
943 | # if NUM_APPLETS > 0 | ||
944 | /* find_applet_by_name() search is more expensive, so goes second */ | 944 | /* find_applet_by_name() search is more expensive, so goes second */ |
945 | applet = find_applet_by_name(name); | 945 | { |
946 | if (applet >= 0) | 946 | int applet = find_applet_by_name(name); |
947 | run_applet_no_and_exit(applet, argv); | 947 | if (applet >= 0) |
948 | run_applet_no_and_exit(applet, argv); | ||
949 | } | ||
950 | # endif | ||
951 | |||
952 | /*bb_error_msg_and_die("applet not found"); - links in printf */ | ||
953 | full_write2_str(applet_name); | ||
954 | full_write2_str(": applet not found\n"); | ||
955 | /* POSIX: "If a command is not found, the exit status shall be 127" */ | ||
956 | exit(127); | ||
948 | } | 957 | } |
949 | 958 | ||
950 | #endif /* !defined(SINGLE_APPLET_MAIN) */ | 959 | #endif /* !defined(SINGLE_APPLET_MAIN) */ |
@@ -1017,6 +1026,10 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1017 | #else | 1026 | #else |
1018 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); | 1027 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); |
1019 | 1028 | ||
1029 | # if !ENABLE_BUSYBOX | ||
1030 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) | ||
1031 | argv++; | ||
1032 | # endif | ||
1020 | applet_name = argv[0]; | 1033 | applet_name = argv[0]; |
1021 | if (applet_name[0] == '-') | 1034 | if (applet_name[0] == '-') |
1022 | applet_name++; | 1035 | applet_name++; |
@@ -1048,11 +1061,5 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1048 | parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ | 1061 | parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ |
1049 | 1062 | ||
1050 | run_applet_and_exit(applet_name, argv); | 1063 | run_applet_and_exit(applet_name, argv); |
1051 | |||
1052 | /*bb_error_msg_and_die("applet not found"); - sucks in printf */ | ||
1053 | full_write2_str(applet_name); | ||
1054 | full_write2_str(": applet not found\n"); | ||
1055 | /* POSIX: "If a command is not found, the exit status shall be 127" */ | ||
1056 | exit(127); | ||
1057 | #endif | 1064 | #endif |
1058 | } | 1065 | } |
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index a427c441f..c52297376 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
@@ -64,6 +64,11 @@ static int ask_and_unlink(const char *dest, int flags) | |||
64 | bb_perror_msg("can't create '%s'", dest); | 64 | bb_perror_msg("can't create '%s'", dest); |
65 | return -1; /* error */ | 65 | return -1; /* error */ |
66 | } | 66 | } |
67 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | ||
68 | if (flags & FILEUTILS_RMDEST) | ||
69 | if (flags & FILEUTILS_VERBOSE) | ||
70 | printf("removed '%s'\n", dest); | ||
71 | #endif | ||
67 | return 1; /* ok (to try again) */ | 72 | return 1; /* ok (to try again) */ |
68 | } | 73 | } |
69 | 74 | ||
@@ -213,6 +218,22 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) | |||
213 | goto preserve_mode_ugid_time; | 218 | goto preserve_mode_ugid_time; |
214 | } | 219 | } |
215 | 220 | ||
221 | if (dest_exists) { | ||
222 | if (flags & FILEUTILS_UPDATE) { | ||
223 | if (source_stat.st_mtime <= dest_stat.st_mtime) { | ||
224 | return 0; /* source file must be newer */ | ||
225 | } | ||
226 | } | ||
227 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | ||
228 | if (flags & FILEUTILS_RMDEST) { | ||
229 | ovr = ask_and_unlink(dest, flags); | ||
230 | if (ovr <= 0) | ||
231 | return ovr; | ||
232 | dest_exists = 0; | ||
233 | } | ||
234 | #endif | ||
235 | } | ||
236 | |||
216 | if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { | 237 | if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { |
217 | int (*lf)(const char *oldpath, const char *newpath); | 238 | int (*lf)(const char *oldpath, const char *newpath); |
218 | make_links: | 239 | make_links: |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index ae019b26b..ed9352191 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -17,23 +17,20 @@ | |||
17 | uint32_t | 17 | uint32_t |
18 | getopt32(char **argv, const char *applet_opts, ...) | 18 | getopt32(char **argv, const char *applet_opts, ...) |
19 | 19 | ||
20 | The command line options must be declared in const char | 20 | The command line options are passed as the applet_opts string. |
21 | *applet_opts as a string of chars, for example: | ||
22 | |||
23 | flags = getopt32(argv, "rnug"); | ||
24 | 21 | ||
25 | If one of the given options is found, a flag value is added to | 22 | If one of the given options is found, a flag value is added to |
26 | the return value (an unsigned long). | 23 | the return value. |
27 | 24 | ||
28 | The flag value is determined by the position of the char in | 25 | The flag value is determined by the position of the char in |
29 | applet_opts string. For example, in the above case: | 26 | applet_opts string. For example: |
30 | 27 | ||
31 | flags = getopt32(argv, "rnug"); | 28 | flags = getopt32(argv, "rnug"); |
32 | 29 | ||
33 | "r" will add 1 (bit 0) | 30 | "r" will set 1 (bit 0) |
34 | "n" will add 2 (bit 1) | 31 | "n" will set 2 (bit 1) |
35 | "u" will add 4 (bit 2) | 32 | "u" will set 4 (bit 2) |
36 | "g" will add 8 (bit 3) | 33 | "g" will set 8 (bit 3) |
37 | 34 | ||
38 | and so on. You can also look at the return value as a bit | 35 | and so on. You can also look at the return value as a bit |
39 | field and each option sets one bit. | 36 | field and each option sets one bit. |
@@ -45,7 +42,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
45 | (options and their parameters will be moved into argv[] | 42 | (options and their parameters will be moved into argv[] |
46 | positions prior to argv[optind]). | 43 | positions prior to argv[optind]). |
47 | 44 | ||
48 | ":" If one of the options requires an argument, then add a ":" | 45 | "o:" If one of the options requires an argument, then add a ":" |
49 | after the char in applet_opts and provide a pointer to store | 46 | after the char in applet_opts and provide a pointer to store |
50 | the argument. For example: | 47 | the argument. For example: |
51 | 48 | ||
@@ -58,15 +55,39 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
58 | &pointer_to_arg_for_a, &pointer_to_arg_for_b, | 55 | &pointer_to_arg_for_a, &pointer_to_arg_for_b, |
59 | &pointer_to_arg_for_c, &pointer_to_arg_for_d); | 56 | &pointer_to_arg_for_c, &pointer_to_arg_for_d); |
60 | 57 | ||
61 | The type of the pointer (char* or llist_t*) may be controlled | 58 | The type of the pointer may be controlled by "o::" or "o+" in |
62 | by the "::" special separator that is set in the external string | 59 | the external string opt_complementary (see below for more info). |
63 | opt_complementary (see below for more info). | ||
64 | 60 | ||
65 | "::" If option can have an *optional* argument, then add a "::" | 61 | "o::" If option can have an *optional* argument, then add a "::" |
66 | after its char in applet_opts and provide a pointer to store | 62 | after its char in applet_opts and provide a pointer to store |
67 | the argument. Note that optional arguments _must_ | 63 | the argument. Note that optional arguments _must_ |
68 | immediately follow the option: -oparam, not -o param. | 64 | immediately follow the option: -oparam, not -o param. |
69 | 65 | ||
66 | "o:+" This means that the parameter for this option is a nonnegative integer. | ||
67 | It will be processed with xatoi_positive() - allowed range | ||
68 | is 0..INT_MAX. | ||
69 | |||
70 | int param; // "unsigned param;" will also work | ||
71 | getopt32(argv, "p:+", ¶m); | ||
72 | |||
73 | "o:*" This means that the option can occur multiple times. Each occurrence | ||
74 | will be saved as a llist_t element instead of char*. | ||
75 | |||
76 | For example: | ||
77 | The grep applet can have one or more "-e pattern" arguments. | ||
78 | In this case you should use getopt32() as follows: | ||
79 | |||
80 | llist_t *patterns = NULL; | ||
81 | |||
82 | (this pointer must be initializated to NULL if the list is empty | ||
83 | as required by llist_add_to_end(llist_t **old_head, char *new_item).) | ||
84 | |||
85 | getopt32(argv, "e:*", &patterns); | ||
86 | |||
87 | $ grep -e user -e root /etc/passwd | ||
88 | root:x:0:0:root:/root:/bin/bash | ||
89 | user:x:500:500::/home/user:/bin/bash | ||
90 | |||
70 | "+" If the first character in the applet_opts string is a plus, | 91 | "+" If the first character in the applet_opts string is a plus, |
71 | then option processing will stop as soon as a non-option is | 92 | then option processing will stop as soon as a non-option is |
72 | encountered in the argv array. Useful for applets like env | 93 | encountered in the argv array. Useful for applets like env |
@@ -82,7 +103,7 @@ const char *applet_long_options | |||
82 | This struct allows you to define long options: | 103 | This struct allows you to define long options: |
83 | 104 | ||
84 | static const char applet_longopts[] ALIGN1 = | 105 | static const char applet_longopts[] ALIGN1 = |
85 | //"name\0" has_arg val | 106 | //"name\0" has_arg val |
86 | "verbose\0" No_argument "v" | 107 | "verbose\0" No_argument "v" |
87 | ; | 108 | ; |
88 | applet_long_options = applet_longopts; | 109 | applet_long_options = applet_longopts; |
@@ -90,7 +111,7 @@ const char *applet_long_options | |||
90 | The last member of struct option (val) typically is set to | 111 | The last member of struct option (val) typically is set to |
91 | matching short option from applet_opts. If there is no matching | 112 | matching short option from applet_opts. If there is no matching |
92 | char in applet_opts, then: | 113 | char in applet_opts, then: |
93 | - return bit have next position after short options | 114 | - return bit has next position after short options |
94 | - if has_arg is not "No_argument", use ptr for arg also | 115 | - if has_arg is not "No_argument", use ptr for arg also |
95 | - opt_complementary affects it too | 116 | - opt_complementary affects it too |
96 | 117 | ||
@@ -139,8 +160,8 @@ const char *opt_complementary | |||
139 | 160 | ||
140 | llist_t *my_b = NULL; | 161 | llist_t *my_b = NULL; |
141 | int verbose_level = 0; | 162 | int verbose_level = 0; |
142 | opt_complementary = "vv:b::b-c:c-b"; | 163 | opt_complementary = "vv:b-c:c-b"; |
143 | f = getopt32(argv, "vb:c", &my_b, &verbose_level); | 164 | f = getopt32(argv, "vb:*c", &my_b, &verbose_level); |
144 | if (f & 2) // -c after -b unsets -b flag | 165 | if (f & 2) // -c after -b unsets -b flag |
145 | while (my_b) dosomething_with(llist_pop(&my_b)); | 166 | while (my_b) dosomething_with(llist_pop(&my_b)); |
146 | if (my_b) // but llist is stored if -b is specified | 167 | if (my_b) // but llist is stored if -b is specified |
@@ -233,7 +254,7 @@ Special characters: | |||
233 | "x--x" Variation of the above, it means that -x option should occur | 254 | "x--x" Variation of the above, it means that -x option should occur |
234 | at most once. | 255 | at most once. |
235 | 256 | ||
236 | "a+" A plus after a char in opt_complementary means that the parameter | 257 | "o+" A plus after a char in opt_complementary means that the parameter |
237 | for this option is a nonnegative integer. It will be processed | 258 | for this option is a nonnegative integer. It will be processed |
238 | with xatoi_positive() - allowed range is 0..INT_MAX. | 259 | with xatoi_positive() - allowed range is 0..INT_MAX. |
239 | 260 | ||
@@ -241,7 +262,7 @@ Special characters: | |||
241 | opt_complementary = "p+"; | 262 | opt_complementary = "p+"; |
242 | getopt32(argv, "p:", ¶m); | 263 | getopt32(argv, "p:", ¶m); |
243 | 264 | ||
244 | "a::" A double colon after a char in opt_complementary means that the | 265 | "o::" A double colon after a char in opt_complementary means that the |
245 | option can occur multiple times. Each occurrence will be saved as | 266 | option can occur multiple times. Each occurrence will be saved as |
246 | a llist_t element instead of char*. | 267 | a llist_t element instead of char*. |
247 | 268 | ||
@@ -255,12 +276,17 @@ Special characters: | |||
255 | as required by llist_add_to_end(llist_t **old_head, char *new_item).) | 276 | as required by llist_add_to_end(llist_t **old_head, char *new_item).) |
256 | 277 | ||
257 | opt_complementary = "e::"; | 278 | opt_complementary = "e::"; |
258 | |||
259 | getopt32(argv, "e:", &patterns); | 279 | getopt32(argv, "e:", &patterns); |
280 | |||
260 | $ grep -e user -e root /etc/passwd | 281 | $ grep -e user -e root /etc/passwd |
261 | root:x:0:0:root:/root:/bin/bash | 282 | root:x:0:0:root:/root:/bin/bash |
262 | user:x:500:500::/home/user:/bin/bash | 283 | user:x:500:500::/home/user:/bin/bash |
263 | 284 | ||
285 | "o+" and "o::" can be handled by "o:+" and "o:*" specifiers | ||
286 | in option string (and it is preferred), but this does not work | ||
287 | for "long options only" cases, such as tar --exclude=PATTERN, | ||
288 | wget --header=HDR cases. | ||
289 | |||
264 | "a?b" A "?" between an option and a group of options means that | 290 | "a?b" A "?" between an option and a group of options means that |
265 | at least one of them is required to occur if the first option | 291 | at least one of them is required to occur if the first option |
266 | occurs in preceding command line arguments. | 292 | occurs in preceding command line arguments. |
@@ -359,10 +385,11 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
359 | 385 | ||
360 | va_start(p, applet_opts); | 386 | va_start(p, applet_opts); |
361 | 387 | ||
362 | c = 0; | ||
363 | on_off = complementary; | 388 | on_off = complementary; |
364 | memset(on_off, 0, sizeof(complementary)); | 389 | memset(on_off, 0, sizeof(complementary)); |
365 | 390 | ||
391 | applet_opts = strcpy(alloca(strlen(applet_opts) + 1), applet_opts); | ||
392 | |||
366 | /* skip bbox extension */ | 393 | /* skip bbox extension */ |
367 | first_char = applet_opts[0]; | 394 | first_char = applet_opts[0]; |
368 | if (first_char == '!') | 395 | if (first_char == '!') |
@@ -372,6 +399,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
372 | s = (const unsigned char *)applet_opts; | 399 | s = (const unsigned char *)applet_opts; |
373 | if (*s == '+' || *s == '-') | 400 | if (*s == '+' || *s == '-') |
374 | s++; | 401 | s++; |
402 | c = 0; | ||
375 | while (*s) { | 403 | while (*s) { |
376 | if (c >= 32) | 404 | if (c >= 32) |
377 | break; | 405 | break; |
@@ -379,6 +407,13 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
379 | on_off->switch_on = (1 << c); | 407 | on_off->switch_on = (1 << c); |
380 | if (*++s == ':') { | 408 | if (*++s == ':') { |
381 | on_off->optarg = va_arg(p, void **); | 409 | on_off->optarg = va_arg(p, void **); |
410 | if (s[1] == '+' || s[1] == '*') { | ||
411 | /* 'o:+' or 'o:*' */ | ||
412 | on_off->param_type = (s[1] == '+') ? | ||
413 | PARAM_INT : PARAM_LIST; | ||
414 | overlapping_strcpy((char*)s + 1, (char*)s + 2); | ||
415 | } | ||
416 | /* skip possible 'o::' (or 'o:+:' !) */ | ||
382 | while (*++s == ':') | 417 | while (*++s == ':') |
383 | continue; | 418 | continue; |
384 | } | 419 | } |
@@ -431,6 +466,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
431 | applet_long_options = NULL; | 466 | applet_long_options = NULL; |
432 | } | 467 | } |
433 | #endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */ | 468 | #endif /* ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG */ |
469 | |||
434 | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { | 470 | for (s = (const unsigned char *)opt_complementary; s && *s; s++) { |
435 | t_complementary *pair; | 471 | t_complementary *pair; |
436 | unsigned *pair_switch; | 472 | unsigned *pair_switch; |
diff --git a/libbb/parse_config.c b/libbb/parse_config.c index 1590d9a4c..408439766 100644 --- a/libbb/parse_config.c +++ b/libbb/parse_config.c | |||
@@ -42,8 +42,8 @@ int parse_main(int argc UNUSED_PARAM, char **argv) | |||
42 | int mintokens = 0, ntokens = 128; | 42 | int mintokens = 0, ntokens = 128; |
43 | unsigned noout; | 43 | unsigned noout; |
44 | 44 | ||
45 | opt_complementary = "-1:n+:m+:f+"; | 45 | opt_complementary = "-1"; |
46 | noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags); | 46 | noout = 1 & getopt32(argv, "xn:+m:+d:f:+", &ntokens, &mintokens, &delims, &flags); |
47 | //argc -= optind; | 47 | //argc -= optind; |
48 | argv += optind; | 48 | argv += optind; |
49 | 49 | ||
diff --git a/libbb/time.c b/libbb/time.c index aa19a47d4..82e6cb172 100644 --- a/libbb/time.c +++ b/libbb/time.c | |||
@@ -186,6 +186,7 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) | |||
186 | } else { | 186 | } else { |
187 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | 187 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
188 | } | 188 | } |
189 | ptm->tm_sec = 0; /* assume zero if [.SS] is not given */ | ||
189 | if (end == '.') { | 190 | if (end == '.') { |
190 | /* xxx.SS */ | 191 | /* xxx.SS */ |
191 | if (sscanf(strchr(date_str, '.') + 1, "%u%c", | 192 | if (sscanf(strchr(date_str, '.') + 1, "%u%c", |