hush: fix a bug in argv restoration after sourcing a file
[oweals/busybox.git] / networking / wget.c
index 653d8076f3ad174457b9df758ea5c932d66346c6..b082a0f591103dc8d16715bac53364dd732f05b3 100644 (file)
 
 //usage:#define wget_trivial_usage
 //usage:       IF_FEATURE_WGET_LONG_OPTIONS(
-//usage:       "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n"
+//usage:       "[-c|--continue] [--spider] [-q|--quiet] [-O|--output-document FILE]\n"
 //usage:       "       [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n"
 /* Since we ignore these opts, we don't show them in --help */
 /* //usage:    "       [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */
 //usage:       "       [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..."
 //usage:       )
 //usage:       IF_NOT_FEATURE_WGET_LONG_OPTIONS(
-//usage:       "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]"
+//usage:       "[-cq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]"
 //usage:                       IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..."
 //usage:       )
 //usage:#define wget_full_usage "\n\n"
 //usage:       "Retrieve files via HTTP or FTP\n"
-//usage:     "\n       -s      Spider mode - only check file existence"
-//usage:     "\n       -c      Continue retrieval of aborted transfer"
-//usage:     "\n       -q      Quiet"
-//usage:     "\n       -P DIR  Save to DIR (default .)"
+//usage:       IF_FEATURE_WGET_LONG_OPTIONS(
+//usage:     "\n       --spider        Spider mode - only check file existence"
+//usage:       )
+//usage:     "\n       -c              Continue retrieval of aborted transfer"
+//usage:     "\n       -q              Quiet"
+//usage:     "\n       -P DIR          Save to DIR (default .)"
 //usage:       IF_FEATURE_WGET_TIMEOUT(
-//usage:     "\n       -T SEC  Network read timeout is SEC seconds"
+//usage:     "\n       -T SEC          Network read timeout is SEC seconds"
 //usage:       )
-//usage:     "\n       -O FILE Save to FILE ('-' for stdout)"
-//usage:     "\n       -U STR  Use STR for User-Agent header"
-//usage:     "\n       -Y      Use proxy ('on' or 'off')"
+//usage:     "\n       -O FILE         Save to FILE ('-' for stdout)"
+//usage:     "\n       -U STR          Use STR for User-Agent header"
+//usage:     "\n       -Y on/off       Use proxy"
 
 #include "libbb.h"
 
@@ -229,17 +231,17 @@ struct globals {
 /* Must match option string! */
 enum {
        WGET_OPT_CONTINUE   = (1 << 0),
-       WGET_OPT_SPIDER     = (1 << 1),
-       WGET_OPT_QUIET      = (1 << 2),
-       WGET_OPT_OUTNAME    = (1 << 3),
-       WGET_OPT_PREFIX     = (1 << 4),
-       WGET_OPT_PROXY      = (1 << 5),
-       WGET_OPT_USER_AGENT = (1 << 6),
-       WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 7),
-       WGET_OPT_RETRIES    = (1 << 8),
-       WGET_OPT_PASSIVE    = (1 << 9),
-       WGET_OPT_HEADER     = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
-       WGET_OPT_POST_DATA  = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
+       WGET_OPT_QUIET      = (1 << 1),
+       WGET_OPT_OUTNAME    = (1 << 2),
+       WGET_OPT_PREFIX     = (1 << 3),
+       WGET_OPT_PROXY      = (1 << 4),
+       WGET_OPT_USER_AGENT = (1 << 5),
+       WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 6),
+       WGET_OPT_RETRIES    = (1 << 7),
+       WGET_OPT_nsomething = (1 << 8),
+       WGET_OPT_HEADER     = (1 << 9) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
+       WGET_OPT_POST_DATA  = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
+       WGET_OPT_SPIDER     = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
 };
 
 enum {
@@ -1091,6 +1093,12 @@ static void download_one_url(const char *url)
                }
 
                fflush(sfp);
+               /* If we use SSL helper, keeping our end of the socket open for writing
+                * makes our end (i.e. the same fd!) readable (EAGAIN instead of EOF)
+                * even after child closes its copy of the fd.
+                * This helps:
+                */
+               shutdown(fileno(sfp), SHUT_WR);
 
                /*
                 * Retrieve HTTP response line and check for "200" status code.
@@ -1110,7 +1118,21 @@ static void download_one_url(const char *url)
                        while (gethdr(sfp) != NULL)
                                /* eat all remaining headers */;
                        goto read_response;
+
+               /* Success responses */
                case 200:
+                       /* fall through */
+               case 201: /* 201 Created */
+/* "The request has been fulfilled and resulted in a new resource being created" */
+                       /* Standard wget is reported to treat this as success */
+                       /* fall through */
+               case 202: /* 202 Accepted */
+/* "The request has been accepted for processing, but the processing has not been completed" */
+                       /* Treat as success: fall through */
+               case 203: /* 203 Non-Authoritative Information */
+/* "Use of this response code is not required and is only appropriate when the response would otherwise be 200 (OK)" */
+                       /* fall through */
+               case 204: /* 204 No Content */
 /*
 Response 204 doesn't say "null file", it says "metadata
 has changed but data didn't":
@@ -1135,7 +1157,6 @@ is always terminated by the first empty line after the header fields."
 However, in real world it was observed that some web servers
 (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero.
 */
-               case 204:
                        if (G.beg_range != 0) {
                                /* "Range:..." was not honored by the server.
                                 * Restart download from the beginning.
@@ -1143,11 +1164,14 @@ However, in real world it was observed that some web servers
                                reset_beg_range_to_zero();
                        }
                        break;
+               /* 205 Reset Content ?? what to do on this ??   */
+
                case 300:  /* redirection */
                case 301:
                case 302:
                case 303:
                        break;
+
                case 206: /* Partial Content */
                        if (G.beg_range != 0)
                                /* "Range:..." worked. Good. */
@@ -1264,8 +1288,6 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
        static const char wget_longopts[] ALIGN1 =
                /* name, has_arg, val */
                "continue\0"         No_argument       "c"
-//FIXME: -s isn't --spider, it's --save-headers!
-               "spider\0"           No_argument       "s"
                "quiet\0"            No_argument       "q"
                "output-document\0"  Required_argument "O"
                "directory-prefix\0" Required_argument "P"
@@ -1277,6 +1299,7 @@ IF_FEATURE_WGET_TIMEOUT(
 IF_DESKTOP(    "tries\0"            Required_argument "t")
                "header\0"           Required_argument "\xff"
                "post-data\0"        Required_argument "\xfe"
+               "spider\0"           No_argument       "\xfd"
                /* Ignored (we always use PASV): */
 IF_DESKTOP(    "passive-ftp\0"      No_argument       "\xf0")
                /* Ignored (we don't do ssl) */
@@ -1308,7 +1331,7 @@ IF_DESKTOP(       "no-parent\0"        No_argument       "\xf0")
 #endif
        opt_complementary = "-1" /* at least one URL */
                IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */
-       getopt32(argv, "csqO:P:Y:U:T:+"
+       getopt32(argv, "cqO:P:Y:U:T:+"
                /*ignored:*/ "t:"
                /*ignored:*/ "n::"
                /* wget has exactly four -n<letter> opts, all of which we can ignore:
@@ -1327,6 +1350,14 @@ IF_DESKTOP(      "no-parent\0"        No_argument       "\xf0")
                IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
                IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data)
        );
+#if 0 /* option bits debug */
+       if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM");
+       if (option_mask32 & WGET_OPT_nsomething) bb_error_msg("-nsomething");
+       if (option_mask32 & WGET_OPT_HEADER) bb_error_msg("--header");
+       if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data");
+       if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider");
+       exit(0);
+#endif
        argv += optind;
 
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS