mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Commit my url.c fix (space as unsafe character) and Jan's
winnt directory listing parsing.
This commit is contained in:
parent
518fe8d06d
commit
7b5ad90acf
@ -1,3 +1,8 @@
|
|||||||
|
2000-12-05 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||||
|
|
||||||
|
* url.c (init_unsafe_char_table): Reinstate space as an unsafe
|
||||||
|
char.
|
||||||
|
|
||||||
2000-11-29 John Summerfield <summer@OS2.ami.com.au>
|
2000-11-29 John Summerfield <summer@OS2.ami.com.au>
|
||||||
|
|
||||||
* netrc.c (parse_netrc): Get rid of line ending.
|
* netrc.c (parse_netrc): Get rid of line ending.
|
||||||
|
@ -541,7 +541,7 @@ ftp_list (struct rbuf *rbuf, const char *file)
|
|||||||
|
|
||||||
/* Sends the SYST command to the server. */
|
/* Sends the SYST command to the server. */
|
||||||
uerr_t
|
uerr_t
|
||||||
ftp_syst (struct rbuf *rbuf, enum stype *host_type)
|
ftp_syst (struct rbuf *rbuf, enum stype *server_type)
|
||||||
{
|
{
|
||||||
char *request, *respline;
|
char *request, *respline;
|
||||||
int nwritten;
|
int nwritten;
|
||||||
@ -577,12 +577,15 @@ ftp_syst (struct rbuf *rbuf, enum stype *host_type)
|
|||||||
request = strtok (NULL, " ");
|
request = strtok (NULL, " ");
|
||||||
|
|
||||||
if (!strcasecmp (request, "VMS"))
|
if (!strcasecmp (request, "VMS"))
|
||||||
*host_type = ST_VMS;
|
*server_type = ST_VMS;
|
||||||
else
|
else
|
||||||
if (!strcasecmp (request, "UNIX"))
|
if (!strcasecmp (request, "UNIX"))
|
||||||
*host_type = ST_UNIX;
|
*server_type = ST_UNIX;
|
||||||
else
|
else
|
||||||
*host_type = ST_OTHER;
|
if (!strcasecmp (request, "WINDOWS_NT"))
|
||||||
|
*server_type = ST_WINNT;
|
||||||
|
else
|
||||||
|
*server_type = ST_OTHER;
|
||||||
|
|
||||||
xfree (respline);
|
xfree (respline);
|
||||||
/* All OK. */
|
/* All OK. */
|
||||||
|
174
src/ftp-ls.c
174
src/ftp-ls.c
@ -76,7 +76,7 @@ symperms (const char *s)
|
|||||||
The time stamps are stored in a separate variable, time_t
|
The time stamps are stored in a separate variable, time_t
|
||||||
compatible (I hope). The timezones are ignored. */
|
compatible (I hope). The timezones are ignored. */
|
||||||
static struct fileinfo *
|
static struct fileinfo *
|
||||||
ftp_parse_unix_ls (const char *file)
|
ftp_parse_unix_ls (const char *file, int ignore_perms)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
static const char *months[] = {
|
static const char *months[] = {
|
||||||
@ -149,10 +149,28 @@ ftp_parse_unix_ls (const char *file)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ignore_perms)
|
||||||
|
{
|
||||||
|
switch (cur.type)
|
||||||
|
{
|
||||||
|
case FT_PLAINFILE:
|
||||||
|
cur.perms = 420;
|
||||||
|
break;
|
||||||
|
case FT_DIRECTORY:
|
||||||
|
cur.perms = 493;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cur.perms = 1023;
|
||||||
|
}
|
||||||
|
DEBUGP (("implicite perms %0o; ", cur.perms));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
cur.perms = symperms (tok + 1);
|
cur.perms = symperms (tok + 1);
|
||||||
DEBUGP (("perms %0o; ", cur.perms));
|
DEBUGP (("perms %0o; ", cur.perms));
|
||||||
|
}
|
||||||
|
|
||||||
error = ignore = 0; /* Errnoeous and ignoring entries are
|
error = ignore = 0; /* Erroneous and ignoring entries are
|
||||||
treated equally for now. */
|
treated equally for now. */
|
||||||
year = hour = min = sec = 0; /* Silence the compiler. */
|
year = hour = min = sec = 0; /* Silence the compiler. */
|
||||||
month = day = 0;
|
month = day = 0;
|
||||||
@ -385,6 +403,133 @@ ftp_parse_unix_ls (const char *file)
|
|||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct fileinfo *
|
||||||
|
ftp_parse_winnt_ls (const char *file)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int len;
|
||||||
|
int year, month, day; /* for time analysis */
|
||||||
|
int hour, min, sec;
|
||||||
|
struct tm timestruct;
|
||||||
|
|
||||||
|
char *line, *tok; /* tokenizer */
|
||||||
|
struct fileinfo *dir, *l, cur; /* list creation */
|
||||||
|
|
||||||
|
fp = fopen (file, "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dir = l = NULL;
|
||||||
|
|
||||||
|
/* Line loop to end of file: */
|
||||||
|
while ((line = read_whole_line (fp)))
|
||||||
|
{
|
||||||
|
DEBUGP (("%s\n", line));
|
||||||
|
len = strlen (line);
|
||||||
|
/* Destroy <CR><LF> if present. */
|
||||||
|
if (len && line[len - 1] == '\n')
|
||||||
|
line[--len] = '\0';
|
||||||
|
if (len && line[len - 1] == '\r')
|
||||||
|
line[--len] = '\0';
|
||||||
|
|
||||||
|
/* 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?). */
|
||||||
|
if (len < 40) continue;
|
||||||
|
tok = line + 39;
|
||||||
|
cur.name = xstrdup(tok);
|
||||||
|
DEBUGP(("Name: '%s'\n", cur.name));
|
||||||
|
|
||||||
|
/* First column: mm-dd-yy */
|
||||||
|
tok = strtok(line, "-");
|
||||||
|
month = atoi(tok);
|
||||||
|
tok = strtok(NULL, "-");
|
||||||
|
day = atoi(tok);
|
||||||
|
tok = strtok(NULL, " ");
|
||||||
|
year = atoi(tok);
|
||||||
|
/* Assuming the epoch starting at 1.1.1970 */
|
||||||
|
if (year <= 70) year += 100;
|
||||||
|
|
||||||
|
/* Second column: hh:mm[AP]M */
|
||||||
|
tok = strtok(NULL, ":");
|
||||||
|
hour = atoi(tok);
|
||||||
|
tok = strtok(NULL, "M");
|
||||||
|
min = atoi(tok);
|
||||||
|
/* Adjust hour from AM/PM */
|
||||||
|
tok+=2;
|
||||||
|
if (*tok == 'P') hour += 12;
|
||||||
|
/* Listing does not contain value for seconds */
|
||||||
|
sec = 0;
|
||||||
|
|
||||||
|
DEBUGP(("YYYY/MM/DD HH:MM - %d/%02d/%02d %02d:%02d\n",
|
||||||
|
year+1900, month, day, hour, min));
|
||||||
|
|
||||||
|
/* Build the time-stamp (copy & paste from above) */
|
||||||
|
timestruct.tm_sec = sec;
|
||||||
|
timestruct.tm_min = min;
|
||||||
|
timestruct.tm_hour = hour;
|
||||||
|
timestruct.tm_mday = day;
|
||||||
|
timestruct.tm_mon = month;
|
||||||
|
timestruct.tm_year = year;
|
||||||
|
timestruct.tm_wday = 0;
|
||||||
|
timestruct.tm_yday = 0;
|
||||||
|
timestruct.tm_isdst = -1;
|
||||||
|
cur.tstamp = mktime (×truct); /* store the time-stamp */
|
||||||
|
|
||||||
|
DEBUGP(("Timestamp: %ld\n", cur.tstamp));
|
||||||
|
|
||||||
|
/* Third column: Either file length, or <DIR>. We also set the
|
||||||
|
permissions (guessed as 0644 for plain files and 0755 for
|
||||||
|
directories as the listing does not give us a clue) and filetype
|
||||||
|
here. */
|
||||||
|
tok = strtok(NULL, " ");
|
||||||
|
while (*tok == '\0') tok = strtok(NULL, " ");
|
||||||
|
if (*tok == '<')
|
||||||
|
{
|
||||||
|
cur.type = FT_DIRECTORY;
|
||||||
|
cur.size = 0;
|
||||||
|
cur.perms = 493; /* my gcc does not like 0755 ?? */
|
||||||
|
DEBUGP(("Directory\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur.type = FT_PLAINFILE;
|
||||||
|
cur.size = atoi(tok);
|
||||||
|
cur.perms = 420; /* 0664 octal */
|
||||||
|
DEBUGP(("File, size %ld bytes\n", cur.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.linkto = NULL;
|
||||||
|
|
||||||
|
/* And put everything into the linked list */
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
|
||||||
|
memcpy (l, &cur, sizeof (cur));
|
||||||
|
l->prev = l->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur.prev = l;
|
||||||
|
l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
|
||||||
|
l = l->next;
|
||||||
|
memcpy (l, &cur, sizeof (cur));
|
||||||
|
l->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_FTPPARSE
|
#ifdef HAVE_FTPPARSE
|
||||||
|
|
||||||
/* This is a "glue function" that connects the ftpparse interface to
|
/* This is a "glue function" that connects the ftpparse interface to
|
||||||
@ -477,12 +622,31 @@ ftp_parse_nonunix_ls (const char *file)
|
|||||||
struct fileinfo *
|
struct fileinfo *
|
||||||
ftp_parse_ls (const char *file, const enum stype system_type)
|
ftp_parse_ls (const char *file, const enum stype system_type)
|
||||||
{
|
{
|
||||||
if (system_type == ST_UNIX)
|
switch (system_type)
|
||||||
{
|
{
|
||||||
return ftp_parse_unix_ls (file);
|
case ST_UNIX:
|
||||||
|
return ftp_parse_unix_ls (file, FALSE);
|
||||||
|
case ST_WINNT:
|
||||||
|
{
|
||||||
|
/* Detect whether the listing is simulating the UNIX format */
|
||||||
|
FILE *fp;
|
||||||
|
int c;
|
||||||
|
fp = fopen (file, "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
c = fgetc(fp);
|
||||||
|
fclose(fp);
|
||||||
|
/* If the first character of the file is '0'-'9', it's WINNT
|
||||||
|
format. */
|
||||||
|
if (c >= '0' && c <='9')
|
||||||
|
return ftp_parse_winnt_ls (file);
|
||||||
else
|
else
|
||||||
{
|
return ftp_parse_unix_ls (file, TRUE);
|
||||||
|
}
|
||||||
|
default:
|
||||||
#ifdef HAVE_FTPPARSE
|
#ifdef HAVE_FTPPARSE
|
||||||
return ftp_parse_nonunix_ls (file);
|
return ftp_parse_nonunix_ls (file);
|
||||||
#else
|
#else
|
||||||
|
@ -353,6 +353,7 @@ Error in server response, closing control connection.\n"));
|
|||||||
/* Change working directory. If the FTP host runs VMS and
|
/* Change working directory. If the FTP host runs VMS and
|
||||||
the path specified is absolute, we will have to convert
|
the path specified is absolute, we will have to convert
|
||||||
it to VMS style as VMS does not like leading slashes */
|
it to VMS style as VMS does not like leading slashes */
|
||||||
|
DEBUGP (("changing working directory\n"));
|
||||||
if (*(u->dir) == '/')
|
if (*(u->dir) == '/')
|
||||||
{
|
{
|
||||||
int pwd_len = strlen (pwd);
|
int pwd_len = strlen (pwd);
|
||||||
@ -375,6 +376,7 @@ Error in server response, closing control connection.\n"));
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_UNIX:
|
case ST_UNIX:
|
||||||
|
case ST_WINNT:
|
||||||
/* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
|
/* pwd_len == 1 means pwd = "/", but u->dir begins with '/'
|
||||||
already */
|
already */
|
||||||
if (pwd_len > 1)
|
if (pwd_len > 1)
|
||||||
|
@ -26,6 +26,7 @@ enum stype
|
|||||||
{
|
{
|
||||||
ST_UNIX,
|
ST_UNIX,
|
||||||
ST_VMS,
|
ST_VMS,
|
||||||
|
ST_WINNT,
|
||||||
ST_OTHER
|
ST_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user