]> sjero.net Git - wget/blobdiff - src/ftp-ls.c
HTML-escape dirname in href (not perfect, good enough).
[wget] / src / ftp-ls.c
index fb1537e26eef559b724b28b1a5493f238c2974d3..181c8d452837807b96dc65e5c5ed36da9cd4a157 100644 (file)
@@ -1,6 +1,6 @@
 /* Parsing FTP `ls' output.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007 Free Software Foundation, Inc. 
+   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 
 
 This file is part of GNU Wget.
 
@@ -28,7 +28,7 @@ Corresponding Source for a non-source form of such a combination
 shall include the source code for the parts of OpenSSL used as well
 as that of the covered work.  */
 
-#include <config.h>
+#include "wget.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -38,8 +38,6 @@ as that of the covered work.  */
 #endif
 #include <errno.h>
 #include <time.h>
-
-#include "wget.h"
 #include "utils.h"
 #include "ftp.h"
 #include "url.h"
@@ -77,6 +75,7 @@ clean_line(char *line)
   if (!len) return 0; 
   if (line[len - 1] == '\n')
     line[--len] = '\0';
+  if (!len) return 0; 
   if (line[len - 1] == '\r')
     line[--len] = '\0';
   for ( ; *line ; line++ ) if (*line == '\t') *line = ' '; 
@@ -253,10 +252,10 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
               year = 0;
               min = hour = sec = 0;
               /* We must deal with digits.  */
-              if (ISDIGIT (*tok))
+              if (c_isdigit (*tok))
                 {
                   /* Suppose it's year.  */
-                  for (; ISDIGIT (*tok); tok++)
+                  for (; c_isdigit (*tok); tok++)
                     year = (*tok - '0') + 10 * year;
                   if (*tok == ':')
                     {
@@ -265,13 +264,13 @@ ftp_parse_unix_ls (const char *file, int ignore_perms)
                       year = 0;
                       ++tok;
                       /* Get the minutes...  */
-                      for (; ISDIGIT (*tok); tok++)
+                      for (; c_isdigit (*tok); tok++)
                         min = (*tok - '0') + 10 * min;
                       if (*tok == ':')
                         {
                           /* ...and the seconds.  */
                           ++tok;
-                          for (; ISDIGIT (*tok); tok++)
+                          for (; c_isdigit (*tok); tok++)
                             sec = (*tok - '0') + 10 * sec;
                         }
                     }
@@ -851,7 +850,9 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
 {
   FILE *fp;
   char *upwd;
+  char *htcldir;                /* HTML-clean dir name */
   char *htclfile;               /* HTML-clean file name */
+  char *urlclfile;              /* URL-clean file name */
 
   if (!output_stream)
     {
@@ -879,12 +880,16 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
     }
   else
     upwd = xstrdup ("");
+
+  htcldir = html_quote_string (u->dir);
+
   fprintf (fp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
   fprintf (fp, "<html>\n<head>\n<title>");
-  fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
+  fprintf (fp, _("Index of /%s on %s:%d"), htcldir, u->host, u->port);
   fprintf (fp, "</title>\n</head>\n<body>\n<h1>");
-  fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
+  fprintf (fp, _("Index of /%s on %s:%d"), htcldir, u->host, u->port);
   fprintf (fp, "</h1>\n<hr>\n<pre>\n");
+
   while (f)
     {
       fprintf (fp, "  ");
@@ -896,7 +901,8 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
             "Jan", "Feb", "Mar", "Apr", "May", "Jun",
             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
           };
-          struct tm *ptm = localtime ((time_t *)&f->tstamp);
+          time_t tstamp = f->tstamp;
+          struct tm *ptm = localtime (&tstamp);
 
           fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
                   ptm->tm_mday);
@@ -923,13 +929,18 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
           break;
         }
       htclfile = html_quote_string (f->name);
+      urlclfile = url_escape_unsafe_and_reserved (f->name);
       fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port);
       if (*u->dir != '/')
         putc ('/', fp);
-      fprintf (fp, "%s", u->dir);
+      /* XXX: Should probably URL-escape dir components here, rather
+       * than just HTML-escape, for consistency with the next bit where
+       * we use urlclfile for the file component. Anyway, this is safer
+       * than what we had... */
+      fprintf (fp, "%s", htcldir);
       if (*u->dir)
         putc ('/', fp);
-      fprintf (fp, "%s", htclfile);
+      fprintf (fp, "%s", urlclfile);
       if (f->type == FT_DIRECTORY)
         putc ('/', fp);
       fprintf (fp, "\">%s", htclfile);
@@ -942,9 +953,11 @@ ftp_index (const char *file, struct url *u, struct fileinfo *f)
         fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
       putc ('\n', fp);
       xfree (htclfile);
+      xfree (urlclfile);
       f = f->next;
     }
   fprintf (fp, "</pre>\n</body>\n</html>\n");
+  xfree (htcldir);
   xfree (upwd);
   if (!output_stream)
     fclose (fp);