]> sjero.net Git - wget/commitdiff
[svn] Implemented the item I formerly had in the TODO: When -K and -N are used
authordan <devnull@localhost>
Thu, 2 Mar 2000 06:33:48 +0000 (22:33 -0800)
committerdan <devnull@localhost>
Thu, 2 Mar 2000 06:33:48 +0000 (22:33 -0800)
together, we compare local file X.orig (if extant) against server file X.
Previously -k and -N were worthless in combination because the local converted
files always differed from the server versions.

ChangeLog
NEWS
TODO
src/ChangeLog
src/ftp.c
src/http.c
src/retr.c
src/url.c
src/url.h
src/wget.h

index 92039a925ad4ece92e34e5d5d725c8d0143bd0ae..6edc5cbc5aba5fb01b8649ac73625fc15f7bb259 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-03-01  Dan Harkless  <dan-wget@dilvish.speed.net>
+
+       * NEWS (-K): Now possible to use -N with -k thanks to this option.
+
+       * TODO: Removed the -K / -N interaction item.
+
 2000-02-29  Dan Harkless  <dan-wget@dilvish.speed.net>
 
        * NEWS (-K / --backup-converted): Mentioned this new option.
 2000-02-29  Dan Harkless  <dan-wget@dilvish.speed.net>
 
        * NEWS (-K / --backup-converted): Mentioned this new option.
diff --git a/NEWS b/NEWS
index 35c5dc41b36cc1efab4c46b4897d2a20325f5aca..eeab6a3e82386da4f6449a17bb8d8763943efc2e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,8 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
 * Changes in Wget 1.5.3+dev
 
 ** New -K / --backup-converted / backup_converted = on option causes files
 * Changes in Wget 1.5.3+dev
 
 ** New -K / --backup-converted / backup_converted = on option causes files
-modified due to -k to be saved with a .orig prefix before being changed.
+modified due to -k to be saved with a .orig prefix before being changed.  When
+using -N as well, it is these .orig files that are compared against the server.
 \f
 * Wget 1.5.3 is a bugfix release with no user-visible changes.
 \f
 \f
 * Wget 1.5.3 is a bugfix release with no user-visible changes.
 \f
diff --git a/TODO b/TODO
index f25ac4f2d4817ecad864bdf652bdcea68d99a4e3..9f5476993fa95178bd0983119f0f78ae6f38c7c9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -76,6 +76,3 @@ particular order.  Not all of them are user-visible changes.
 * Implement more HTTP/1.1 bells and whistles (ETag, Content-MD5 etc.)
 
 * Support SSL encryption through SSLeay or OpenSSL.
 * Implement more HTTP/1.1 bells and whistles (ETag, Content-MD5 etc.)
 
 * Support SSL encryption through SSLeay or OpenSSL.
-
-* When -K is used with -N, check local file X.orig (if extant) against server 
-  file X.
index 3661374715206105c3940a94e98e9066bd4fa45e..54704959744cb986e15e1b40cdcf6d39ff378211 100644 (file)
@@ -1,3 +1,35 @@
+2000-03-01  Dan Harkless  <dan-wget@dilvish.speed.net>
+
+       * ftp.c (ftp_loop_internal): Call new downloaded_file() function,
+       even though we don't do conversion on HTML files retrieved via
+       FTP, so _current_ usage of downloaded_file() makes this call unneeded. 
+       (ftp_retrieve_list): Added a comment saying where we need to
+       stat() a .orig file if FTP'd HTML file conversion is ever implemented.
+       (ftp_retrieve_list): "Local file '%s' is more recent," is sometimes
+       a lie -- reworded as "Server file no newer than local file '%s' --".
+       
+       * http.c (http_loop): Fixed a typo and clarified a comment.
+       (http_loop): When -K and -N are specified together, compare size
+       and timestamp of server file X against local file X.orig (if
+       extant) rather than converted local file X.
+       (http_loop): "Local file '%s' is more recent," is sometimes a lie
+       -- reworded as "Server file no newer than local file '%s' --".
+       (http_loop): Call new downloaded_file() function to prevent
+       wrongful overwriting of .orig file when -N is specified.
+       
+       * url.c (convert_links): When -K specified, only rename X to
+       X.orig if downloaded_file() returns TRUE.  Otherwise when we skip
+       file X due to -N, we clobber an X.orig from a previous invocation.
+       (convert_links): Call the failsafe xstrdup(), not the real strdup().
+       (convert_links): Added a note asking anyone who understands how
+       multiple URLs can correspond to a single file to comment it.
+       (downloaded_file): Added this new function.
+       
+       * url.h (downloaded_file): Added prototype for this new function
+       as well as its downloaded_file_t enum type.
+
+       * wget.h (boolean): Added this new typedef and TRUE and FALSE #defines.
+
 2000-02-29  Dan Harkless  <dan-wget@dilvish.speed.net>
 
        * version.c: Upped version to developer-only "1.5.3+dev".
 2000-02-29  Dan Harkless  <dan-wget@dilvish.speed.net>
 
        * version.c: Upped version to developer-only "1.5.3+dev".
index 61507db4742a26618758cf7c7dc9dbf87ad96ea8..9077c674c4b243477754e304553698711a20e3dd 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -947,6 +947,11 @@ ftp_loop_internal (struct urlinfo *u, struct fileinfo *f, ccon *con)
          /* Not as great.  */
          abort ();
        }
          /* Not as great.  */
          abort ();
        }
+
+      /* If we get out of the switch above without continue'ing, we've
+        successfully downloaded a file.  Remember this fact. */
+      downloaded_file(ADD_FILE, locf);
+
       if (con->st & ON_YOUR_OWN)
        {
          CLOSE (RBUF_FD (&con->rbuf));
       if (con->st & ON_YOUR_OWN)
        {
          CLOSE (RBUF_FD (&con->rbuf));
@@ -1086,6 +1091,11 @@ ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
       if (opt.timestamping && f->type == FT_PLAINFILE)
        {
          struct stat st;
       if (opt.timestamping && f->type == FT_PLAINFILE)
        {
          struct stat st;
+         /* If conversion of HTML files retrieved via FTP is ever implemented,
+            we'll need to stat() <file>.orig here when -K has been specified.
+            I'm not implementing it now since files on an FTP server are much
+            more likely than files on an HTTP server to legitimately have a
+            .orig suffix. */
          if (!stat (u->local, &st))
            {
              /* Else, get it from the file.  */
          if (!stat (u->local, &st))
            {
              /* Else, get it from the file.  */
@@ -1094,13 +1104,13 @@ ftp_retrieve_list (struct urlinfo *u, struct fileinfo *f, ccon *con)
              if (local_size == f->size && tml >= f->tstamp)
                {
                  logprintf (LOG_VERBOSE, _("\
              if (local_size == f->size && tml >= f->tstamp)
                {
                  logprintf (LOG_VERBOSE, _("\
-Local file `%s' is more recent, not retrieving.\n\n"), u->local);
+Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
                  dlthis = 0;
                }
              else if (local_size != f->size)
                {
                  logprintf (LOG_VERBOSE, _("\
                  dlthis = 0;
                }
              else if (local_size != f->size)
                {
                  logprintf (LOG_VERBOSE, _("\
-The sizes do not match (local %ld), retrieving.\n"), local_size);
+The sizes do not match (local %ld) -- retrieving.\n"), local_size);
                }
            }
        }       /* opt.timestamping && f->type == FT_PLAINFILE */
                }
            }
        }       /* opt.timestamping && f->type == FT_PLAINFILE */
index 9ea0670f4988a5b756e7911cbf0ffcf8b85be956..c79e6fecbfe31210f30d3aaf9f3ba7abb0cade0c 100644 (file)
@@ -840,6 +840,7 @@ http_loop (struct urlinfo *u, char **newloc, int *dt)
   static int first_retrieval = 1;
 
   int count;
   static int first_retrieval = 1;
 
   int count;
+  int local_dot_orig_file_exists = FALSE;
   int use_ts, got_head = 0;    /* time-stamping info */
   char *tms, *suf, *locf, *tmrate;
   uerr_t err;
   int use_ts, got_head = 0;    /* time-stamping info */
   char *tms, *suf, *locf, *tmrate;
   uerr_t err;
@@ -851,7 +852,7 @@ http_loop (struct urlinfo *u, char **newloc, int *dt)
   *newloc = NULL;
 
   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
   *newloc = NULL;
 
   /* Warn on (likely bogus) wildcard usage in HTTP.  Don't use
-     has_wildcards_p because it would also warn on `?', and we that
+     has_wildcards_p because it would also warn on `?', and we know that
      shows up in CGI paths a *lot*.  */
   if (strchr (u->url, '*'))
     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
      shows up in CGI paths a *lot*.  */
   if (strchr (u->url, '*'))
     logputs (LOG_VERBOSE, _("Warning: wildcards not supported in HTTP.\n"));
@@ -888,7 +889,43 @@ File `%s' already there, will not retrieve.\n"), u->local);
   use_ts = 0;
   if (opt.timestamping)
     {
   use_ts = 0;
   if (opt.timestamping)
     {
-      if (stat (u->local, &st) == 0)
+      boolean  local_file_exists = FALSE;
+
+      if (opt.backup_converted)
+       /* If -K is specified, we'll act on the assumption that it was specified
+          last time these files were downloaded as well, and instead of just
+          comparing local file X against server file X, we'll compare local
+          file X.orig (if extant, else X) against server file X.  If -K
+          _wasn't_ specified last time, or the server contains files called
+          *.orig, -N will be back to not operating correctly with -k. */
+       {
+         size_t filename_len = strlen(u->local);
+         char*  filename_plus_orig_suffix = malloc(filename_len +
+                                                   sizeof(".orig"));
+
+         /* Would a single s[n]printf() call be faster? */
+         strcpy(filename_plus_orig_suffix, u->local);
+         strcpy(filename_plus_orig_suffix + filename_len, ".orig");
+
+         /* Try to stat() the .orig file. */
+         if (stat(filename_plus_orig_suffix, &st) == 0)
+           {
+             local_file_exists = TRUE;
+             local_dot_orig_file_exists = TRUE;
+           }
+
+         free(filename_plus_orig_suffix);
+       }      
+
+      if (!local_dot_orig_file_exists)
+       /* Couldn't stat() <file>.orig, so try to stat() <file>. */
+       if (stat (u->local, &st) == 0)
+         local_file_exists = TRUE;
+
+      if (local_file_exists)
+       /* There was a local file, so we'll check later to see if the version
+          the server has is the same version we already have, allowing us to
+          skip a download. */
        {
          use_ts = 1;
          tml = st.st_mtime;
        {
          use_ts = 1;
          tml = st.st_mtime;
@@ -1051,14 +1088,26 @@ Last-modified header invalid -- time-stamp ignored.\n"));
              if (tml >= tmr &&
                  (hstat.contlen == -1 || local_size == hstat.contlen))
                {
              if (tml >= tmr &&
                  (hstat.contlen == -1 || local_size == hstat.contlen))
                {
-                 logprintf (LOG_VERBOSE, _("\
-Local file `%s' is more recent, not retrieving.\n\n"), u->local);
+                 if (local_dot_orig_file_exists)
+                   /* We can't collapse this down into just one logprintf()
+                      call with a variable set to u->local or the .orig
+                      filename because we have to malloc() space for the
+                      latter, and because there are multiple returns above (a
+                      coding style no-no by many measures, for reasons such as
+                      this) we'd have to remember to free() the string at each
+                      one to avoid a memory leak. */
+                   logprintf (LOG_VERBOSE, _("\
+Server file no newer than local file `%s.orig' -- not retrieving.\n\n"),
+                              u->local);
+                 else
+                   logprintf (LOG_VERBOSE, _("\
+Server file no newer than local file `%s' -- not retrieving.\n\n"), u->local);
                  FREEHSTAT (hstat);
                  return RETROK;
                }
              else if (tml >= tmr)
                logprintf (LOG_VERBOSE, _("\
                  FREEHSTAT (hstat);
                  return RETROK;
                }
              else if (tml >= tmr)
                logprintf (LOG_VERBOSE, _("\
-The sizes do not match (local %ld), retrieving.\n"), local_size);
+The sizes do not match (local %ld) -- retrieving.\n"), local_size);
              else
                logputs (LOG_VERBOSE,
                         _("Remote file is newer, retrieving.\n"));
              else
                logputs (LOG_VERBOSE,
                         _("Remote file is newer, retrieving.\n"));
@@ -1103,12 +1152,13 @@ The sizes do not match (local %ld), retrieving.\n"), local_size);
            }
          ++opt.numurls;
          opt.downloaded += hstat.len;
            }
          ++opt.numurls;
          opt.downloaded += hstat.len;
+         downloaded_file(ADD_FILE, locf);
          return RETROK;
        }
       else if (hstat.res == 0) /* No read error */
        {
          return RETROK;
        }
       else if (hstat.res == 0) /* No read error */
        {
-         if (hstat.contlen == -1)  /* We don't know how much we were
-                                      supposed to get, so...  */
+         if (hstat.contlen == -1)  /* We don't know how much we were supposed
+                                      to get, so assume we succeeded. */ 
            {
              if (*dt & RETROKF)
                {
            {
              if (*dt & RETROKF)
                {
@@ -1121,6 +1171,7 @@ The sizes do not match (local %ld), retrieving.\n"), local_size);
                }
              ++opt.numurls;
              opt.downloaded += hstat.len;
                }
              ++opt.numurls;
              opt.downloaded += hstat.len;
+             downloaded_file(ADD_FILE, locf);
              return RETROK;
            }
          else if (hstat.len < hstat.contlen) /* meaning we lost the
              return RETROK;
            }
          else if (hstat.len < hstat.contlen) /* meaning we lost the
@@ -1142,6 +1193,7 @@ The sizes do not match (local %ld), retrieving.\n"), local_size);
                         tms, u->url, hstat.len, hstat.contlen, locf, count);
              ++opt.numurls;
              opt.downloaded += hstat.len;
                         tms, u->url, hstat.len, hstat.contlen, locf, count);
              ++opt.numurls;
              opt.downloaded += hstat.len;
+             downloaded_file(ADD_FILE, locf);
              return RETROK;
            }
          else                  /* the same, but not accepted */
              return RETROK;
            }
          else                  /* the same, but not accepted */
index 592500547255f3c9f5afdfb4a0d70790618e8958..d90fa5296fa8a48e90d7c61ad47af7d3b38452c9 100644 (file)
@@ -350,7 +350,7 @@ retrieve_url (const char *origurl, char **file, char **newloc,
       if (result != URLOK || u->proto != URLHTTP)
        {
          if (u->proto == URLHTTP)
       if (result != URLOK || u->proto != URLHTTP)
        {
          if (u->proto == URLHTTP)
-           logprintf (LOG_NOTQUIET, "Proxy %s: %s.\n", proxy, uerrmsg (result));
+           logprintf (LOG_NOTQUIET, "Proxy %s: %s.\n", proxy, uerrmsg(result));
          else
            logprintf (LOG_NOTQUIET, _("Proxy %s: Must be HTTP.\n"), proxy);
          freeurl (u, 1);
          else
            logprintf (LOG_NOTQUIET, _("Proxy %s: Must be HTTP.\n"), proxy);
          freeurl (u, 1);
@@ -455,7 +455,8 @@ retrieve_from_file (const char *file, int html, int *count)
        }
       status = retrieve_url (cur_url->url, &filename, &new_file, NULL, &dt);
       if (opt.recursive && status == RETROK && (dt & TEXTHTML))
        }
       status = retrieve_url (cur_url->url, &filename, &new_file, NULL, &dt);
       if (opt.recursive && status == RETROK && (dt & TEXTHTML))
-       status = recursive_retrieve (filename, new_file ? new_file : cur_url->url);
+       status = recursive_retrieve (filename, new_file ? new_file
+                                                       : cur_url->url);
 
       if (filename && opt.delete_after && file_exists_p (filename))
        {
 
       if (filename && opt.delete_after && file_exists_p (filename))
        {
index 87a97b30cec0a0d6f2448fe5fe80517df601bda6..33aa37b82bfa07099931d041cd5ec30244f7477d 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -1366,10 +1366,9 @@ no_proxy_match (const char *host, const char **no_proxy)
 void
 convert_links (const char *file, urlpos *l)
 {
 void
 convert_links (const char *file, urlpos *l)
 {
-  FILE           *fp;
-  char           *buf, *p, *p2;
-  long           size;
-  static slist*  converted_files = NULL;
+  FILE *fp;
+  char *buf, *p, *p2;
+  long size;
 
   logprintf (LOG_VERBOSE, _("Converting %s... "), file);
   /* Read from the file....  */
 
   logprintf (LOG_VERBOSE, _("Converting %s... "), file);
   /* Read from the file....  */
@@ -1383,28 +1382,34 @@ convert_links (const char *file, urlpos *l)
   /* ...to a buffer.  */
   load_file (fp, &buf, &size);
   fclose (fp);
   /* ...to a buffer.  */
   load_file (fp, &buf, &size);
   fclose (fp);
-  if (opt.backup_converted)
+  if (opt.backup_converted && downloaded_file(CHECK_FOR_FILE, file))
     /* Rather than just writing over the original .html file with the converted
     /* Rather than just writing over the original .html file with the converted
-       version, save the former to *.orig. */
+       version, save the former to *.orig.  Note we only do this for files we've
+       _successfully_ downloaded, so we don't clobber .orig files sitting around
+       from previous invocations. */
     {
       /* Construct the backup filename as the original name plus ".orig". */
     {
       /* Construct the backup filename as the original name plus ".orig". */
-      size_t filename_len = strlen(file);
-      char*  filename_plus_orig_suffix = malloc(filename_len + sizeof(".orig"));
-      int    already_wrote_backup_file = 0;
-      slist* converted_file_ptr;
-
+      size_t         filename_len = strlen(file);
+      char*          filename_plus_orig_suffix = malloc(filename_len +
+                                                       sizeof(".orig"));
+      boolean        already_wrote_backup_file = FALSE;
+      slist*         converted_file_ptr;
+      static slist*  converted_files = NULL;
+
+      /* Would a single s[n]printf() call be faster? */
       strcpy(filename_plus_orig_suffix, file);
       strcpy(filename_plus_orig_suffix + filename_len, ".orig");
 
       /* We can get called twice on the same URL thanks to the
         convert_all_links() call in main().  If we write the .orig file each
         time in such a case, it'll end up containing the first-pass conversion,
       strcpy(filename_plus_orig_suffix, file);
       strcpy(filename_plus_orig_suffix + filename_len, ".orig");
 
       /* We can get called twice on the same URL thanks to the
         convert_all_links() call in main().  If we write the .orig file each
         time in such a case, it'll end up containing the first-pass conversion,
-        not the original file. */
+        not the original file.  So, see if we've already been called on this
+        file. */
       converted_file_ptr = converted_files;
       while (converted_file_ptr != NULL)
        if (strcmp(converted_file_ptr->string, file) == 0)
          {
       converted_file_ptr = converted_files;
       while (converted_file_ptr != NULL)
        if (strcmp(converted_file_ptr->string, file) == 0)
          {
-           already_wrote_backup_file = 1;
+           already_wrote_backup_file = TRUE;
            break;
          }
        else
            break;
          }
        else
@@ -1421,10 +1426,13 @@ convert_links (const char *file, urlpos *l)
             Note that we never free this memory since we need it till the
             convert_all_links() call, which is one of the last things the
             program does before terminating.  BTW, I'm not sure if it would be
             Note that we never free this memory since we need it till the
             convert_all_links() call, which is one of the last things the
             program does before terminating.  BTW, I'm not sure if it would be
-            safe to just set converted_file_ptr->string to file below, rather
-            than making a copy of the string... */
+            safe to just set 'converted_file_ptr->string' to 'file' below,
+            rather than making a copy of the string...  Another note is that I
+            thought I could just add a field to the urlpos structure saying
+            that we'd written a .orig file for this URL, but that didn't work,
+            so I had to make this separate list. */
          converted_file_ptr = malloc(sizeof(slist));
          converted_file_ptr = malloc(sizeof(slist));
-         converted_file_ptr->string = strdup(file);
+         converted_file_ptr->string = xstrdup(file);  /* die on out-of-mem. */
          converted_file_ptr->next = converted_files;
          converted_files = converted_file_ptr;
        }
          converted_file_ptr->next = converted_files;
          converted_files = converted_file_ptr;
        }
@@ -1440,6 +1448,8 @@ convert_links (const char *file, urlpos *l)
       free (buf);
       return;
     }
       free (buf);
       return;
     }
+  /* [If someone understands why multiple URLs can correspond to one local file,
+     can they please add a comment here...?] */
   for (p = buf; l; l = l->next)
     {
       if (l->pos >= size)
   for (p = buf; l; l = l->next)
     {
       if (l->pos >= size)
@@ -1547,3 +1557,44 @@ add_url (urlpos *l, const char *url, const char *file)
   t->next = l;
   return t;
 }
   t->next = l;
   return t;
 }
+
+
+/* Remembers which files have been downloaded.  Should be called with
+   add_or_check == ADD_FILE for each file we actually download successfully
+   (i.e. not for ones we have failures on or that we skip due to -N).  If you
+   just want to check if a file has been previously added without adding it,
+   call with add_or_check == CHECK_FOR_FILE.  Please be sure to call this
+   function with local filenames, not remote URLs -- by some means that isn't
+   commented well enough for me understand, multiple remote URLs can apparently
+   correspond to a single local file. */
+boolean
+downloaded_file (downloaded_file_t  add_or_check, const char*  file)
+{
+  boolean        found_file = FALSE;
+  static slist*  downloaded_files = NULL;
+  slist*         rover = downloaded_files;
+
+  while (rover != NULL)
+    if (strcmp(rover->string, file) == 0)
+      {
+       found_file = TRUE;
+       break;
+      }
+    else
+      rover = rover->next;
+
+  if (found_file)
+    return TRUE;  /* file had already been downloaded */
+  else
+    {
+      if (add_or_check == ADD_FILE)
+       {
+         rover = malloc(sizeof(slist));
+         rover->string = xstrdup(file);  /* die on out-of-mem. */
+         rover->next = downloaded_files;
+         downloaded_files = rover;
+       }
+
+      return FALSE;  /* file had not already been downloaded */
+    }
+}
index 771f17a4e89776ebbca6c49cb300f84c3f65d42e..87044cdd497c9309d54bb15a5df376cd4936e57c 100644 (file)
--- a/src/url.h
+++ b/src/url.h
@@ -62,6 +62,12 @@ typedef struct _urlpos
   struct _urlpos *next;        /* Next struct in list */
 } urlpos;
 
   struct _urlpos *next;        /* Next struct in list */
 } urlpos;
 
+/* Controls how downloaded_file() behaves. */
+typedef enum
+{
+  ADD_FILE,
+  CHECK_FOR_FILE
+} downloaded_file_t;
 
 /* Function declarations */
 
 
 /* Function declarations */
 
@@ -95,4 +101,6 @@ int no_proxy_match PARAMS ((const char *, const char **));
 void convert_links PARAMS ((const char *, urlpos *));
 urlpos *add_url PARAMS ((urlpos *, const char *, const char *));
 
 void convert_links PARAMS ((const char *, urlpos *));
 urlpos *add_url PARAMS ((urlpos *, const char *, const char *));
 
+boolean downloaded_file PARAMS ((downloaded_file_t, const char *));
+
 #endif /* URL_H */
 #endif /* URL_H */
index cdc301cfced6a39e10c72a7868ab530d30a925fd..4467f5fbd6829a787f62d89b7855a2f22fc77368 100644 (file)
@@ -198,4 +198,12 @@ typedef enum
   ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED
 } uerr_t;
 
   ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED
 } uerr_t;
 
+typedef unsigned char  boolean;
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE  1
+#endif
+
 #endif /* WGET_H */
 #endif /* WGET_H */