diff options
Diffstat (limited to 'usr.bin/ftp/fetch.c')
-rw-r--r-- | usr.bin/ftp/fetch.c | 141 |
1 files changed, 124 insertions, 17 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c index 3d4c4998db2..f923f135f6d 100644 --- a/usr.bin/ftp/fetch.c +++ b/usr.bin/ftp/fetch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fetch.c,v 1.21 1998/09/11 08:04:24 marc Exp $ */ +/* $OpenBSD: fetch.c,v 1.22 1998/09/28 13:38:22 deraadt Exp $ */ /* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */ /*- @@ -38,7 +38,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: fetch.c,v 1.21 1998/09/11 08:04:24 marc Exp $"; +static char rcsid[] = "$OpenBSD: fetch.c,v 1.22 1998/09/28 13:38:22 deraadt Exp $"; #endif /* not lint */ /* @@ -48,6 +48,7 @@ static char rcsid[] = "$OpenBSD: fetch.c,v 1.21 1998/09/11 08:04:24 marc Exp $"; #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> +#include <sys/stat.h> #include <netinet/in.h> @@ -70,10 +71,12 @@ static char rcsid[] = "$OpenBSD: fetch.c,v 1.21 1998/09/11 08:04:24 marc Exp $"; static int url_get __P((const char *, const char *, const char *)); void aborthttp __P((int)); +void abortfile __P((int)); #define FTP_URL "ftp://" /* ftp URL prefix */ #define HTTP_URL "http://" /* http URL prefix */ +#define FILE_URL "file:" /* file URL prefix */ #define FTP_PROXY "ftp_proxy" /* env var with ftp proxy location */ #define HTTP_PROXY "http_proxy" /* env var with http proxy location */ @@ -94,7 +97,7 @@ url_get(origline, proxyenv, outfile) const char *outfile; { struct sockaddr_in sin; - int i, out, isftpurl; + int i, out, isftpurl, isfileurl; in_port_t port; volatile int s; size_t len; @@ -108,6 +111,7 @@ url_get(origline, proxyenv, outfile) s = -1; proxy = NULL; isftpurl = 0; + isfileurl = 0; #ifdef __GNUC__ /* XXX: to shut up gcc warnings */ (void)&out; @@ -123,22 +127,29 @@ url_get(origline, proxyenv, outfile) else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { host = line + sizeof(FTP_URL) - 1; isftpurl = 1; + } else if (strncasecmp(line, FILE_URL, sizeof(FILE_URL) - 1) == 0) { + host = line + sizeof(FILE_URL) - 1; + isfileurl = 1; } else errx(1, "url_get: Invalid URL '%s'", line); - path = strchr(host, '/'); /* find path */ - if (EMPTYSTRING(path)) { - if (isftpurl) - goto noftpautologin; - warnx("Invalid URL (no `/' after host): %s", origline); - goto cleanup_url_get; - } - *path++ = '\0'; - if (EMPTYSTRING(path)) { - if (isftpurl) - goto noftpautologin; - warnx("Invalid URL (no file after host): %s", origline); - goto cleanup_url_get; + if (isfileurl) { + path = host; + } else { + path = strchr(host, '/'); /* find path */ + if (EMPTYSTRING(path)) { + if (isftpurl) + goto noftpautologin; + warnx("Invalid URL (no `/' after host): %s", origline); + goto cleanup_url_get; + } + *path++ = '\0'; + if (EMPTYSTRING(path)) { + if (isftpurl) + goto noftpautologin; + warnx("Invalid URL (no file after host): %s", origline); + goto cleanup_url_get; + } } if (outfile) @@ -176,6 +187,87 @@ url_get(origline, proxyenv, outfile) path = line; } + if (isfileurl) { + struct stat st; + + s = open(path, O_RDONLY); + if (s == -1) { + warn("Can't open file %s", path); + goto cleanup_url_get; + } + + if (fstat(s, &st) == -1) + filesize = -1; + else + filesize = st.st_size; + + /* Open the output file. */ + if (strcmp(savefile, "-") != 0) { + out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (out < 0) { + warn("Can't open %s", savefile); + goto cleanup_url_get; + } + } else + out = fileno(stdout); + + /* Trap signals */ + oldintr = NULL; + if (setjmp(httpabort)) { + if (oldintr) + (void)signal(SIGINT, oldintr); + goto cleanup_url_get; + } + oldintr = signal(SIGINT, abortfile); + + bytes = 0; + hashbytes = mark; + progressmeter(-1); + + /* Finally, suck down the file. */ + i = 0; + while ((len = read(s, buf, sizeof(buf))) > 0) { + bytes += len; + for (cp = buf; len > 0; len -= i, cp += i) { + if ((i = write(out, cp, len)) == -1) { + warn("Writing %s", savefile); + goto cleanup_url_get; + } + else if (i == 0) + break; + } + if (hash && !progress) { + while (bytes >= hashbytes) { + (void)putc('#', ttyout); + hashbytes += mark; + } + (void)fflush(ttyout); + } + } + if (hash && !progress && bytes > 0) { + if (bytes < mark) + (void)putc('#', ttyout); + (void)putc('\n', ttyout); + (void)fflush(ttyout); + } + if (len != 0) { + warn("Reading from file"); + goto cleanup_url_get; + } + progressmeter(1); + if (verbose) + fputs("Successfully retrieved file.\n", ttyout); + (void)signal(SIGINT, oldintr); + + close(s); + if (out != fileno(stdout)) + close(out); + if (proxy) + free(proxy); + free(line); + return (0); + } + portnum = strchr(host, ':'); /* find portnum */ if (portnum != NULL) *portnum++ = '\0'; @@ -423,6 +515,20 @@ aborthttp(notused) } /* + * Abort a http retrieval + */ +void +abortfile(notused) + int notused; +{ + + alarmtimer(0); + fputs("\nfile fetch aborted.\n", ttyout); + (void)fflush(ttyout); + longjmp(httpabort, 1); +} + +/* * Retrieve multiple files from the command line, transferring * files of the form "host:path", "ftp://host/path" using the * ftp protocol, and files of the form "http://host/path" using @@ -483,7 +589,8 @@ auto_fetch(argc, argv, outfile) /* * 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 || + strncasecmp(line, FILE_URL, sizeof(FILE_URL) - 1) == 0) { if (url_get(line, httpproxy, outfile) == -1) rval = argpos + 1; continue; |