svn commit: trunk/busybox: include libbb networking

vda at busybox.net vda at busybox.net
Wed Oct 25 00:33:45 UTC 2006


Author: vda
Date: 2006-10-24 17:33:44 -0700 (Tue, 24 Oct 2006)
New Revision: 16433

Log:
wget: wget $'-\207' ... should not be allowed to work. ever. :)
So fix wget & getopt32. Also fix multiple --header options
order: add and use rev_llist.


Modified:
   trunk/busybox/include/libbb.h
   trunk/busybox/libbb/getopt32.c
   trunk/busybox/libbb/llist.c
   trunk/busybox/networking/wget.c


Changeset:
Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2006-10-24 21:46:19 UTC (rev 16432)
+++ trunk/busybox/include/libbb.h	2006-10-25 00:33:44 UTC (rev 16433)
@@ -166,8 +166,8 @@
 extern void llist_add_to_end(llist_t **list_head, void *data);
 extern void *llist_pop(llist_t **elm);
 extern void llist_free(llist_t *elm, void (*freeit)(void *data));
+extern llist_t* rev_llist(llist_t *list);
 
-
 enum {
 	LOGMODE_NONE = 0,
 	LOGMODE_STDIO = 1<<0,

Modified: trunk/busybox/libbb/getopt32.c
===================================================================
--- trunk/busybox/libbb/getopt32.c	2006-10-24 21:46:19 UTC (rev 16432)
+++ trunk/busybox/libbb/getopt32.c	2006-10-25 00:33:44 UTC (rev 16433)
@@ -313,7 +313,7 @@
 {
 	unsigned flags = 0;
 	unsigned requires = 0;
-	t_complementary complementary[sizeof(flags) * 8 + 1];
+	t_complementary complementary[33];
 	int c;
 	const unsigned char *s;
 	t_complementary *on_off;
@@ -342,16 +342,13 @@
 	s = (const unsigned char *)applet_opts;
 	if (*s == '+' || *s == '-')
 		s++;
-	for (; *s; s++) {
-		if (c >= (int)(sizeof(flags)*8))
-			break;
+	while (*s) {
+		if (c >= 32) break;
 		on_off->opt = *s;
 		on_off->switch_on = (1 << c);
-		if (s[1] == ':') {
+		if (*++s == ':') {
 			on_off->optarg = va_arg(p, void **);
-			do
-				s++;
-			while (s[1] == ':');
+			while (*++s == ':') /* skip */;
 		}
 		on_off++;
 		c++;
@@ -363,16 +360,14 @@
 			continue;
 		for (on_off = complementary; on_off->opt != 0; on_off++)
 			if (on_off->opt == l_o->val)
-				break;
-		if (on_off->opt == 0) {
-			if (c >= (int)(sizeof(flags)*8))
-				break;
-			on_off->opt = l_o->val;
-			on_off->switch_on = (1 << c);
-			if (l_o->has_arg != no_argument)
-				on_off->optarg = va_arg(p, void **);
-			c++;
-		}
+				goto next_long;
+		if (c >= 32) break;
+		on_off->opt = l_o->val;
+		on_off->switch_on = (1 << c);
+		if (l_o->has_arg != no_argument)
+			on_off->optarg = va_arg(p, void **);
+		c++;
+ next_long: ;
 	}
 #endif /* ENABLE_GETOPT_LONG */
 	for (s = (const unsigned char *)opt_complementary; s && *s; s++) {
@@ -461,12 +456,17 @@
 		}
 	}
 #endif
+	/* Note: just "getopt() <= 0" will not work good for
+	 * "fake" short options, like this one:
+	 * wget $'-\203' "Test: test" http://kernel.org/
+	 * (supposed to act as --header, but doesn't) */
 #if ENABLE_GETOPT_LONG
 	while ((c = getopt_long(argc, argv, applet_opts,
-				 applet_long_options, NULL)) >= 0) {
+				 applet_long_options, NULL)) != -1) {
 #else
-	while ((c = getopt(argc, argv, applet_opts)) >= 0) {
+	while ((c = getopt(argc, argv, applet_opts)) != -1) {
 #endif /* ENABLE_GETOPT_LONG */
+		c &= 0xff; /* fight libc's sign extends */
 loop_arg_is_opt:
 		for (on_off = complementary; on_off->opt != c; on_off++) {
 			/* c==0 if long opt have non NULL flag */

Modified: trunk/busybox/libbb/llist.c
===================================================================
--- trunk/busybox/libbb/llist.c	2006-10-24 21:46:19 UTC (rev 16432)
+++ trunk/busybox/libbb/llist.c	2006-10-25 00:33:44 UTC (rev 16433)
@@ -62,3 +62,17 @@
 		if (freeit) freeit(data);
 	}
 }
+
+/* Reverse list order. Useful since getopt32 saves option params
+ * in reverse order */
+llist_t* rev_llist(llist_t *list)
+{
+	llist_t *new = NULL;
+	while (list) {
+		llist_t *next = list->link;
+		list->link = new;
+		new = list;
+		list = next;
+	}
+	return new;
+}

Modified: trunk/busybox/networking/wget.c
===================================================================
--- trunk/busybox/networking/wget.c	2006-10-24 21:46:19 UTC (rev 16432)
+++ trunk/busybox/networking/wget.c	2006-10-25 00:33:44 UTC (rev 16433)
@@ -86,42 +86,22 @@
 }
 #endif
 
-#define WGET_OPT_CONTINUE     1
-#define WGET_OPT_QUIET        2
-#define WGET_OPT_PASSIVE      4
-#define WGET_OPT_OUTNAME      8
-#define WGET_OPT_HEADER      16
-#define WGET_OPT_PREFIX      32
-#define WGET_OPT_PROXY       64
-#define WGET_OPT_USER_AGENT 128
-
-#if ENABLE_FEATURE_WGET_LONG_OPTIONS
-static const struct option wget_long_options[] = {
-	{ "continue",        0, NULL, 'c' },
-	{ "quiet",           0, NULL, 'q' },
-	{ "passive-ftp",     0, NULL, 139 }, /* FIXME: what is this - 139?? */
-	{ "output-document", 1, NULL, 'O' },
-	{ "header",          1, NULL, 131 },
-	{ "directory-prefix",1, NULL, 'P' },
-	{ "proxy",           1, NULL, 'Y' },
-	{ "user-agent",      1, NULL, 'U' },
-	{ 0,                 0, 0, 0 }
-};
-#endif
-
 int wget_main(int argc, char **argv)
 {
+	char buf[512];
+	struct host_info server, target;
+	struct sockaddr_in s_in;
 	int n, status;
+	int port;
 	int try = 5;
-	int port;
 	unsigned opt;
+	char *s;
 	char *proxy = 0;
 	char *dir_prefix = NULL;
-	char *s, buf[512];
+#if ENABLE_FEATURE_WGET_LONG_OPTIONS
 	char *extra_headers = NULL;
-	struct host_info server, target;
-	struct sockaddr_in s_in;
 	llist_t *headers_llist = NULL;
+#endif
 
 	/* server.allocated = target.allocated = NULL; */
 
@@ -137,21 +117,46 @@
 	/*
 	 * Crack command line.
 	 */
-	opt_complementary = "-1:\203::";
+	enum {
+		WGET_OPT_CONTINUE   = 0x1,
+		WGET_OPT_QUIET      = 0x2,
+		WGET_OPT_OUTNAME    = 0x4,
+		WGET_OPT_PREFIX     = 0x8,
+		WGET_OPT_PROXY      = 0x10,
+		WGET_OPT_USER_AGENT = 0x20,
+		WGET_OPT_PASSIVE    = 0x40,
+		WGET_OPT_HEADER     = 0x80,
+	};
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS
+	static const struct option wget_long_options[] = {
+		// name, has_arg, flag, val
+		{ "continue",         no_argument, NULL, 'c' },
+		{ "quiet",            no_argument, NULL, 'q' },
+		{ "output-document",  required_argument, NULL, 'O' },
+		{ "directory-prefix", required_argument, NULL, 'P' },
+		{ "proxy",            required_argument, NULL, 'Y' },
+		{ "user-agent",       required_argument, NULL, 'U' },
+		{ "passive-ftp",      no_argument, NULL, 0xff },
+		{ "header",           required_argument, NULL, 0xfe },
+		{ 0, 0, 0, 0 }
+};
 	applet_long_options = wget_long_options;
 #endif
-	opt = getopt32(argc, argv, "cq\213O:\203:P:Y:U:",
-					&fname_out, &headers_llist,
-					&dir_prefix, &proxy_flag, &user_agent);
+	opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
+	opt = getopt32(argc, argv, "cqO:P:Y:U:",
+				&fname_out, &dir_prefix,
+				&proxy_flag, &user_agent
+				USE_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
+				);
 	if (strcmp(proxy_flag, "off") == 0) {
 		/* Use the proxy if necessary. */
 		use_proxy = 0;
 	}
+#if ENABLE_FEATURE_WGET_LONG_OPTIONS
 	if (headers_llist) {
 		int size = 1;
 		char *cp;
-		llist_t *ll = headers_llist;
+		llist_t *ll = headers_llist = rev_llist(headers_llist);
 		while (ll) {
 			size += strlen(ll->data) + 2;
 			ll = ll->link;
@@ -162,6 +167,7 @@
 			headers_llist = headers_llist->link;
 		}
 	}
+#endif
 
 	parse_url(argv[optind], &target);
 	server.host = target.host;
@@ -281,8 +287,10 @@
 
 			if (beg_range)
 				fprintf(sfp, "Range: bytes="OFF_FMT"-\r\n", beg_range);
+#if ENABLE_FEATURE_WGET_LONG_OPTIONS
 			if (extra_headers)
 				fputs(extra_headers, sfp);
+#endif
 			fprintf(sfp, "Connection: close\r\n\r\n");
 
 			/*




More information about the busybox-cvs mailing list