summaryrefslogtreecommitdiff
path: root/usr.bin/ftp/fetch.c
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2007-11-26 12:39:01 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2007-11-26 12:39:01 +0000
commit03fc186892cc696b1dfd66f6501a24ea9d92c344 (patch)
treef8d667ae94d89d88e11e7edb17fabb23272615a1 /usr.bin/ftp/fetch.c
parent4445a4d33864c9d2da16d9fe6e7c5c03588a9f34 (diff)
implement -C for continuing ftp, http(s), and file transfers
ok millert@, pyr@
Diffstat (limited to 'usr.bin/ftp/fetch.c')
-rw-r--r--usr.bin/ftp/fetch.c90
1 files changed, 81 insertions, 9 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index efc018a386d..6acfd587d78 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fetch.c,v 1.74 2007/06/13 13:52:26 pyr Exp $ */
+/* $OpenBSD: fetch.c,v 1.75 2007/11/26 12:39:00 martynas Exp $ */
/* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
/*-
@@ -38,7 +38,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: fetch.c,v 1.74 2007/06/13 13:52:26 pyr Exp $";
+static const char rcsid[] = "$OpenBSD: fetch.c,v 1.75 2007/11/26 12:39:00 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -184,6 +184,13 @@ url_get(const char *origline, const char *proxyenv, const char *outfile)
else
savefile = basename(path);
+#ifndef SMALL
+ if (resume && (strcmp(savefile, "-") == 0)) {
+ warnx("can't append to stdout");
+ goto cleanup_url_get;
+ }
+#endif
+
if (EMPTYSTRING(savefile)) {
if (isftpurl)
goto noftpautologin;
@@ -259,8 +266,13 @@ url_get(const char *origline, const char *proxyenv, const char *outfile)
/* Open the output file. */
if (strcmp(savefile, "-") != 0) {
- out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC,
- 0666);
+#ifndef SMALL
+ if (resume)
+ out = open(savefile, O_APPEND | O_WRONLY);
+ else
+#endif
+ out = open(savefile, O_CREAT | O_WRONLY |
+ O_TRUNC, 0666);
if (out < 0) {
warn("Can't open %s", savefile);
goto cleanup_url_get;
@@ -268,6 +280,20 @@ url_get(const char *origline, const char *proxyenv, const char *outfile)
} else
out = fileno(stdout);
+#ifndef SMALL
+ if (resume) {
+ if (fstat(out, &st) == -1) {
+ warn("Can't fstat %s", savefile);
+ goto cleanup_url_get;
+ }
+ if (lseek(s, st.st_size, SEEK_SET) == -1) {
+ warn("Can't lseek %s", path);
+ goto cleanup_url_get;
+ }
+ restart_point = st.st_size;
+ }
+#endif
+
/* Trap signals */
oldintr = NULL;
if (setjmp(httpabort)) {
@@ -467,7 +493,11 @@ again:
path, buf ? buf : "", HTTP_USER_AGENT);
} else {
- ftp_printf(fin, ssl, "GET /%s HTTP/1.0\r\nHost: ", path);
+ ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", path,
+#ifndef SMALL
+ resume ? "HTTP/1.1" :
+#endif
+ "HTTP/1.0");
if (strchr(host, ':')) {
char *h, *p;
@@ -493,6 +523,21 @@ again:
#ifndef SMALL
if (port && strcmp(port, (ishttpsurl ? "443" : "80")) != 0)
ftp_printf(fin, ssl, ":%s", port);
+ if (resume) {
+ int ret;
+ struct stat stbuf;
+
+ ret = stat(savefile, &stbuf);
+ if (ret < 0) {
+ if (verbose)
+ fprintf(ttyout, "\n");
+ warn("Can't open %s", savefile);
+ goto cleanup_url_get;
+ }
+ restart_point = stbuf.st_size;
+ ftp_printf(fin, ssl, "\r\nRange: bytes=%lld-",
+ (long long)restart_point);
+ }
#else
if (port && strcmp(port, "80") != 0)
ftp_printf(fin, ssl, ":%s", port);
@@ -530,7 +575,7 @@ again:
cp++;
strlcpy(ststr, cp, sizeof(ststr));
- status = strtonum(ststr, 200, 307, &errstr);
+ status = strtonum(ststr, 200, 416, &errstr);
if (errstr) {
warnx("Error retrieving file: %s", cp);
goto cleanup_url_get;
@@ -538,7 +583,10 @@ again:
switch (status) {
case 200: /* OK */
+#ifndef SMALL
+ case 206: /* Partial Content */
break;
+#endif
case 301: /* Moved Permanently */
case 302: /* Found */
case 303: /* See Other */
@@ -549,6 +597,11 @@ again:
goto cleanup_url_get;
}
break;
+#ifndef SMALL
+ case 416: /* Requested Range Not Satisfiable */
+ warnx("File is already fully retrieved.");
+ goto cleanup_url_get;
+#endif
default:
warnx("Error retrieving file: %s", cp);
goto cleanup_url_get;
@@ -581,6 +634,10 @@ again:
filesize = strtonum(cp, 0, LLONG_MAX, &errstr);
if (errstr != NULL)
goto improper;
+#ifndef SMALL
+ if (resume)
+ filesize += restart_point;
+#endif
#define LOCATION "Location: "
} else if (isredirect &&
strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
@@ -601,7 +658,13 @@ again:
/* Open the output file. */
if (strcmp(savefile, "-") != 0) {
- out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+#ifndef SMALL
+ if (resume)
+ out = open(savefile, O_APPEND | O_WRONLY);
+ else
+#endif
+ out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC,
+ 0666);
if (out < 0) {
warn("Can't open %s", savefile);
goto cleanup_url_get;
@@ -659,7 +722,11 @@ again:
goto cleanup_url_get;
}
progressmeter(1);
- if (filesize != -1 && len == 0 && bytes != filesize) {
+ if (
+#ifndef SMALL
+ !resume &&
+#endif
+ filesize != -1 && len == 0 && bytes != filesize) {
if (verbose)
fputs("Read short file.\n", ttyout);
goto cleanup_url_get;
@@ -1002,7 +1069,12 @@ bad_ftp_url:
xargv[3] = NULL;
xargc++;
}
- get(xargc, xargv);
+#ifndef SMALL
+ if (resume)
+ reget(xargc, xargv);
+ else
+#endif
+ get(xargc, xargv);
}
if ((code / 100) != COMPLETE)