]> sjero.net Git - wget/commitdiff
[svn] New option --keep-session-cookies.
authorhniksic <devnull@localhost>
Wed, 5 Nov 2003 00:11:33 +0000 (16:11 -0800)
committerhniksic <devnull@localhost>
Wed, 5 Nov 2003 00:11:33 +0000 (16:11 -0800)
src/ChangeLog
src/cookies.c
src/cookies.h
src/http.c
src/init.c
src/main.c
src/options.h
src/utils.c

index 96fe01c17416d676fec32ae7dd161517747dcbaa..f83a97bff46df7cf36ae03d484af3985463e354f 100644 (file)
@@ -1,3 +1,15 @@
+2003-11-05  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * cookies.c (save_cookies_mapper): Respect the setting of
+       keep-session-cookies.
+       (cookie_jar_load): Import session cookies.
+       Based on code submitted by Nicolas Schodet.
+
+       * utils.c (datetime_str): Use information in TM when it's
+       non-NULL.
+
+       * main.c (main): New option `--keep-session-cookies'.
+
 2003-11-04  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * Makefile.in (realclean): Delete config.h.in.
index 259d0012bd5fc14e72a04079e69c99e472e58424..599d2daa577ccab76d259baea10378203b9de3f4 100644 (file)
@@ -108,12 +108,13 @@ struct cookie {
                                   whole. */
 
   int permanent;               /* whether the cookie should outlive
-                                  the session */
-  time_t expiry_time;          /* time when the cookie expires */
+                                  the session. */
+  time_t expiry_time;          /* time when the cookie expires, 0
+                                  means undetermined. */
 
   int discard_requested;       /* whether cookie was created to
                                   request discarding another
-                                  cookie */
+                                  cookie. */
 
   char *attr;                  /* cookie attribute name */
   char *value;                 /* cookie attribute value */
@@ -123,7 +124,6 @@ struct cookie {
 };
 
 #define PORT_ANY (-1)
-#define COOKIE_EXPIRED_P(c) ((c)->expiry_time != 0 && (c)->expiry_time < cookies_now)
 
 /* Allocate and return a new, empty cookie structure. */
 
@@ -132,14 +132,23 @@ cookie_new (void)
 {
   struct cookie *cookie = xnew0 (struct cookie);
 
-  /* Both cookie->permanent and cookie->expiry_time are now 0.  By
-     default, we assume that the cookie is non-permanent and valid
-     until the end of the session.  */
+  /* Both cookie->permanent and cookie->expiry_time are now 0.  This
+     means that the cookie doesn't expire, but is only valid for this
+     session (i.e. not written out to disk).  */
 
   cookie->port = PORT_ANY;
   return cookie;
 }
 
+/* Non-zero if the cookie has expired.  Assumes cookies_now has been
+   set by one of the entry point functions.  */
+
+static int
+cookie_expired_p (const struct cookie *c)
+{
+  return c->expiry_time != 0 && c->expiry_time < cookies_now;
+}
+
 /* Deallocate COOKIE and its components. */
 
 static void
@@ -252,15 +261,20 @@ store_cookie (struct cookie_jar *jar, struct cookie *cookie)
   hash_table_put (jar->chains, chain_key, cookie);
   ++jar->cookie_count;
 
-  DEBUGP (("\nStored cookie %s %d%s %s %s %d %s %s %s\n",
-          cookie->domain, cookie->port,
-          cookie->port == PORT_ANY ? " (ANY)" : "",
-          cookie->path,
-          cookie->permanent ? "permanent" : "nonpermanent",
-          cookie->secure,
-          cookie->expiry_time
-          ? asctime (localtime (&cookie->expiry_time)) : "<undefined>",
-          cookie->attr, cookie->value));
+#ifdef ENABLE_DEBUG
+  if (opt.debug)
+    {
+      time_t exptime = (time_t) cookie->expiry_time;
+      DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n",
+              cookie->domain, cookie->port,
+              cookie->port == PORT_ANY ? " (ANY)" : "",
+              cookie->path,
+              cookie->permanent ? "permanent" : "session",
+              cookie->secure ? "secure" : "insecure",
+              cookie->expiry_time ? datetime_str (&exptime) : "none",
+              cookie->attr, cookie->value));
+    }
+#endif
 }
 
 /* Discard a cookie matching COOKIE's domain, port, path, and
@@ -386,8 +400,8 @@ update_cookie_field (struct cookie *cookie,
          cookie->expiry_time = (time_t)expires;
        }
       else
-       /* Error in expiration spec.  Assume default (cookie valid for
-          this session.)  */
+       /* Error in expiration spec.  Assume default (cookie doesn't
+          expire, but valid only for this session.)  */
        ;
 
       /* According to netscape's specification, expiry time in the
@@ -649,9 +663,9 @@ parse_set_cookies (const char *sc,
 
 /* Check whether ADDR matches <digits>.<digits>.<digits>.<digits>.
 
-  We don't want to call network functions like inet_addr() because all
-  we need is a check, preferrably one that is small, fast, and
-  well-defined.  */
+   We don't want to call network functions like inet_addr() because
+   all we need is a check, preferrably one that is small, fast, and
+   well-defined.  */
 
 static int
 numeric_address_p (const char *addr)
@@ -818,9 +832,9 @@ check_path_match (const char *cookie_path, const char *path)
    depending on the contents.  */
 
 void
-cookie_jar_process_set_cookie (struct cookie_jar *jar,
-                              const char *host, int port,
-                              const char *path, const char *set_cookie)
+cookie_handle_set_cookie (struct cookie_jar *jar,
+                         const char *host, int port,
+                         const char *path, const char *set_cookie)
 {
   struct cookie *cookie;
   cookies_now = time (NULL);
@@ -969,7 +983,7 @@ cookie_matches_url (const struct cookie *cookie,
 {
   int pg;
 
-  if (COOKIE_EXPIRED_P (cookie))
+  if (cookie_expired_p (cookie))
     /* Ignore stale cookies.  Don't bother unchaining the cookie at
        this point -- Wget is a relatively short-lived application, and
        stale cookies will not be saved by `save_cookies'.  On the
@@ -1097,9 +1111,8 @@ goodness_comparator (const void *p1, const void *p2)
    generated, NULL is returned.  */
 
 char *
-cookie_jar_generate_cookie_header (struct cookie_jar *jar, const char *host,
-                                  int port, const char *path,
-                                  int connection_secure_p)
+cookie_header (struct cookie_jar *jar, const char *host,
+              int port, const char *path, int secflag)
 {
   struct cookie **chains;
   int chain_count;
@@ -1132,8 +1145,7 @@ cookie_jar_generate_cookie_header (struct cookie_jar *jar, const char *host,
   count = 0;
   for (i = 0; i < chain_count; i++)
     for (cookie = chains[i]; cookie; cookie = cookie->next)
-      if (cookie_matches_url (cookie, host, port, path, connection_secure_p,
-                             NULL))
+      if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
        ++count;
   if (!count)
     return NULL;               /* no cookies matched */
@@ -1148,8 +1160,7 @@ cookie_jar_generate_cookie_header (struct cookie_jar *jar, const char *host,
     for (cookie = chains[i]; cookie; cookie = cookie->next)
       {
        int pg;
-       if (!cookie_matches_url (cookie, host, port, path,
-                                connection_secure_p, &pg))
+       if (!cookie_matches_url (cookie, host, port, path, secflag, &pg))
          continue;
        outgoing[ocnt].cookie = cookie;
        outgoing[ocnt].domain_goodness = strlen (cookie->domain);
@@ -1356,14 +1367,21 @@ cookie_jar_load (struct cookie_jar *jar, const char *file)
         malloced.)  */
       *expires_e = '\0';
       sscanf (expires_b, "%lf", &expiry);
-      if (expiry < cookies_now)
-       /* ignore stale cookie. */
-       goto abort;
-      cookie->expiry_time = expiry;
 
-      /* If the cookie has survived being saved into an external file,
-        it is obviously permanent.  */
-      cookie->permanent = 1;
+      if (expiry == 0)
+       {
+         /* EXPIRY can be 0 for session cookies saved because the
+            user specified `--keep-session-cookies' in the past.
+            They remain session cookies, and will be saved only if
+            the user has specified `keep-session-cookies' again.  */
+       }
+      else
+       {
+         if (expiry < cookies_now)
+           goto abort;         /* ignore stale cookie. */
+         cookie->expiry_time = expiry;
+         cookie->permanent = 1;
+       }
 
       store_cookie (jar, cookie);
 
@@ -1388,9 +1406,9 @@ save_cookies_mapper (void *key, void *value, void *arg)
   struct cookie *cookie = (struct cookie *)value;
   for (; cookie; cookie = cookie->next)
     {
-      if (!cookie->permanent)
+      if (!cookie->permanent && !opt.keep_session_cookies)
        continue;
-      if (COOKIE_EXPIRED_P (cookie))
+      if (cookie_expired_p (cookie))
        continue;
       if (!cookie->domain_exact)
        fputc ('.', fp);
@@ -1428,7 +1446,7 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
     }
 
   fputs ("# HTTP cookie file.\n", fp);
-  fprintf (fp, "# Generated by Wget on %s.\n", datetime_str (NULL));
+  fprintf (fp, "# Generated by Wget on %s.\n", datetime_str (&cookies_now));
   fputs ("# Edit at your own risk.\n\n", fp);
 
   hash_table_map (jar->chains, save_cookies_mapper, fp);
@@ -1436,7 +1454,6 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
   if (ferror (fp))
     logprintf (LOG_NOTQUIET, _("Error writing to `%s': %s\n"),
               file, strerror (errno));
-
   if (fclose (fp) < 0)
     logprintf (LOG_NOTQUIET, _("Error closing `%s': %s\n"),
               file, strerror (errno));
index d9dc477c8e44943c2318704ff52028dca85d3649..7533a461644d6cdeb6cbdcb67ee6a122c16452ba 100644 (file)
@@ -35,11 +35,10 @@ struct cookie_jar;
 struct cookie_jar *cookie_jar_new PARAMS ((void));
 void cookie_jar_delete PARAMS ((struct cookie_jar *));
 
-void cookie_jar_process_set_cookie PARAMS ((struct cookie_jar *, const char *,
-                                           int, const char *, const char *));
-char *cookie_jar_generate_cookie_header PARAMS ((struct cookie_jar *,
-                                                const char *, int,
-                                                const char *, int));
+void cookie_handle_set_cookie PARAMS ((struct cookie_jar *, const char *,
+                                      int, const char *, const char *));
+char *cookie_header PARAMS ((struct cookie_jar *,
+                            const char *, int, const char *, int));
 
 void cookie_jar_load PARAMS ((struct cookie_jar *, const char *));
 void cookie_jar_save PARAMS ((struct cookie_jar *, const char *));
index 7104f8e0082d3f226c4409f8e2407fde7206d3bb..2d27dbb5b031a81c514f5449b73a5479ac322cba 100644 (file)
@@ -344,8 +344,7 @@ http_process_set_cookie (const char *hdr, void *arg)
   /* The jar should have been created by now. */
   assert (wget_cookie_jar != NULL);
 
-  cookie_jar_process_set_cookie (wget_cookie_jar, u->host, u->port, u->path,
-                                hdr);
+  cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, u->path, hdr);
   return 1;
 }
 
@@ -901,14 +900,13 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
     request_keep_alive = NULL;
 
   if (opt.cookies)
-    cookies = cookie_jar_generate_cookie_header (wget_cookie_jar, u->host,
-                                                u->port, u->path,
+    cookies = cookie_header (wget_cookie_jar, u->host, u->port, u->path,
 #ifdef HAVE_SSL
-                                                u->scheme == SCHEME_HTTPS
+                            u->scheme == SCHEME_HTTPS
 #else
-                                                0
+                            0
 #endif
-                                );
+                            );
 
   if (opt.post_data || opt.post_file_name)
     {
index 8cc77bc7980afe56edf53d2130b82ea692c2d583..a92b5e114d2fba846b0d5d955d4a0990a4fa9645 100644 (file)
@@ -167,6 +167,7 @@ static struct {
   { "ignoretags",      &opt.ignore_tags,       cmd_vector },
   { "includedirectories", &opt.includes,       cmd_directory_vector },
   { "input",           &opt.input_filename,    cmd_file },
+  { "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
   { "killlonger",      &opt.kill_longer,       cmd_boolean },
   { "limitrate",       &opt.limit_rate,        cmd_bytes },
   { "loadcookies",     &opt.cookies_input,     cmd_file },
index 94aef3b56958a8f9b392fd2c875c572a51d02880..207654b3b9591b1ffdafc5901e2f9940b9da2a3b 100644 (file)
@@ -210,6 +210,7 @@ HTTP options:\n\
        --cookies=off         don't use cookies.\n\
        --load-cookies=FILE   load cookies from FILE before session.\n\
        --save-cookies=FILE   save cookies to FILE after session.\n\
+       --keep-session-cookies  load and save session (non-permanent) cookies.\n\
        --post-data=STRING    use the POST method; send STRING as the data.\n\
        --post-file=FILE      use the POST method; send contents of FILE.\n\
 \n"), stdout);
@@ -287,6 +288,7 @@ main (int argc, char *const *argv)
     { "help", no_argument, NULL, 'h' },
     { "html-extension", no_argument, NULL, 'E' },
     { "ignore-length", no_argument, NULL, 138 },
+    { "keep-session-cookies", no_argument, NULL, 181 },
     { "mirror", no_argument, NULL, 'm' },
     { "no-clobber", no_argument, NULL, 141 },
     { "no-directories", no_argument, NULL, 147 },
@@ -536,6 +538,9 @@ GNU General Public License for more details.\n"));
        case 177:
          setoptval ("strictcomments", "on");
          break;
+       case 181:
+         setoptval ("keepsessioncookies", "on");
+         break;
 
          /* Options accepting an argument: */
        case 129:
index 55ee968e6041d69d0b607d06e69fb8628eda82d4..6adeb6bdd91779d153bed28a3328c01ea68d6ec3 100644 (file)
@@ -177,9 +177,11 @@ struct options
   int   sslprotocol;           /* 0 = auto / 1 = v2 / 2 = v3 / 3 = TLSv1 */
 #endif /* HAVE_SSL */
 
-  int   cookies;
-  char *cookies_input;
-  char *cookies_output;
+  int   cookies;               /* whether cookies are used. */
+  char *cookies_input;         /* file we're loading the cookies from. */
+  char *cookies_output;                /* file we're saving the cookies to. */
+  int   keep_session_cookies;  /* whether session cookies should be
+                                  saved and loaded. */
 
   char *post_data;             /* POST query string */
   char *post_file_name;                /* File to post */
index 5b577587f22bb6668d4c8ff596c4d0008284dc41..5f99fa7ea7a6e642604453518037f021c3b7d7af 100644 (file)
@@ -177,20 +177,14 @@ sepstring (const char *s)
 /* Return pointer to a static char[] buffer in which zero-terminated
    string-representation of TM (in form hh:mm:ss) is printed.
 
-   If TM is non-NULL, the current time-in-seconds will be stored
-   there.
-
-   (#### This is misleading: one would expect TM would be used instead
-   of the current time in that case.  This design was probably
-   influenced by the design time(2), and should be changed at some
-   points.  No callers use non-NULL TM anyway.)  */
+   If TM is NULL, the current time will be used.  */
 
 char *
 time_str (time_t *tm)
 {
   static char output[15];
   struct tm *ptm;
-  time_t secs = time (tm);
+  time_t secs = tm ? *tm : time (NULL);
 
   if (secs == -1)
     {
@@ -211,7 +205,7 @@ datetime_str (time_t *tm)
 {
   static char output[20];      /* "YYYY-MM-DD hh:mm:ss" + \0 */
   struct tm *ptm;
-  time_t secs = time (tm);
+  time_t secs = tm ? *tm : time (NULL);
 
   if (secs == -1)
     {