- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+ Inc.
- int len = strlen (line);
- if (!len) return 0;
- if (line[len - 1] == '\n')
- line[--len] = '\0';
- if (line[len - 1] == '\r')
+ if (len <= 0) return 0;
+
+ while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
};
int next, len, i, error, ignore;
int year, month, day; /* for time analysis */
};
int next, len, i, error, ignore;
int year, month, day; /* for time analysis */
/* Get the first token (permissions). */
tok = strtok (line, " ");
if (!tok)
/* Get the first token (permissions). */
tok = strtok (line, " ");
if (!tok)
next = -1;
/* While there are tokens on the line, parse them. Next is the
number of tokens left until the filename.
next = -1;
/* While there are tokens on the line, parse them. Next is the
number of tokens left until the filename.
- len = clean_line (line);
-
- /* Extracting name is a bit of black magic and we have to do it
- before `strtok' inserted extra \0 characters in the line
- string. For the moment let us just suppose that the name starts at
- column 39 of the listing. This way we could also recognize
- filenames that begin with a series of space characters (but who
- really wants to use such filenames anyway?). */
+ len = clean_line (line, len);
+
+ /* Name begins at 39 column of the listing if date presented in `mm-dd-yy'
+ format or at 41 column if date presented in `mm-dd-yyyy' format. Thus,
+ we cannot extract name before we parse date. Using this information we
+ also can recognize filenames that begin with a series of space
+ characters (but who really wants to use such filenames anyway?). */
- if (year <= 70) year += 100;
+ if (year <= 70)
+ {
+ year += 100;
+ }
+ else if (year >= 1900)
+ {
+ year -= 1900;
+ filename += 2;
+ }
+ /* Now it is possible to determine the position of the first symbol in
+ filename. */
+ cur.name = xstrdup(filename);
+ DEBUGP (("Name: '%s'\n", cur.name));
+
year+1900, month, day, hour, min));
year+1900, month, day, hour, min));
/* Third column: Either file length, or <DIR>. We also set the
permissions (guessed as 0644 for plain files and 0755 for
/* Third column: Either file length, or <DIR>. We also set the
permissions (guessed as 0644 for plain files and 0755 for
more or less. (Different VMS FTP servers may have different headers,
and may not supply the same data, but all should be subsets of this.)
more or less. (Different VMS FTP servers may have different headers,
and may not supply the same data, but all should be subsets of this.)
Define the logical name or environment variable
"WGET_TIMEZONE_DIFFERENTIAL" (seconds) to adjust the receiving local
times if different from the remote local times.
Define the logical name or environment variable
"WGET_TIMEZONE_DIFFERENTIAL" (seconds) to adjust the receiving local
times if different from the remote local times.
- line = read_whole_line (fp);
- if (line == NULL)
+ i = clean_line (line, i);
+ if (i <= 0)
+ continue; /* Ignore blank line. */
+
+ if ((j == 0) && (line[i - 1] == ']'))
+ /* Found Directory heading line. Next non-blank line
+ is significant. */
+ j = 1;
+ }
+ else if (!strncmp (line, "Total of ", 9))
+ {
+ /* Found "Total of ..." footing line. No valid data
+ will follow (empty directory). */
+ i = 0; /* Arrange for early exit. */
+ break;
- i = clean_line (line);
- if (i <= 0)
- {
- xfree (line); /* Free useless line storage. */
- continue; /* Blank line. Keep looking. */
- }
- else
- {
- if ((j == 0) && (line[ i- 1] == ']'))
- {
- /* Found Directory heading line. Next non-blank line
- is significant.
- */
- j = 1;
- }
- else if (!strncmp (line, "Total of ", 9))
- {
- /* Found "Total of ..." footing line. No valid data
- will follow (empty directory).
- */
- xfree (line); /* Free useless line storage. */
- line = NULL; /* Arrange for early exit. */
- break;
- }
- else
- {
- break; /* Must be significant data. */
- }
- }
- xfree (line); /* Free useless line storage. */
+ break; /* Must be significant data. */
/* Stripping the version number on a VMS system would be wrong.
It may be foolish on a non-VMS system, too, but that's someone
/* Stripping the version number on a VMS system would be wrong.
It may be foolish on a non-VMS system, too, but that's someone
/* Differentiate between a directory and any other file. A VMS
listing may not include file protections (permissions). Set a
/* Differentiate between a directory and any other file. A VMS
listing may not include file protections (permissions). Set a
".DIR;1" file type and version number, as the plain name is
what will work in a CWD command.
*/
".DIR;1" file type and version number, as the plain name is
what will work in a CWD command.
*/
- cur.name = xstrdup(tok);
- DEBUGP(("Name: '%s'\n", cur.name));
+ cur.name = xstrdup (tok);
+ DEBUGP (("Name: '%s'\n", cur.name));
/* Get token 2, if any. A long name may force all other data onto
a second line. If needed, read the second line.
*/
/* Get token 2, if any. A long name may force all other data onto
a second line. If needed, read the second line.
*/
- DEBUGP(("Getting additional line.\n"));
- xfree (line);
- line = read_whole_line (fp);
- if (!line)
+ DEBUGP (("Getting additional line.\n"));
+ i = getline (&line, &bufsize, fp);
+ if (i <= 0)
break;
}
/* Second line must begin with " ". Otherwise, it's a first
line (and we may be confused).
*/
break;
}
/* Second line must begin with " ". Otherwise, it's a first
line (and we may be confused).
*/
- DEBUGP(("Blank line. Leaving listing parser.\n"));
- xfree (line); /* Free useless line storage. */
- break;
- }
- else if (line[ 0] != ' ')
+ DEBUGP (("Blank line. Leaving listing parser.\n"));
+ break;
+ }
+ else if (line[0] != ' ')
Time: HH:MM or HH:MM:SS or HH:MM:SS.CC
Owner: [user] or [user,group]
Protection: (ppp,ppp,ppp,ppp) (where "ppp" is "RWED" or some
Time: HH:MM or HH:MM:SS or HH:MM:SS.CC
Owner: [user] or [user,group]
Protection: (ppp,ppp,ppp,ppp) (where "ppp" is "RWED" or some
- subset thereof, for System, Owner, Group, World.
+ subset thereof, for System, Owner, Group, World.
If permission is lacking, info may be replaced by the string:
"No privilege for attempted operation".
*/
while (tok != NULL)
If permission is lacking, info may be replaced by the string:
"No privilege for attempted operation".
*/
while (tok != NULL)
- {
- DEBUGP (("Token: >%s<: ", tok));
-
- if ((strlen( tok) < 12) && (strchr( tok, '-') != NULL))
- {
- /* Date. */
- DEBUGP (("Date.\n"));
- strcpy( date_str, tok);
- strcat( date_str, " ");
- }
- else if ((strlen( tok) < 12) && (strchr( tok, ':') != NULL))
- {
- /* Time. */
- DEBUGP (("Time. "));
- strncat( date_str,
- tok,
- (sizeof( date_str)- strlen( date_str)- 1));
- DEBUGP (("Date time: >%s<\n", date_str));
- }
- else if (strchr( tok, '[') != NULL)
- {
- /* Owner. (Ignore.) */
- DEBUGP (("Owner.\n"));
- }
- else if (strchr( tok, '(') != NULL)
- {
- /* Protections (permissions). */
- perms = 0;
- j = 0;
- for (i = 0; i < strlen( tok); i++)
- {
- switch (tok[ i])
- {
- case '(':
- break;
- case ')':
- break;
- case ',':
- if (j == 0)
- {
- perms = 0;
- j = 1;
- }
- else
- {
- perms <<= 3;
- }
- break;
- case 'R':
- perms |= 4;
- break;
- case 'W':
- perms |= 2;
- break;
- case 'E':
- perms |= 1;
- break;
- case 'D':
- perms |= 2;
- break;
- }
- }
- cur.perms = perms;
- DEBUGP (("Prot. perms = %0o.\n", cur.perms));
- }
- else
- {
- /* Nondescript. Probably size(s), probably in blocks.
+ {
+ DEBUGP (("Token: >%s<: ", tok));
+
+ if ((strlen (tok) < 12) && (strchr( tok, '-') != NULL))
+ {
+ /* Date. */
+ DEBUGP (("Date.\n"));
+ strcpy( date_str, tok);
+ strcat( date_str, " ");
+ }
+ else if ((strlen (tok) < 12) && (strchr( tok, ':') != NULL))
+ {
+ /* Time. */
+ DEBUGP (("Time. "));
+ strncat( date_str,
+ tok,
+ (sizeof( date_str)- strlen (date_str) - 1));
+ DEBUGP (("Date time: >%s<\n", date_str));
+ }
+ else if (strchr (tok, '[') != NULL)
+ {
+ /* Owner. (Ignore.) */
+ DEBUGP (("Owner.\n"));
+ }
+ else if (strchr (tok, '(') != NULL)
+ {
+ /* Protections (permissions). */
+ perms = 0;
+ j = 0;
+ for (i = 0; i < strlen(tok); i++)
+ {
+ switch (tok[ i])
+ {
+ case '(':
+ break;
+ case ')':
+ break;
+ case ',':
+ if (j == 0)
+ {
+ perms = 0;
+ j = 1;
+ }
+ else
+ {
+ perms <<= 3;
+ }
+ break;
+ case 'R':
+ perms |= 4;
+ break;
+ case 'W':
+ perms |= 2;
+ break;
+ case 'E':
+ perms |= 1;
+ break;
+ case 'D':
+ perms |= 2;
+ break;
+ }
+ }
+ cur.perms = perms;
+ DEBUGP (("Prot. perms = %0o.\n", cur.perms));
+ }
+ else
+ {
+ /* Nondescript. Probably size(s), probably in blocks.
- localtime_r( &timenow, ×truct);
- strptime( date_str, "%d-%b-%Y %H:%M:%S", ×truct);
+ timestruct = localtime( &timenow );
+ strptime( date_str, "%d-%b-%Y %H:%M:%S", timestruct);
fprintf (fp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
fprintf (fp, "<html>\n<head>\n<title>");
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, _("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);
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
ptm->tm_mday);
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
ptm->tm_mday);
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
else
fprintf (fp, " ");
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
else
fprintf (fp, " ");
fprintf (fp, "<a href=\"ftp://%s%s:%d", upwd, u->host, u->port);
if (*u->dir != '/')
putc ('/', fp);
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 (f->type == FT_DIRECTORY)
putc ('/', fp);
fprintf (fp, "\">%s", htclfile);
if (f->type == FT_DIRECTORY)
putc ('/', fp);
fprintf (fp, "\">%s", htclfile);