version 1.77, 2008/06/15 04:43:20 |
version 1.78, 2008/06/25 21:15:19 |
|
|
#ifndef SMALL |
#ifndef SMALL |
#include <openssl/ssl.h> |
#include <openssl/ssl.h> |
#include <openssl/err.h> |
#include <openssl/err.h> |
#else |
#else /* !SMALL */ |
#define SSL void |
#define SSL void |
#endif |
#endif /* !SMALL */ |
|
|
#include "ftp_var.h" |
#include "ftp_var.h" |
|
|
|
|
int proxy_connect(int, char *); |
int proxy_connect(int, char *); |
int SSL_vprintf(SSL *, const char *, va_list); |
int SSL_vprintf(SSL *, const char *, va_list); |
char *SSL_readline(SSL *, size_t *); |
char *SSL_readline(SSL *, size_t *); |
#endif |
#endif /* !SMALL */ |
|
|
#define FTP_URL "ftp://" /* ftp URL prefix */ |
#define FTP_URL "ftp://" /* ftp URL prefix */ |
#define HTTP_URL "http://" /* http URL prefix */ |
#define HTTP_URL "http://" /* http URL prefix */ |
|
|
char *sslpath = NULL, *sslhost = NULL; |
char *sslpath = NULL, *sslhost = NULL; |
int ishttpsurl = 0; |
int ishttpsurl = 0; |
SSL_CTX *ssl_ctx = NULL; |
SSL_CTX *ssl_ctx = NULL; |
#endif |
#endif /* !SMALL */ |
SSL *ssl = NULL; |
SSL *ssl = NULL; |
int status; |
int status; |
|
|
|
|
} else if (strncasecmp(newline, HTTPS_URL, sizeof(HTTPS_URL) - 1) == 0) { |
} else if (strncasecmp(newline, HTTPS_URL, sizeof(HTTPS_URL) - 1) == 0) { |
host = newline + sizeof(HTTPS_URL) - 1; |
host = newline + sizeof(HTTPS_URL) - 1; |
ishttpsurl = 1; |
ishttpsurl = 1; |
#endif |
#endif /* !SMALL */ |
} else |
} else |
errx(1, "url_get: Invalid URL '%s'", newline); |
errx(1, "url_get: Invalid URL '%s'", newline); |
|
|
|
|
warnx("can't append to stdout"); |
warnx("can't append to stdout"); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
#endif |
#endif /* !SMALL */ |
|
|
if (EMPTYSTRING(savefile)) { |
if (EMPTYSTRING(savefile)) { |
if (isftpurl) |
if (isftpurl) |
|
|
if (! sslpath || ! sslhost) |
if (! sslpath || ! sslhost) |
errx(1, "Can't allocate memory for https path/host."); |
errx(1, "Can't allocate memory for https path/host."); |
} |
} |
#endif |
#endif /* !SMALL */ |
proxyurl = strdup(proxyenv); |
proxyurl = strdup(proxyenv); |
if (proxyurl == NULL) |
if (proxyurl == NULL) |
errx(1, "Can't allocate memory for proxy URL."); |
errx(1, "Can't allocate memory for proxy URL."); |
|
|
if (resume) |
if (resume) |
out = open(savefile, O_APPEND | O_WRONLY); |
out = open(savefile, O_APPEND | O_WRONLY); |
else |
else |
#endif |
#endif /* !SMALL */ |
out = open(savefile, O_CREAT | O_WRONLY | |
out = open(savefile, O_CREAT | O_WRONLY | |
O_TRUNC, 0666); |
O_TRUNC, 0666); |
if (out < 0) { |
if (out < 0) { |
|
|
} |
} |
restart_point = st.st_size; |
restart_point = st.st_size; |
} |
} |
#endif |
#endif /* !SMALL */ |
|
|
/* Trap signals */ |
/* Trap signals */ |
oldintr = NULL; |
oldintr = NULL; |
|
|
hints.ai_socktype = SOCK_STREAM; |
hints.ai_socktype = SOCK_STREAM; |
#ifndef SMALL |
#ifndef SMALL |
port = portnum ? portnum : (ishttpsurl ? httpsport : httpport); |
port = portnum ? portnum : (ishttpsurl ? httpsport : httpport); |
#else |
#else /* !SMALL */ |
port = portnum ? portnum : httpport; |
port = portnum ? portnum : httpport; |
#endif |
#endif /* !SMALL */ |
error = getaddrinfo(host, port, &hints, &res0); |
error = getaddrinfo(host, port, &hints, &res0); |
/* |
/* |
* If the services file is corrupt/missing, fall back |
* If the services file is corrupt/missing, fall back |
|
|
} else if (error == EAI_SERVICE && port == httpsport) { |
} else if (error == EAI_SERVICE && port == httpsport) { |
snprintf(pbuf, sizeof(pbuf), "%d", HTTPS_PORT); |
snprintf(pbuf, sizeof(pbuf), "%d", HTTPS_PORT); |
error = getaddrinfo(host, pbuf, &hints, &res0); |
error = getaddrinfo(host, pbuf, &hints, &res0); |
#endif |
#endif /* !SMALL */ |
} |
} |
if (error) { |
if (error) { |
warnx("%s: %s", gai_strerror(error), host); |
warnx("%s: %s", gai_strerror(error), host); |
|
|
#ifndef SMALL |
#ifndef SMALL |
if (proxyenv && sslhost) |
if (proxyenv && sslhost) |
proxy_connect(s, sslhost); |
proxy_connect(s, sslhost); |
#endif |
#endif /* !SMALL */ |
break; |
break; |
} |
} |
freeaddrinfo(res0); |
freeaddrinfo(res0); |
|
|
} else { |
} else { |
fin = fdopen(s, "r+"); |
fin = fdopen(s, "r+"); |
} |
} |
#else |
#else /* !SMALL */ |
fin = fdopen(s, "r+"); |
fin = fdopen(s, "r+"); |
#endif |
#endif /* !SMALL */ |
|
|
if (verbose) |
if (verbose) |
fprintf(ttyout, "Requesting %s", origline); |
fprintf(ttyout, "Requesting %s", origline); |
|
|
*/ |
*/ |
#ifndef SMALL |
#ifndef SMALL |
cookie_get(host, path, ishttpsurl, &buf); |
cookie_get(host, path, ishttpsurl, &buf); |
#endif |
#endif /* !SMALL */ |
if (proxyurl) { |
if (proxyurl) { |
if (verbose) |
if (verbose) |
fprintf(ttyout, " (via %s)\n", proxyenv); |
fprintf(ttyout, " (via %s)\n", proxyenv); |
|
|
ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", path, |
ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", path, |
#ifndef SMALL |
#ifndef SMALL |
resume ? "HTTP/1.1" : |
resume ? "HTTP/1.1" : |
#endif |
#endif /* !SMALL */ |
"HTTP/1.0"); |
"HTTP/1.0"); |
if (strchr(host, ':')) { |
if (strchr(host, ':')) { |
char *h, *p; |
char *h, *p; |
|
|
ftp_printf(fin, ssl, "\r\nRange: bytes=%lld-", |
ftp_printf(fin, ssl, "\r\nRange: bytes=%lld-", |
(long long)restart_point); |
(long long)restart_point); |
} |
} |
#else |
#else /* !SMALL */ |
if (port && strcmp(port, "80") != 0) |
if (port && strcmp(port, "80") != 0) |
ftp_printf(fin, ssl, ":%s", port); |
ftp_printf(fin, ssl, ":%s", port); |
#endif |
#endif /* !SMALL */ |
ftp_printf(fin, ssl, "\r\n%s%s\r\n\r\n", |
ftp_printf(fin, ssl, "\r\n%s%s\r\n\r\n", |
buf ? buf : "", HTTP_USER_AGENT); |
buf ? buf : "", HTTP_USER_AGENT); |
if (verbose) |
if (verbose) |
|
|
|
|
#ifndef SMALL |
#ifndef SMALL |
free(buf); |
free(buf); |
#endif |
#endif /* !SMALL */ |
buf = NULL; |
buf = NULL; |
|
|
if (fin != NULL && fflush(fin) == EOF) { |
if (fin != NULL && fflush(fin) == EOF) { |
|
|
#ifndef SMALL |
#ifndef SMALL |
case 206: /* Partial Content */ |
case 206: /* Partial Content */ |
break; |
break; |
#endif |
#endif /* !SMALL */ |
case 301: /* Moved Permanently */ |
case 301: /* Moved Permanently */ |
case 302: /* Found */ |
case 302: /* Found */ |
case 303: /* See Other */ |
case 303: /* See Other */ |
|
|
case 416: /* Requested Range Not Satisfiable */ |
case 416: /* Requested Range Not Satisfiable */ |
warnx("File is already fully retrieved."); |
warnx("File is already fully retrieved."); |
goto cleanup_url_get; |
goto cleanup_url_get; |
#endif |
#endif /* !SMALL */ |
default: |
default: |
warnx("Error retrieving file: %s", cp); |
warnx("Error retrieving file: %s", cp); |
goto cleanup_url_get; |
goto cleanup_url_get; |
|
|
#ifndef SMALL |
#ifndef SMALL |
if (resume) |
if (resume) |
filesize += restart_point; |
filesize += restart_point; |
#endif |
#endif /* !SMALL */ |
#define LOCATION "Location: " |
#define LOCATION "Location: " |
} else if (isredirect && |
} else if (isredirect && |
strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) { |
strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) { |
|
|
if (resume) |
if (resume) |
out = open(savefile, O_APPEND | O_WRONLY); |
out = open(savefile, O_APPEND | O_WRONLY); |
else |
else |
#endif |
#endif /* !SMALL */ |
out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, |
out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, |
0666); |
0666); |
if (out < 0) { |
if (out < 0) { |
|
|
if ( |
if ( |
#ifndef SMALL |
#ifndef SMALL |
!resume && |
!resume && |
#endif |
#endif /* !SMALL */ |
filesize != -1 && len == 0 && bytes != filesize) { |
filesize != -1 && len == 0 && bytes != filesize) { |
if (verbose) |
if (verbose) |
fputs("Read short file.\n", ttyout); |
fputs("Read short file.\n", ttyout); |
|
|
SSL_shutdown(ssl); |
SSL_shutdown(ssl); |
SSL_free(ssl); |
SSL_free(ssl); |
} |
} |
#endif |
#endif /* !SMALL */ |
if (fin != NULL) |
if (fin != NULL) |
fclose(fin); |
fclose(fin); |
else if (s != -1) |
else if (s != -1) |
|
|
#ifndef SMALL |
#ifndef SMALL |
/* even if we compiled without SSL, url_get will check */ |
/* even if we compiled without SSL, url_get will check */ |
strncasecmp(url, HTTPS_URL, sizeof(HTTPS_URL) -1) == 0 || |
strncasecmp(url, HTTPS_URL, sizeof(HTTPS_URL) -1) == 0 || |
#endif |
#endif /* !SMALL */ |
strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) { |
strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) { |
redirect_loop = 0; |
redirect_loop = 0; |
if (url_get(url, httpproxy, outfile) == -1) |
if (url_get(url, httpproxy, outfile) == -1) |
|
|
ointeractive = interactive; |
ointeractive = interactive; |
interactive = 0; |
interactive = 0; |
xargv[0] = "mget"; |
xargv[0] = "mget"; |
|
#ifndef SMALL |
|
if (resume) { |
|
xargc = 3; |
|
xargv[1] = "-c"; |
|
xargv[2] = file; |
|
xargv[3] = NULL; |
|
} |
|
#endif /* !SMALL */ |
mget(xargc, xargv); |
mget(xargc, xargv); |
interactive = ointeractive; |
interactive = ointeractive; |
} else { |
} else { |
|
|
if (resume) |
if (resume) |
reget(xargc, xargv); |
reget(xargc, xargv); |
else |
else |
#endif |
#endif /* !SMALL */ |
get(xargc, xargv); |
get(xargc, xargv); |
} |
} |
|
|
|
|
strncasecmp(p, HTTP_URL, sizeof(HTTP_URL) - 1) == 0 || |
strncasecmp(p, HTTP_URL, sizeof(HTTP_URL) - 1) == 0 || |
#ifndef SMALL |
#ifndef SMALL |
strncasecmp(p, HTTPS_URL, sizeof(HTTPS_URL) - 1) == 0 || |
strncasecmp(p, HTTPS_URL, sizeof(HTTPS_URL) - 1) == 0 || |
#endif |
#endif /* !SMALL */ |
strncasecmp(p, FILE_URL, sizeof(FILE_URL) - 1) == 0 || |
strncasecmp(p, FILE_URL, sizeof(FILE_URL) - 1) == 0 || |
strstr(p, ":/")) |
strstr(p, ":/")) |
return (1); |
return (1); |
|
|
#ifndef SMALL |
#ifndef SMALL |
else if (ssl != NULL) |
else if (ssl != NULL) |
return SSL_readline(ssl, lenp); |
return SSL_readline(ssl, lenp); |
#endif |
#endif /* !SMALL */ |
else |
else |
return NULL; |
return NULL; |
} |
} |
|
|
else |
else |
ret = nr; |
ret = nr; |
} |
} |
#endif |
#endif /* !SMALL */ |
else |
else |
ret = 0; |
ret = 0; |
return (ret); |
return (ret); |
|
|
#ifndef SMALL |
#ifndef SMALL |
else if (ssl != NULL) |
else if (ssl != NULL) |
ret = SSL_vprintf((SSL*)ssl, fmt, ap); |
ret = SSL_vprintf((SSL*)ssl, fmt, ap); |
#endif |
#endif /* !SMALL */ |
else |
else |
ret = NULL; |
ret = NULL; |
|
|
|
|
free(connstr); |
free(connstr); |
return(200); |
return(200); |
} |
} |
#endif |
#endif /* !SMALL */ |