aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--miscutils/dc.c57
-rw-r--r--modutils/modinfo.c2
-rw-r--r--modutils/modprobe-small.c75
-rw-r--r--networking/wget.c98
5 files changed, 150 insertions, 84 deletions
diff --git a/Makefile b/Makefile
index d449fa511..4b81cb157 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
1VERSION = 1 1VERSION = 1
2PATCHLEVEL = 23 2PATCHLEVEL = 23
3SUBLEVEL = 1 3SUBLEVEL = 2
4EXTRAVERSION = 4EXTRAVERSION =
5NAME = Unnamed 5NAME = Unnamed
6 6
diff --git a/miscutils/dc.c b/miscutils/dc.c
index 6bcfbe249..a7bd360d2 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -196,14 +196,6 @@ struct op {
196}; 196};
197 197
198static const struct op operators[] = { 198static const struct op operators[] = {
199 {"+", add},
200 {"add", add},
201 {"-", sub},
202 {"sub", sub},
203 {"*", mul},
204 {"mul", mul},
205 {"/", divide},
206 {"div", divide},
207#if ENABLE_FEATURE_DC_LIBM 199#if ENABLE_FEATURE_DC_LIBM
208 {"**", power}, 200 {"**", power},
209 {"exp", power}, 201 {"exp", power},
@@ -216,28 +208,47 @@ static const struct op operators[] = {
216 {"not", not}, 208 {"not", not},
217 {"eor", eor}, 209 {"eor", eor},
218 {"xor", eor}, 210 {"xor", eor},
211 {"+", add},
212 {"add", add},
213 {"-", sub},
214 {"sub", sub},
215 {"*", mul},
216 {"mul", mul},
217 {"/", divide},
218 {"div", divide},
219 {"p", print_no_pop}, 219 {"p", print_no_pop},
220 {"f", print_stack_no_pop}, 220 {"f", print_stack_no_pop},
221 {"o", set_output_base}, 221 {"o", set_output_base},
222}; 222};
223 223
224/* Feed the stack machine */
224static void stack_machine(const char *argument) 225static void stack_machine(const char *argument)
225{ 226{
226 char *end; 227 char *end;
227 double d; 228 double number;
228 const struct op *o; 229 const struct op *o;
229 230
230 d = strtod(argument, &end); 231 next:
231 if (end != argument && *end == '\0') { 232 number = strtod(argument, &end);
232 push(d); 233 if (end != argument) {
233 return; 234 argument = end;
235 push(number);
236 goto next;
234 } 237 }
235 238
239 /* We might have matched a digit, eventually advance the argument */
240 argument = skip_whitespace(argument);
241
242 if (*argument == '\0')
243 return;
244
236 o = operators; 245 o = operators;
237 do { 246 do {
238 if (strcmp(o->name, argument) == 0) { 247 const size_t name_len = strlen(o->name);
248 if (strncmp(o->name, argument, name_len) == 0) {
249 argument += name_len;
239 o->function(); 250 o->function();
240 return; 251 goto next;
241 } 252 }
242 o++; 253 o++;
243 } while (o != operators + ARRAY_SIZE(operators)); 254 } while (o != operators + ARRAY_SIZE(operators));
@@ -254,25 +265,11 @@ int dc_main(int argc UNUSED_PARAM, char **argv)
254 if (!argv[0]) { 265 if (!argv[0]) {
255 /* take stuff from stdin if no args are given */ 266 /* take stuff from stdin if no args are given */
256 char *line; 267 char *line;
257 char *cursor;
258 char *token;
259 while ((line = xmalloc_fgetline(stdin)) != NULL) { 268 while ((line = xmalloc_fgetline(stdin)) != NULL) {
260 cursor = line; 269 stack_machine(line);
261 while (1) {
262 token = skip_whitespace(cursor);
263 if (*token == '\0')
264 break;
265 cursor = skip_non_whitespace(token);
266 if (*cursor != '\0')
267 *cursor++ = '\0';
268 stack_machine(token);
269 }
270 free(line); 270 free(line);
271 } 271 }
272 } else { 272 } else {
273 // why? it breaks "dc -2 2 + p"
274 //if (argv[0][0] == '-')
275 // bb_show_usage();
276 do { 273 do {
277 stack_machine(*argv); 274 stack_machine(*argv);
278 } while (*++argv); 275 } while (*++argv);
diff --git a/modutils/modinfo.c b/modutils/modinfo.c
index 0ab942890..ee379304c 100644
--- a/modutils/modinfo.c
+++ b/modutils/modinfo.c
@@ -154,7 +154,7 @@ int modinfo_main(int argc UNUSED_PARAM, char **argv)
154 if (colon == NULL) 154 if (colon == NULL)
155 continue; 155 continue;
156 *colon = '\0'; 156 *colon = '\0';
157 filename2modname(tokens[0], name); 157 filename2modname(bb_basename(tokens[0]), name);
158 for (i = 0; argv[i]; i++) { 158 for (i = 0; argv[i]; i++) {
159 if (fnmatch(argv[i], name, 0) == 0) { 159 if (fnmatch(argv[i], name, 0) == 0) {
160 modinfo(tokens[0], uts.release, &env); 160 modinfo(tokens[0], uts.release, &env);
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index cf8a3f0fe..e6d43229c 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -552,9 +552,23 @@ static int already_loaded(const char *name)
552 return ret; 552 return ret;
553} 553}
554#else 554#else
555#define already_loaded(name) is_rmmod 555#define already_loaded(name) 0
556#endif 556#endif
557 557
558static int rmmod(const char *filename)
559{
560 int r;
561 char modname[MODULE_NAME_LEN];
562
563 filename2modname(filename, modname);
564 r = delete_module(modname, O_NONBLOCK | O_EXCL);
565 dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
566 if (r != 0 && !(option_mask32 & OPT_q)) {
567 bb_perror_msg("remove '%s'", modname);
568 }
569 return r;
570}
571
558/* 572/*
559 * Given modules definition and module name (or alias, or symbol) 573 * Given modules definition and module name (or alias, or symbol)
560 * load/remove the module respecting dependencies. 574 * load/remove the module respecting dependencies.
@@ -571,26 +585,36 @@ static void process_module(char *name, const char *cmdline_options)
571 module_info **infovec; 585 module_info **infovec;
572 module_info *info; 586 module_info *info;
573 int infoidx; 587 int infoidx;
574 int is_rmmod = (option_mask32 & OPT_r) != 0; 588 int is_remove = (option_mask32 & OPT_r) != 0;
575 589
576 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); 590 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);
577 591
578 replace(name, '-', '_'); 592 replace(name, '-', '_');
579 593
580 dbg1_error_msg("already_loaded:%d is_rmmod:%d", already_loaded(name), is_rmmod); 594 dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove);
595
596 if (applet_name[0] == 'r') {
597 /* rmmod.
598 * Does not remove dependencies, no need to scan, just remove.
599 * (compat note: this allows and strips .ko suffix)
600 */
601 rmmod(name);
602 return;
603 }
604
581 /* 605 /*
582 * We used to have "is_rmmod != already_loaded(name)" check here, but 606 * We used to have "is_remove != already_loaded(name)" check here, but
583 * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80 607 * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80
584 * won't unload modules (there are more than one) 608 * won't unload modules (there are more than one)
585 * which have this alias. 609 * which have this alias.
586 */ 610 */
587 if (!is_rmmod && already_loaded(name)) { 611 if (!is_remove && already_loaded(name)) {
588 dbg1_error_msg("nothing to do for '%s'", name); 612 dbg1_error_msg("nothing to do for '%s'", name);
589 return; 613 return;
590 } 614 }
591 615
592 options = NULL; 616 options = NULL;
593 if (!is_rmmod) { 617 if (!is_remove) {
594 char *opt_filename = xasprintf("/etc/modules/%s", name); 618 char *opt_filename = xasprintf("/etc/modules/%s", name);
595 options = xmalloc_open_read_close(opt_filename, NULL); 619 options = xmalloc_open_read_close(opt_filename, NULL);
596 if (options) 620 if (options)
@@ -624,7 +648,7 @@ static void process_module(char *name, const char *cmdline_options)
624 0 /* depth */ 648 0 /* depth */
625 ); 649 );
626 dbg1_error_msg("dirscan complete"); 650 dbg1_error_msg("dirscan complete");
627 /* Module was not found, or load failed, or is_rmmod */ 651 /* Module was not found, or load failed, or is_remove */
628 if (module_found_idx >= 0) { /* module was found */ 652 if (module_found_idx >= 0) { /* module was found */
629 infovec = xzalloc(2 * sizeof(infovec[0])); 653 infovec = xzalloc(2 * sizeof(infovec[0]));
630 infovec[0] = &modinfo[module_found_idx]; 654 infovec[0] = &modinfo[module_found_idx];
@@ -637,7 +661,7 @@ static void process_module(char *name, const char *cmdline_options)
637 661
638 if (!infovec) { 662 if (!infovec) {
639 /* both dirscan and find_alias found nothing */ 663 /* both dirscan and find_alias found nothing */
640 if (!is_rmmod && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ 664 if (!is_remove && applet_name[0] != 'd') /* it wasn't rmmod or depmod */
641 bb_error_msg("module '%s' not found", name); 665 bb_error_msg("module '%s' not found", name);
642//TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? 666//TODO: _and_die()? or should we continue (un)loading modules listed on cmdline?
643 goto ret; 667 goto ret;
@@ -651,29 +675,15 @@ static void process_module(char *name, const char *cmdline_options)
651 * a *list* of modinfo pointers from find_alias(). 675 * a *list* of modinfo pointers from find_alias().
652 */ 676 */
653 677
654 /* rmmod or modprobe -r? unload module(s) */ 678 /* modprobe -r? unload module(s) */
655 if (is_rmmod) { 679 if (is_remove) {
656 infoidx = 0; 680 infoidx = 0;
657 while ((info = infovec[infoidx++]) != NULL) { 681 while ((info = infovec[infoidx++]) != NULL) {
658 int r; 682 int r = rmmod(bb_get_last_path_component_nostrip(info->pathname));
659 char modname[MODULE_NAME_LEN];
660
661 filename2modname(
662 bb_get_last_path_component_nostrip(info->pathname), modname);
663 r = delete_module(modname, O_NONBLOCK | O_EXCL);
664 dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
665 if (r != 0) { 683 if (r != 0) {
666 if (!(option_mask32 & OPT_q)) 684 goto ret; /* error */
667 bb_perror_msg("remove '%s'", modname);
668 goto ret;
669 } 685 }
670 } 686 }
671
672 if (applet_name[0] == 'r') {
673 /* rmmod: do not remove dependencies, exit */
674 goto ret;
675 }
676
677 /* modprobe -r: we do not stop here - 687 /* modprobe -r: we do not stop here -
678 * continue to unload modules on which the module depends: 688 * continue to unload modules on which the module depends:
679 * "-r --remove: option causes modprobe to remove a module. 689 * "-r --remove: option causes modprobe to remove a module.
@@ -694,7 +704,7 @@ static void process_module(char *name, const char *cmdline_options)
694 } 704 }
695 free(deps); 705 free(deps);
696 706
697 if (is_rmmod) 707 if (is_remove)
698 continue; 708 continue;
699 709
700 /* We are modprobe: load it */ 710 /* We are modprobe: load it */
@@ -897,10 +907,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
897 } 907 }
898 908
899#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE 909#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
900 /* If not rmmod, parse possible module options given on command line. 910 /* If not rmmod/-r, parse possible module options given on command line.
901 * insmod/modprobe takes one module name, the rest are parameters. */ 911 * insmod/modprobe takes one module name, the rest are parameters. */
902 options = NULL; 912 options = NULL;
903 if ('r' != applet0) { 913 if (!(option_mask32 & OPT_r)) {
904 char **arg = argv; 914 char **arg = argv;
905 while (*++arg) { 915 while (*++arg) {
906 /* Enclose options in quotes */ 916 /* Enclose options in quotes */
@@ -911,7 +921,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
911 } 921 }
912 } 922 }
913#else 923#else
914 if ('r' != applet0) 924 if (!(option_mask32 & OPT_r))
915 argv[1] = NULL; 925 argv[1] = NULL;
916#endif 926#endif
917 927
@@ -935,10 +945,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
935 } 945 }
936 946
937 /* Try to load modprobe.dep.bb */ 947 /* Try to load modprobe.dep.bb */
938 load_dep_bb(); 948 if ('r' != applet0) /* not rmmod */
949 load_dep_bb();
939 950
940 /* Load/remove modules. 951 /* Load/remove modules.
941 * Only rmmod loops here, modprobe has only argv[0] */ 952 * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */
942 do { 953 do {
943 process_module(*argv, options); 954 process_module(*argv, options);
944 } while (*++argv); 955 } while (*++argv);
diff --git a/networking/wget.c b/networking/wget.c
index 1013f66cb..6c8bd90a8 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -38,8 +38,14 @@
38 38
39#if 0 39#if 0
40# define log_io(...) bb_error_msg(__VA_ARGS__) 40# define log_io(...) bb_error_msg(__VA_ARGS__)
41# define SENDFMT(fp, fmt, ...) \
42 do { \
43 log_io("> " fmt, ##__VA_ARGS__); \
44 fprintf(fp, fmt, ##__VA_ARGS__); \
45 } while (0);
41#else 46#else
42# define log_io(...) ((void)0) 47# define log_io(...) ((void)0)
48# define SENDFMT(fp, fmt, ...) fprintf(fp, fmt, ##__VA_ARGS__)
43#endif 49#endif
44 50
45 51
@@ -55,6 +61,36 @@ static const char P_FTP[] = "ftp";
55static const char P_HTTP[] = "http"; 61static const char P_HTTP[] = "http";
56static const char P_HTTPS[] = "https"; 62static const char P_HTTPS[] = "https";
57 63
64#if ENABLE_FEATURE_WGET_LONG_OPTIONS
65/* User-specified headers prevent using our corresponding built-in headers. */
66enum {
67 HDR_HOST = (1<<0),
68 HDR_USER_AGENT = (1<<1),
69 HDR_RANGE = (1<<2),
70 HDR_AUTH = (1<<3) * ENABLE_FEATURE_WGET_AUTHENTICATION,
71 HDR_PROXY_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION,
72};
73static const char wget_user_headers[] ALIGN1 =
74 "Host:\0"
75 "User-Agent:\0"
76 "Range:\0"
77# if ENABLE_FEATURE_WGET_AUTHENTICATION
78 "Authorization:\0"
79 "Proxy-Authorization:\0"
80# endif
81 ;
82# define USR_HEADER_HOST (G.user_headers & HDR_HOST)
83# define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT)
84# define USR_HEADER_RANGE (G.user_headers & HDR_RANGE)
85# define USR_HEADER_AUTH (G.user_headers & HDR_AUTH)
86# define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH)
87#else /* No long options, no user-headers :( */
88# define USR_HEADER_HOST 0
89# define USR_HEADER_USER_AGENT 0
90# define USR_HEADER_RANGE 0
91# define USR_HEADER_AUTH 0
92# define USR_HEADER_PROXY_AUTH 0
93#endif
58 94
59/* Globals */ 95/* Globals */
60struct globals { 96struct globals {
@@ -69,6 +105,7 @@ struct globals {
69#if ENABLE_FEATURE_WGET_LONG_OPTIONS 105#if ENABLE_FEATURE_WGET_LONG_OPTIONS
70 char *post_data; 106 char *post_data;
71 char *extra_headers; 107 char *extra_headers;
108 unsigned char user_headers; /* Headers mentioned by the user */
72#endif 109#endif
73 char *fname_out; /* where to direct output (-O) */ 110 char *fname_out; /* where to direct output (-O) */
74 const char *proxy_flag; /* Use proxies if env vars are set */ 111 const char *proxy_flag; /* Use proxies if env vars are set */
@@ -830,43 +867,46 @@ static void download_one_url(const char *url)
830#endif 867#endif
831 /* Send HTTP request */ 868 /* Send HTTP request */
832 if (use_proxy) { 869 if (use_proxy) {
833 fprintf(sfp, "GET %s://%s/%s HTTP/1.1\r\n", 870 SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n",
834 target.protocol, target.host, 871 target.protocol, target.host,
835 target.path); 872 target.path);
836 } else { 873 } else {
837 fprintf(sfp, "%s /%s HTTP/1.1\r\n", 874 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n",
838 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", 875 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET",
839 target.path); 876 target.path);
840 } 877 }
841 878 if (!USR_HEADER_HOST)
842 fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", 879 SENDFMT(sfp, "Host: %s\r\n", target.host);
843 target.host, G.user_agent); 880 if (!USR_HEADER_USER_AGENT)
881 SENDFMT(sfp, "User-Agent: %s\r\n", G.user_agent);
844 882
845 /* Ask server to close the connection as soon as we are done 883 /* Ask server to close the connection as soon as we are done
846 * (IOW: we do not intend to send more requests) 884 * (IOW: we do not intend to send more requests)
847 */ 885 */
848 fprintf(sfp, "Connection: close\r\n"); 886 SENDFMT(sfp, "Connection: close\r\n");
849 887
850#if ENABLE_FEATURE_WGET_AUTHENTICATION 888#if ENABLE_FEATURE_WGET_AUTHENTICATION
851 if (target.user) { 889 if (target.user && !USR_HEADER_AUTH) {
852 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, 890 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
853 base64enc(target.user)); 891 base64enc(target.user));
854 } 892 }
855 if (use_proxy && server.user) { 893 if (use_proxy && server.user && !USR_HEADER_PROXY_AUTH) {
856 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n", 894 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n",
857 base64enc(server.user)); 895 base64enc(server.user));
858 } 896 }
859#endif 897#endif
860 898
861 if (G.beg_range != 0) 899 if (G.beg_range != 0 && !USR_HEADER_RANGE)
862 fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); 900 SENDFMT(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
863 901
864#if ENABLE_FEATURE_WGET_LONG_OPTIONS 902#if ENABLE_FEATURE_WGET_LONG_OPTIONS
865 if (G.extra_headers) 903 if (G.extra_headers) {
904 log_io(G.extra_headers);
866 fputs(G.extra_headers, sfp); 905 fputs(G.extra_headers, sfp);
906 }
867 907
868 if (option_mask32 & WGET_OPT_POST_DATA) { 908 if (option_mask32 & WGET_OPT_POST_DATA) {
869 fprintf(sfp, 909 SENDFMT(sfp,
870 "Content-Type: application/x-www-form-urlencoded\r\n" 910 "Content-Type: application/x-www-form-urlencoded\r\n"
871 "Content-Length: %u\r\n" 911 "Content-Length: %u\r\n"
872 "\r\n" 912 "\r\n"
@@ -876,7 +916,7 @@ static void download_one_url(const char *url)
876 } else 916 } else
877#endif 917#endif
878 { 918 {
879 fprintf(sfp, "\r\n"); 919 SENDFMT(sfp, "\r\n");
880 } 920 }
881 921
882 fflush(sfp); 922 fflush(sfp);
@@ -1093,7 +1133,9 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
1093#if ENABLE_FEATURE_WGET_LONG_OPTIONS 1133#if ENABLE_FEATURE_WGET_LONG_OPTIONS
1094 applet_long_options = wget_longopts; 1134 applet_long_options = wget_longopts;
1095#endif 1135#endif
1096 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 1136 opt_complementary = "-1"
1137 IF_FEATURE_WGET_TIMEOUT(":T+")
1138 IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
1097 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", 1139 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:",
1098 &G.fname_out, &G.dir_prefix, 1140 &G.fname_out, &G.dir_prefix,
1099 &G.proxy_flag, &G.user_agent, 1141 &G.proxy_flag, &G.user_agent,
@@ -1106,16 +1148,32 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
1106 1148
1107#if ENABLE_FEATURE_WGET_LONG_OPTIONS 1149#if ENABLE_FEATURE_WGET_LONG_OPTIONS
1108 if (headers_llist) { 1150 if (headers_llist) {
1109 int size = 1; 1151 int size = 0;
1110 char *cp; 1152 char *hdr;
1111 llist_t *ll = headers_llist; 1153 llist_t *ll = headers_llist;
1112 while (ll) { 1154 while (ll) {
1113 size += strlen(ll->data) + 2; 1155 size += strlen(ll->data) + 2;
1114 ll = ll->link; 1156 ll = ll->link;
1115 } 1157 }
1116 G.extra_headers = cp = xmalloc(size); 1158 G.extra_headers = hdr = xmalloc(size + 1);
1117 while (headers_llist) { 1159 while (headers_llist) {
1118 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 1160 int bit;
1161 const char *words;
1162
1163 size = sprintf(hdr, "%s\r\n",
1164 (char*)llist_pop(&headers_llist));
1165 /* a bit like index_in_substrings but don't match full key */
1166 bit = 1;
1167 words = wget_user_headers;
1168 while (*words) {
1169 if (strstr(hdr, words) == hdr) {
1170 G.user_headers |= bit;
1171 break;
1172 }
1173 bit <<= 1;
1174 words += strlen(words) + 1;
1175 }
1176 hdr += size;
1119 } 1177 }
1120 } 1178 }
1121#endif 1179#endif