version 1.21, 1998/06/03 15:50:34 |
version 1.22, 1998/06/04 08:28:35 |
Line 56 __RCSID("$NetBSD$"); |
|
Line 56 __RCSID("$NetBSD$"); |
|
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
|
#include <errno.h> |
#include <netdb.h> |
#include <netdb.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <signal.h> |
#include <signal.h> |
Line 66 __RCSID("$NetBSD$"); |
|
Line 67 __RCSID("$NetBSD$"); |
|
|
|
#include "ftp_var.h" |
#include "ftp_var.h" |
|
|
static int url_get __P((const char *, const char *)); |
static int url_get __P((const char *, const char *, const char *)); |
void aborthttp __P((int)); |
void aborthttp __P((int)); |
|
|
|
|
Line 86 jmp_buf httpabort; |
|
Line 87 jmp_buf httpabort; |
|
* Returns -1 on failure, 0 on success |
* Returns -1 on failure, 0 on success |
*/ |
*/ |
static int |
static int |
url_get(origline, proxyenv) |
url_get(origline, proxyenv, outfile) |
const char *origline; |
const char *origline; |
const char *proxyenv; |
const char *proxyenv; |
|
const char *outfile; |
{ |
{ |
struct sockaddr_in sin; |
struct sockaddr_in sin; |
int i, out, isftpurl; |
int i, out, isftpurl; |
Line 98 url_get(origline, proxyenv) |
|
Line 100 url_get(origline, proxyenv) |
|
char c, *cp, *ep, *portnum, *path, buf[4096]; |
char c, *cp, *ep, *portnum, *path, buf[4096]; |
const char *savefile; |
const char *savefile; |
char *line, *proxy, *host; |
char *line, *proxy, *host; |
volatile sig_t oldintr; |
volatile sig_t oldintr, oldintp; |
off_t hashbytes; |
off_t hashbytes; |
|
struct hostent *hp = NULL; |
|
int (*closefunc) __P((FILE *)); |
|
FILE *fout; |
|
|
|
closefunc = NULL; |
|
fout = NULL; |
s = -1; |
s = -1; |
proxy = NULL; |
proxy = NULL; |
isftpurl = 0; |
isftpurl = 0; |
|
|
#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ |
#ifdef __GNUC__ /* to shut up gcc warnings */ |
(void)&savefile; |
(void)&closefunc; |
|
(void)&fout; |
(void)&proxy; |
(void)&proxy; |
|
(void)&savefile; |
#endif |
#endif |
|
|
line = strdup(origline); |
line = strdup(origline); |
Line 136 url_get(origline, proxyenv) |
|
Line 145 url_get(origline, proxyenv) |
|
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
|
|
savefile = strrchr(path, '/'); /* find savefile */ |
if (outfile) |
if (savefile != NULL) |
savefile = outfile; |
savefile++; |
else { |
else |
savefile = strrchr(path, '/'); /* find savefile */ |
savefile = path; |
if (savefile != NULL) |
|
savefile++; |
|
else |
|
savefile = path; |
|
} |
if (EMPTYSTRING(savefile)) { |
if (EMPTYSTRING(savefile)) { |
if (isftpurl) |
if (isftpurl) |
goto noftpautologin; |
goto noftpautologin; |
Line 176 url_get(origline, proxyenv) |
|
Line 189 url_get(origline, proxyenv) |
|
*portnum++ = '\0'; |
*portnum++ = '\0'; |
|
|
if (debug) |
if (debug) |
printf("host %s, port %s, path %s, save as %s.\n", |
fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n", |
host, portnum, path, savefile); |
host, portnum, path, savefile); |
|
|
memset(&sin, 0, sizeof(sin)); |
memset(&sin, 0, sizeof(sin)); |
Line 188 url_get(origline, proxyenv) |
|
Line 201 url_get(origline, proxyenv) |
|
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
} else { |
} else { |
struct hostent *hp; |
|
|
|
hp = gethostbyname(host); |
hp = gethostbyname(host); |
if (hp == NULL) { |
if (hp == NULL) { |
warnx("%s: %s", host, hstrerror(h_errno)); |
warnx("%s: %s", host, hstrerror(h_errno)); |
Line 222 url_get(origline, proxyenv) |
|
Line 233 url_get(origline, proxyenv) |
|
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
|
|
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { |
while (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { |
|
if (errno == EINTR) |
|
continue; |
|
if (hp && hp->h_addr_list[1]) { |
|
int oerrno = errno; |
|
char *ia; |
|
|
|
ia = inet_ntoa(sin.sin_addr); |
|
errno = oerrno; |
|
warn("connect to address %s", ia); |
|
hp->h_addr_list++; |
|
memcpy(&sin.sin_addr, hp->h_addr_list[0], |
|
(size_t)hp->h_length); |
|
fprintf(ttyout, "Trying %s...\n", |
|
inet_ntoa(sin.sin_addr)); |
|
(void)close(s); |
|
s = socket(AF_INET, SOCK_STREAM, 0); |
|
if (s < 0) { |
|
warn("socket"); |
|
goto cleanup_url_get; |
|
} |
|
continue; |
|
} |
warn("Can't connect to %s", host); |
warn("Can't connect to %s", host); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
Line 232 url_get(origline, proxyenv) |
|
Line 265 url_get(origline, proxyenv) |
|
* status of "200". Proxy requests don't want leading /. |
* status of "200". Proxy requests don't want leading /. |
*/ |
*/ |
if (!proxy) { |
if (!proxy) { |
printf("Requesting %s\n", origline); |
fprintf(ttyout, "Requesting %s\n", origline); |
len = snprintf(buf, sizeof(buf), |
len = snprintf(buf, sizeof(buf), |
"GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host); |
"GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host); |
} else { |
} else { |
printf("Requesting %s (via %s)\n", origline, proxyenv); |
fprintf(ttyout, "Requesting %s (via %s)\n", origline, proxyenv); |
len = snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", |
len = snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", |
path); |
path); |
} |
} |
Line 265 url_get(origline, proxyenv) |
|
Line 298 url_get(origline, proxyenv) |
|
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
|
|
/* |
/* Read the rest of the header. */ |
* Read the rest of the header. |
|
*/ |
|
memset(buf, 0, sizeof(buf)); |
memset(buf, 0, sizeof(buf)); |
c = '\0'; |
c = '\0'; |
for (cp = buf; cp < buf + sizeof(buf); ) { |
for (cp = buf; cp < buf + sizeof(buf); ) { |
Line 282 url_get(origline, proxyenv) |
|
Line 313 url_get(origline, proxyenv) |
|
} |
} |
buf[sizeof(buf) - 1] = '\0'; /* sanity */ |
buf[sizeof(buf) - 1] = '\0'; /* sanity */ |
|
|
/* |
/* Look for the "Content-length: " header. */ |
* Look for the "Content-length: " header. |
|
*/ |
|
#define CONTENTLEN "Content-Length: " |
#define CONTENTLEN "Content-Length: " |
for (cp = buf; *cp != '\0'; cp++) { |
for (cp = buf; *cp != '\0'; cp++) { |
if (tolower(*cp) == 'c' && |
if (tolower(*cp) == 'c' && |
Line 304 url_get(origline, proxyenv) |
|
Line 333 url_get(origline, proxyenv) |
|
} else |
} else |
filesize = -1; |
filesize = -1; |
|
|
/* Open the output file. */ |
oldintr = oldintp = NULL; |
out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666); |
|
if (out < 0) { |
/* Open the output file. */ |
warn("Can't open %s", savefile); |
if (strcmp(savefile, "-") == 0) { |
goto cleanup_url_get; |
fout = stdout; |
|
} else if (*savefile == '|') { |
|
oldintp = signal(SIGPIPE, SIG_IGN); |
|
fout = popen(savefile + 1, "w"); |
|
if (fout == NULL) { |
|
warn("Can't run %s", savefile + 1); |
|
goto cleanup_url_get; |
|
} |
|
closefunc = pclose; |
|
} else { |
|
fout = fopen(savefile, "w"); |
|
if (fout == NULL) { |
|
warn("Can't open %s", savefile); |
|
goto cleanup_url_get; |
|
} |
|
closefunc = fclose; |
} |
} |
|
|
/* Trap signals */ |
/* Trap signals */ |
oldintr = NULL; |
|
if (setjmp(httpabort)) { |
if (setjmp(httpabort)) { |
if (oldintr) |
if (oldintr) |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
|
if (oldintp) |
|
(void)signal(SIGPIPE, oldintp); |
goto cleanup_url_get; |
goto cleanup_url_get; |
} |
} |
oldintr = signal(SIGINT, aborthttp); |
oldintr = signal(SIGINT, aborthttp); |
Line 326 url_get(origline, proxyenv) |
|
Line 371 url_get(origline, proxyenv) |
|
|
|
/* Finally, suck down the file. */ |
/* Finally, suck down the file. */ |
i = 0; |
i = 0; |
|
out = fileno(fout); |
while ((len = read(s, buf, sizeof(buf))) > 0) { |
while ((len = read(s, buf, sizeof(buf))) > 0) { |
bytes += len; |
bytes += len; |
for (cp = buf; len > 0; len -= i, cp += i) { |
for (cp = buf; len > 0; len -= i, cp += i) { |
Line 338 url_get(origline, proxyenv) |
|
Line 384 url_get(origline, proxyenv) |
|
} |
} |
if (hash && !progress) { |
if (hash && !progress) { |
while (bytes >= hashbytes) { |
while (bytes >= hashbytes) { |
(void)putchar('#'); |
(void)putc('#', ttyout); |
hashbytes += mark; |
hashbytes += mark; |
} |
} |
(void)fflush(stdout); |
(void)fflush(ttyout); |
} |
} |
} |
} |
if (hash && !progress && bytes > 0) { |
if (hash && !progress && bytes > 0) { |
if (bytes < mark) |
if (bytes < mark) |
(void)putchar('#'); |
(void)putc('#', ttyout); |
(void)putchar('\n'); |
(void)putc('\n', ttyout); |
(void)fflush(stdout); |
(void)fflush(ttyout); |
} |
} |
if (len != 0) { |
if (len != 0) { |
warn("Reading from socket"); |
warn("Reading from socket"); |
Line 356 url_get(origline, proxyenv) |
|
Line 402 url_get(origline, proxyenv) |
|
} |
} |
progressmeter(1); |
progressmeter(1); |
if (verbose) |
if (verbose) |
puts("Successfully retrieved file."); |
fputs("Successfully retrieved file.\n", ttyout); |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
|
if (oldintp) |
|
(void)signal(SIGPIPE, oldintp); |
|
|
close(s); |
close(s); |
close(out); |
if (closefunc != NULL) |
|
(*closefunc)(fout); |
if (proxy) |
if (proxy) |
free(proxy); |
free(proxy); |
free(line); |
free(line); |
|
|
cleanup_url_get: |
cleanup_url_get: |
if (s != -1) |
if (s != -1) |
close(s); |
close(s); |
|
if (closefunc != NULL && fout != NULL) |
|
(*closefunc)(fout); |
if (proxy) |
if (proxy) |
free(proxy); |
free(proxy); |
free(line); |
free(line); |
Line 392 aborthttp(notused) |
|
Line 443 aborthttp(notused) |
|
{ |
{ |
|
|
alarmtimer(0); |
alarmtimer(0); |
puts("\nhttp fetch aborted."); |
fputs("\nhttp fetch aborted.\n", ttyout); |
(void)fflush(stdout); |
(void)fflush(ttyout); |
longjmp(httpabort, 1); |
longjmp(httpabort, 1); |
} |
} |
|
|
Line 412 aborthttp(notused) |
|
Line 463 aborthttp(notused) |
|
* Otherwise, 0 is returned if all files retrieved successfully. |
* Otherwise, 0 is returned if all files retrieved successfully. |
*/ |
*/ |
int |
int |
auto_fetch(argc, argv) |
auto_fetch(argc, argv, outfile) |
int argc; |
int argc; |
char *argv[]; |
char *argv[]; |
|
char *outfile; |
{ |
{ |
static char lasthost[MAXHOSTNAMELEN]; |
static char lasthost[MAXHOSTNAMELEN]; |
char *xargv[5]; |
char *xargv[5]; |
Line 426 auto_fetch(argc, argv) |
|
Line 478 auto_fetch(argc, argv) |
|
int dirhasglob, filehasglob; |
int dirhasglob, filehasglob; |
char rempath[MAXPATHLEN]; |
char rempath[MAXPATHLEN]; |
|
|
|
#ifdef __GNUC__ /* to shut up gcc warnings */ |
|
(void)&outfile; |
|
#endif |
|
|
argpos = 0; |
argpos = 0; |
|
|
if (setjmp(toplevel)) { |
if (setjmp(toplevel)) { |
Line 458 auto_fetch(argc, argv) |
|
Line 514 auto_fetch(argc, argv) |
|
* Try HTTP URL-style arguments first. |
* Try HTTP URL-style arguments first. |
*/ |
*/ |
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { |
if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { |
if (url_get(line, httpproxy) == -1) |
if (url_get(line, httpproxy, outfile) == -1) |
rval = argpos + 1; |
rval = argpos + 1; |
continue; |
continue; |
} |
} |
Line 471 auto_fetch(argc, argv) |
|
Line 527 auto_fetch(argc, argv) |
|
host = line; |
host = line; |
if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { |
if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { |
if (ftpproxy) { |
if (ftpproxy) { |
if (url_get(line, ftpproxy) == -1) |
if (url_get(line, ftpproxy, outfile) == -1) |
rval = argpos + 1; |
rval = argpos + 1; |
continue; |
continue; |
} |
} |
|
|
} |
} |
} |
} |
if (debug) |
if (debug) |
printf("user %s:%s host %s port %s dir %s file %s\n", |
fprintf(ttyout, |
|
"user %s:%s host %s port %s dir %s file %s\n", |
user, pass, host, portnum, dir, file); |
user, pass, host, portnum, dir, file); |
|
|
/* |
/* |
|
|
} |
} |
|
|
if (!verbose) |
if (!verbose) |
printf("Retrieving %s/%s\n", dir ? dir : "", file); |
fprintf(ttyout, "Retrieving %s/%s\n", dir ? dir : "", |
|
file); |
|
|
if (dirhasglob) { |
if (dirhasglob) { |
snprintf(rempath, sizeof(rempath), "%s/%s", dir, file); |
snprintf(rempath, sizeof(rempath), "%s/%s", dir, file); |
|
|
} |
} |
|
|
/* Fetch the file(s). */ |
/* Fetch the file(s). */ |
|
xargc = 2; |
xargv[0] = "get"; |
xargv[0] = "get"; |
xargv[1] = file; |
xargv[1] = file; |
xargv[2] = NULL; |
xargv[2] = NULL; |
|
|
ointeractive = interactive; |
ointeractive = interactive; |
interactive = 0; |
interactive = 0; |
xargv[0] = "mget"; |
xargv[0] = "mget"; |
mget(2, xargv); |
mget(xargc, xargv); |
interactive = ointeractive; |
interactive = ointeractive; |
} else |
} else { |
get(2, xargv); |
if (outfile != NULL) { |
|
xargv[2] = outfile; |
|
xargv[3] = NULL; |
|
xargc++; |
|
} |
|
get(xargc, xargv); |
|
if (outfile != NULL && strcmp(outfile, "-") != 0 |
|
&& outfile[0] != '|') |
|
outfile = NULL; |
|
} |
|
|
if ((code / 100) != COMPLETE) |
if ((code / 100) != COMPLETE) |
rval = argpos + 1; |
rval = argpos + 1; |