X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fftp-basic.c;h=7d36bf267c6f4f3f1ae2a12972dd5a861a10bc4b;hb=d5be8ecca466601bda9b81c28a79077fbda6ccde;hp=d6d7c5a96572ea9421238ccd3e92daf3af7d1fe8;hpb=2e8fc46b7b969039590758c4d0542dd72798e15f;p=wget diff --git a/src/ftp-basic.c b/src/ftp-basic.c index d6d7c5a9..7d36bf26 100644 --- a/src/ftp-basic.c +++ b/src/ftp-basic.c @@ -1,32 +1,33 @@ /* Basic FTP routines. Copyright (C) 1995, 1996, 1997, 1998, 2000 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 +along with Wget; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include +#include + #ifdef HAVE_STRING_H # include #else # include #endif -#include #ifdef HAVE_UNISTD_H # include #endif @@ -60,33 +61,33 @@ ftp_response (struct rbuf *rbuf, char **line) do { for (i = 0; 1; i++) - { - int res; - if (i > bufsize - 1) - *line = (char *)xrealloc (*line, (bufsize <<= 1)); - res = RBUF_READCHAR (rbuf, *line + i); - /* RES is number of bytes read. */ - if (res == 1) - { - if ((*line)[i] == '\n') - { - (*line)[i] = '\0'; - /* Get rid of \r. */ - if (i > 0 && (*line)[i - 1] == '\r') - (*line)[i - 1] = '\0'; - break; - } - } - else - return FTPRERR; - } + { + int res; + if (i > bufsize - 1) + *line = (char *)xrealloc (*line, (bufsize <<= 1)); + res = RBUF_READCHAR (rbuf, *line + i); + /* RES is number of bytes read. */ + if (res == 1) + { + if ((*line)[i] == '\n') + { + (*line)[i] = '\0'; + /* Get rid of \r. */ + if (i > 0 && (*line)[i - 1] == '\r') + (*line)[i - 1] = '\0'; + break; + } + } + else + return FTPRERR; + } if (opt.server_response) - logprintf (LOG_ALWAYS, "%s\n", *line); + logprintf (LOG_ALWAYS, "%s\n", *line); else - DEBUGP (("%s\n", *line)); + DEBUGP (("%s\n", *line)); } while (!(i >= 3 && ISDIGIT (**line) && ISDIGIT ((*line)[1]) && - ISDIGIT ((*line)[2]) && (*line)[3] == ' ')); + ISDIGIT ((*line)[2]) && (*line)[3] == ' ')); strncpy (ftp_last_respline, *line, sizeof (ftp_last_respline)); ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0'; return FTPOK; @@ -99,16 +100,16 @@ static char * ftp_request (const char *command, const char *value) { char *res = (char *)xmalloc (strlen (command) - + (value ? (1 + strlen (value)) : 0) - + 2 + 1); + + (value ? (1 + strlen (value)) : 0) + + 2 + 1); sprintf (res, "%s%s%s\r\n", command, value ? " " : "", value ? value : ""); if (opt.server_response) { /* Hack: don't print out password. */ if (strncmp (res, "PASS", 4) != 0) - logprintf (LOG_ALWAYS, "--> %s\n", res); + logprintf (LOG_ALWAYS, "--> %s\n", res); else - logputs (LOG_ALWAYS, "--> PASS Turtle Power!\n"); + logputs (LOG_ALWAYS, "--> PASS Turtle Power!\n"); } else DEBUGP (("\n--> %s\n", res)); @@ -179,31 +180,31 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass) for (i = 0; i < ARRAY_SIZE (skey_head); i++) { - if (strncasecmp (skey_head[i], respline, strlen (skey_head[i])) == 0) - break; + if (strncasecmp (skey_head[i], respline, strlen (skey_head[i])) == 0) + break; } if (i < ARRAY_SIZE (skey_head)) { - const char *cp; - int skey_sequence = 0; - - for (cp = respline + strlen (skey_head[i]); - '0' <= *cp && *cp <= '9'; - cp++) - { - skey_sequence = skey_sequence * 10 + *cp - '0'; - } - if (*cp == ' ') - cp++; - else - { - bad: - xfree (respline); - return FTPLOGREFUSED; - } - if ((cp = calculate_skey_response (skey_sequence, cp, pass)) == 0) - goto bad; - pass = cp; + const char *cp; + int skey_sequence = 0; + + for (cp = respline + strlen (skey_head[i]); + '0' <= *cp && *cp <= '9'; + cp++) + { + skey_sequence = skey_sequence * 10 + *cp - '0'; + } + if (*cp == ' ') + cp++; + else + { + bad: + xfree (respline); + return FTPLOGREFUSED; + } + if ((cp = calculate_skey_response (skey_sequence, cp, pass)) == 0) + goto bad; + pass = cp; } } #endif /* USE_OPIE */ @@ -258,8 +259,8 @@ ftp_port (struct rbuf *rbuf) /* Construct the argument of PORT (of the form a,b,c,d,e,f). */ bytes = (char *)alloca (6 * 4 + 1); sprintf (bytes, "%d,%d,%d,%d,%d,%d", in_addr[0], in_addr[1], - in_addr[2], in_addr[3], (unsigned) (port & 0xff00) >> 8, - port & 0xff); + in_addr[2], in_addr[3], (unsigned) (port & 0xff00) >> 8, + port & 0xff); /* Send PORT request. */ request = ftp_request ("PORT", bytes); nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request)); @@ -326,15 +327,15 @@ ftp_pasv (struct rbuf *rbuf, unsigned char *addr) { addr[i] = 0; for (; ISDIGIT (*s); s++) - addr[i] = (*s - '0') + 10 * addr[i]; + addr[i] = (*s - '0') + 10 * addr[i]; if (*s == ',') - s++; + s++; else if (i < 5) - { - /* When on the last number, anything can be a terminator. */ - xfree (respline); - return FTPINVPASV; - } + { + /* When on the last number, anything can be a terminator. */ + xfree (respline); + return FTPINVPASV; + } } xfree (respline); return FTPOK; @@ -578,7 +579,10 @@ ftp_syst (struct rbuf *rbuf, enum stype *server_type) if (!strcasecmp (request, "WINDOWS_NT")) *server_type = ST_WINNT; else - *server_type = ST_OTHER; + if (!strcasecmp (request, "MACOS")) + *server_type = ST_MACOS; + else + *server_type = ST_OTHER; xfree (respline); /* All OK. */ @@ -629,3 +633,74 @@ ftp_pwd (struct rbuf *rbuf, char **pwd) /* All OK. */ return FTPOK; } + +/* Sends the SIZE command to the server, and returns the value in 'size'. + * If an error occurs, size is set to zero. */ +uerr_t +ftp_size (struct rbuf *rbuf, const char *file, long int *size) +{ + char *request, *respline; + int nwritten; + uerr_t err; + + /* Send PWD request. */ + request = ftp_request ("SIZE", file); + nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request)); + if (nwritten < 0) + { + xfree (request); + *size = 0; + return WRITEFAILED; + } + xfree (request); + /* Get appropriate response. */ + err = ftp_response (rbuf, &respline); + if (err != FTPOK) + { + xfree (respline); + *size = 0; + return err; + } + if (*respline == '5') + { + /* + * Probably means SIZE isn't supported on this server. + * Error is nonfatal since SIZE isn't in RFC 959 + */ + xfree (respline); + *size = 0; + return FTPOK; + } + + errno = 0; + *size = strtol (respline + 4, NULL, 0); + if (errno) + { + /* + * Couldn't parse the response for some reason. On the (few) + * tests I've done, the response is 213 with nothing else - + * maybe something a bit more resilient is necessary. It's not a + * fatal error, however. + */ + xfree (respline); + *size = 0; + return FTPOK; + } + + xfree (respline); + /* All OK. */ + return FTPOK; +} + +/* If URL's params are of the form "type=X", return character X. + Otherwise, return 'I' (the default type). */ +char +ftp_process_type (const char *params) +{ + if (params + && 0 == strncasecmp (params, "type=", 5) + && params[5] != '\0') + return TOUPPER (params[5]); + else + return 'I'; +}