]> sjero.net Git - wget/blobdiff - src/ftp-ls.c
[svn] * retr.c (fd_read_body): Report the amount of data *written* as
[wget] / src / ftp-ls.c
index 22d1887aaba48ca458321b6e7993b503ce2a81bc..5c8532294ae348998ab975734391b0167e5b59cd 100644 (file)
@@ -1,22 +1,32 @@
 /* Parsing FTP `ls' output.
-   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation,
-   Inc. 
+   Copyright (C) 1995, 1996, 1997, 2000, 2001
+   Free Software Foundation, Inc. 
 
-This file is part of Wget.
+This file is part of GNU Wget.
 
-This program is free software; you can redistribute it and/or modify
+GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
+GNU Wget is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
 
 #include <config.h>
 
@@ -38,6 +48,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ftp.h"
 #include "url.h"
 
+extern FILE *output_stream;
+
 /* Converts symbolic permissions to number-style ones, e.g. string
    rwxr-xr-x to 755.  For now, it knows nothing of
    setuid/setgid/sticky.  ACLs are ignored.  */
@@ -146,7 +158,7 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
          break;
        default:
          cur.type = FT_UNKNOWN;
-         DEBUGP (("UNKOWN; "));
+         DEBUGP (("UNKNOWN; "));
          break;
        }
 
@@ -155,15 +167,16 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
          switch (cur.type)
            {
            case FT_PLAINFILE:
-             cur.perms = 420;
+             cur.perms = 0644;
              break;
            case FT_DIRECTORY:
-             cur.perms = 493;
+             cur.perms = 0755;
              break;
            default:
-             cur.perms = 1023;
+             /*cur.perms = 1023;*/     /* #### What is this?  --hniksic */
+             cur.perms = 0644;
            }
-         DEBUGP (("implicite perms %0o; ", cur.perms));
+         DEBUGP (("implicit perms %0o; ", cur.perms));
        }
        else
          {
@@ -347,8 +360,8 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
       if (error || ignore)
        {
          DEBUGP (("Skipping.\n"));
-         FREE_MAYBE (cur.name);
-         FREE_MAYBE (cur.linkto);
+         xfree_null (cur.name);
+         xfree_null (cur.linkto);
          xfree (line);
          continue;
        }
@@ -440,9 +453,11 @@ ftp_parse_winnt_ls (const char *file)
       cur.name = xstrdup(tok);
       DEBUGP(("Name: '%s'\n", cur.name));
 
-      /* First column: mm-dd-yy */
+      /* First column: mm-dd-yy. Should atoi() on the month fail, january
+        will be assumed.  */
       tok = strtok(line, "-");
-      month = atoi(tok);
+      month = atoi(tok) - 1;
+      if (month < 0) month = 0;
       tok = strtok(NULL, "-");
       day = atoi(tok);
       tok = strtok(NULL, " ");
@@ -456,9 +471,11 @@ ftp_parse_winnt_ls (const char *file)
       hour = atoi(tok);
       tok = strtok(NULL,  "M");
       min = atoi(tok);
-      /* Adjust hour from AM/PM */
+      /* Adjust hour from AM/PM. Just for the record, the sequence goes
+         11:00AM, 12:00PM, 01:00PM ... 11:00PM, 12:00AM, 01:00AM . */
       tok+=2;
-      if (*tok == 'P') hour = (hour + 12) % 24;
+      if (hour == 12)  hour  = 0;
+      if (*tok == 'P') hour += 12;
 
       DEBUGP(("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n", 
               year+1900, month, day, hour, min));
@@ -487,14 +504,14 @@ ftp_parse_winnt_ls (const char *file)
        {
          cur.type  = FT_DIRECTORY;
          cur.size  = 0;
-         cur.perms = 493; /* my gcc does not like 0755 ?? */
+         cur.perms = 0755;
          DEBUGP(("Directory\n"));
        }
       else
        {
          cur.type  = FT_PLAINFILE;
          cur.size  = atoi(tok);
-         cur.perms = 420; /* 0664 octal */
+         cur.perms = 0644;
          DEBUGP(("File, size %ld bytes\n", cur.size));
        }
 
@@ -561,7 +578,7 @@ ftp_parse_vms_ls (const char *file)
   int hour, min, sec;
   struct tm timestruct;
 
-  char *line, *tok, *p;          /* tokenizer */
+  char *line, *tok;             /* tokenizer */
   struct fileinfo *dir, *l, cur; /* list creation */
 
   fp = fopen (file, "rb");
@@ -572,18 +589,31 @@ ftp_parse_vms_ls (const char *file)
     }
   dir = l = NULL;
 
-  /* Empty line */
-  read_whole_line (fp);
-  /* "Directory PUB$DEVICE[PUB]" */
-  read_whole_line (fp);
-  /* Empty line */
-  read_whole_line (fp);
+  /* Skip empty line. */
+  line = read_whole_line (fp);
+  if (line)
+    xfree (line);
+
+  /* Skip "Directory PUB$DEVICE[PUB]" */
+  line = read_whole_line (fp);
+  if (line)
+    xfree (line);
+
+  /* Skip empty line. */
+  line = read_whole_line (fp);
+  if (line)
+    xfree (line);
 
   /* Line loop to end of file: */
   while ((line = read_whole_line (fp)))
     {
+      char *p;
       i = clean_line (line);
-      if (!i) break;
+      if (!i)
+       {
+         xfree (line);
+         break;
+       }
 
       /* First column: Name. A bit of black magic again. The name my be
          either ABCD.EXT or ABCD.EXT;NUM and it might be on a separate
@@ -640,6 +670,7 @@ ftp_parse_vms_ls (const char *file)
         if (!i) 
         {
           DEBUGP(("confusing VMS listing item, leaving listing parser\n"));
+         xfree (line);
           break;
         }
         tok = strtok(line, " ");
@@ -659,22 +690,27 @@ ftp_parse_vms_ls (const char *file)
            the first strtok(NULL, "-") will return everything until the end
            of the line and only the next strtok() call will return NULL. */
         DEBUGP(("nonsense in VMS listing, skipping this line\n"));
+       xfree (line);
         break;
       }
       for (i=0; i<12; i++) if (!strcmp(tok,months[i])) break;
       /* Uknown months are mapped to January */
-      month = (i%12)+1
-      tok = strtok(NULL, " ");
-      year = atoi(tok)-1900;
+      month = i % 12 
+      tok = strtok (NULL, " ");
+      year = atoi (tok) - 1900;
       DEBUGP(("date parsed\n"));
 
-      /* Fourth/Third column: Time hh:mm:ss */
-      tok = strtok(NULL,  ":");
-      hour = atoi(tok);
-      tok = strtok(NULL,  ":");
-      min = atoi(tok);
-      tok = strtok(NULL,  " ");
-      sec = atoi(tok);
+      /* Fourth/Third column: Time hh:mm[:ss] */
+      tok = strtok (NULL, " ");
+      hour = min = sec = 0;
+      p = tok;
+      hour = atoi (p);
+      for (; *p && *p != ':'; ++p);
+      if (*p)
+       min = atoi (++p);
+      for (; *p && *p != ':'; ++p);
+      if (*p)
+       sec = atoi (++p);
 
       DEBUGP(("YYYY/MM/DD HH:MM:SS - %d/%02d/%02d %02d:%02d:%02d\n", 
               year+1900, month, day, hour, min, sec));
@@ -704,6 +740,7 @@ ftp_parse_vms_ls (const char *file)
       if (tok == NULL)
         {
           DEBUGP(("confusing VMS permissions, skipping line\n"));
+         xfree (line);
           continue;
         }
       /* Permissons have the format "RWED,RWED,RE" */
@@ -748,7 +785,7 @@ ftp_parse_ls (const char *file, const enum stype system_type)
   switch (system_type)
     {
     case ST_UNIX:
-      return ftp_parse_unix_ls (file, FALSE);
+      return ftp_parse_unix_ls (file, 0);
     case ST_WINNT:
       {
        /* Detect whether the listing is simulating the UNIX format */
@@ -767,16 +804,16 @@ ftp_parse_ls (const char *file, const enum stype system_type)
        if (c >= '0' && c <='9')
          return ftp_parse_winnt_ls (file);
         else
-          return ftp_parse_unix_ls (file, TRUE);
+          return ftp_parse_unix_ls (file, 1);
       }
     case ST_VMS:
       return ftp_parse_vms_ls (file);
     case ST_MACOS:
-      return ftp_parse_unix_ls (file, TRUE);
+      return ftp_parse_unix_ls (file, 1);
     default:
       logprintf (LOG_NOTQUIET, _("\
-Usupported listing type, trying Unix listing parser.\n"));
-      return ftp_parse_unix_ls (file, FALSE);
+Unsupported listing type, trying Unix listing parser.\n"));
+      return ftp_parse_unix_ls (file, 0);
     }
 }
 \f
@@ -786,13 +823,13 @@ Usupported listing type, trying Unix listing parser.\n"));
    directories and files on the appropriate host.  The references are
    FTP.  */
 uerr_t
-ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
+ftp_index (const char *file, struct url *u, struct fileinfo *f)
 {
   FILE *fp;
   char *upwd;
   char *htclfile;              /* HTML-clean file name */
 
-  if (!opt.dfp)
+  if (!output_stream)
     {
       fp = fopen (file, "wb");
       if (!fp)
@@ -802,18 +839,18 @@ ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
        }
     }
   else
-    fp = opt.dfp;
+    fp = output_stream;
   if (u->user)
     {
       char *tmpu, *tmpp;        /* temporary, clean user and passwd */
 
-      tmpu = CLEANDUP (u->user);
-      tmpp = u->passwd ? CLEANDUP (u->passwd) : NULL;
+      tmpu = url_escape (u->user);
+      tmpp = u->passwd ? url_escape (u->passwd) : NULL;
       upwd = (char *)xmalloc (strlen (tmpu)
                             + (tmpp ? (1 + strlen (tmpp)) : 0) + 2);
       sprintf (upwd, "%s%s%s@", tmpu, tmpp ? ":" : "", tmpp ? tmpp : "");
       xfree (tmpu);
-      FREE_MAYBE (tmpp);
+      xfree_null (tmpp);
     }
   else
     upwd = xstrdup ("");
@@ -828,7 +865,8 @@ ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
       fprintf (fp, "  ");
       if (f->tstamp != -1)
        {
-         /* #### Should we translate the months? */
+         /* #### Should we translate the months?  Or, even better, use
+            ISO 8601 dates?  */
          static char *months[] = {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
@@ -883,7 +921,7 @@ ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
     }
   fprintf (fp, "</pre>\n</body>\n</html>\n");
   xfree (upwd);
-  if (!opt.dfp)
+  if (!output_stream)
     fclose (fp);
   else
     fflush (fp);