summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/ftp/cmds.c185
-rw-r--r--usr.bin/ftp/cmdtab.c10
-rw-r--r--usr.bin/ftp/extern.h4
-rw-r--r--usr.bin/ftp/ftp.139
-rw-r--r--usr.bin/ftp/ftp.c11
5 files changed, 211 insertions, 38 deletions
diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c
index 111664734c3..d04ab8ca3ca 100644
--- a/usr.bin/ftp/cmds.c
+++ b/usr.bin/ftp/cmds.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmds.c,v 1.61 2008/06/16 19:56:04 martynas Exp $ */
+/* $OpenBSD: cmds.c,v 1.62 2008/06/25 18:07:00 martynas Exp $ */
/* $NetBSD: cmds.c,v 1.27 1997/08/18 10:20:15 lukem Exp $ */
/*
@@ -60,7 +60,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: cmds.c,v 1.61 2008/06/16 19:56:04 martynas Exp $";
+static const char rcsid[] = "$OpenBSD: cmds.c,v 1.62 2008/06/25 18:07:00 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -258,11 +258,27 @@ setstruct(int argc, char *argv[])
code = -1;
}
+#ifndef SMALL
+void
+reput(int argc, char *argv[])
+{
+
+ (void)putit(argc, argv, 1);
+}
+#endif /* !SMALL */
+
+void
+put(int argc, char *argv[])
+{
+
+ (void)putit(argc, argv, 0);
+}
+
/*
* Send a single file.
*/
void
-put(int argc, char *argv[])
+putit(int argc, char *argv[], int restartit)
{
char *cmd;
int loc = 0;
@@ -294,7 +310,22 @@ usage:
if (argv[1] != oldargv1 && argv[2] == oldargv1) {
argv[2] = argv[1];
}
- cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
+#ifndef SMALL
+ if (restartit == 1) {
+ if (curtype != type)
+ changetype(type, 0);
+ restart_point = remotesize(argv[2], 1);
+ if (restart_point < 0) {
+ restart_point = 0;
+ code = -1;
+ return;
+ }
+ }
+#endif /* !SMALL */
+ if (strcmp(argv[0], "append") == 0) {
+ restartit = 1;
+ }
+ cmd = restartit ? "APPE" : ((sunique) ? "STOU" : "STOR");
if (loc && ntflag) {
argv[2] = dotrans(argv[2]);
}
@@ -303,6 +334,7 @@ usage:
}
sendrequest(cmd, argv[1], argv[2],
argv[1] != oldargv1 || argv[2] != oldargv2);
+ restart_point = 0;
if (oldargv1 != argv[1]) /* free up after globulize() */
free(argv[1]);
}
@@ -313,17 +345,42 @@ usage:
void
mput(int argc, char *argv[])
{
- int i;
+ extern int optind, optreset;
+ int ch, i, restartit = 0;
sig_t oldintr;
- char *tp;
+ char *cmd, *tp;
+
+ optind = optreset = 1;
- if (argc < 2 && !another(&argc, &argv, "local-files")) {
- fprintf(ttyout, "usage: %s local-files\n", argv[0]);
+#ifndef SMALL
+ while ((ch = getopt(argc, argv, "c")) != -1) {
+ switch(ch) {
+ case 'c':
+ restartit = 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+#endif /* !SMALL */
+
+ if (argc - optind < 1 && !another(&argc, &argv, "local-files")) {
+usage:
+ fprintf(ttyout, "usage: %s [-c] local-files\n", argv[0]);
code = -1;
return;
}
+
+#ifndef SMALL
+ optind--;
+ argv[optind] = argv[0];
+ argc -= optind;
+ argv += optind;
+#endif /* !SMALL */
+
mname = argv[0];
mflag = 1;
+
oldintr = signal(SIGINT, mabort);
(void)setjmp(jabort);
if (proxy) {
@@ -360,10 +417,24 @@ mput(int argc, char *argv[])
if (mapflag) {
tp = domap(tp);
}
- sendrequest((sunique) ? "STOU" : "STOR",
- cp, tp, cp != tp || !interactive);
+#ifndef SMALL
+ if (restartit == 1) {
+ off_t ret;
+
+ if (curtype != type)
+ changetype(type, 0);
+ ret = remotesize(tp, 0);
+ restart_point = (ret < 0) ? 0 : ret;
+ }
+#endif /* !SMALL */
+ cmd = restartit ? "APPE" : ((sunique) ?
+ "STOU" : "STOR");
+ sendrequest(cmd, cp, tp,
+ cp != tp || !interactive);
+ restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with", "mput", 1))
+ if (confirm("Continue with",
+ argv[0], 1))
mflag = 1;
}
}
@@ -381,10 +452,24 @@ mput(int argc, char *argv[])
if (mflag && confirm(argv[0], argv[i], 0)) {
tp = (ntflag) ? dotrans(argv[i]) : argv[i];
tp = (mapflag) ? domap(tp) : tp;
- sendrequest((sunique) ? "STOU" : "STOR",
- argv[i], tp, tp != argv[i] || !interactive);
+#ifndef SMALL
+ if (restartit == 1) {
+ off_t ret;
+
+ if (curtype != type)
+ changetype(type, 0);
+ ret = remotesize(tp, 0);
+ restart_point = (ret < 0) ? 0 : ret;
+ }
+#endif /* !SMALL */
+ cmd = restartit ? "APPE" : ((sunique) ?
+ "STOU" : "STOR");
+ sendrequest(cmd, argv[i], tp,
+ tp != argv[i] || !interactive);
+ restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with", "mput", 1))
+ if (confirm("Continue with",
+ argv[0], 1))
mflag = 1;
}
}
@@ -402,10 +487,24 @@ mput(int argc, char *argv[])
if (mflag && confirm(argv[0], *cpp, 0)) {
tp = (ntflag) ? dotrans(*cpp) : *cpp;
tp = (mapflag) ? domap(tp) : tp;
- sendrequest((sunique) ? "STOU" : "STOR",
- *cpp, tp, *cpp != tp || !interactive);
+#ifndef SMALL
+ if (restartit == 1) {
+ off_t ret;
+
+ if (curtype != type)
+ changetype(type, 0);
+ ret = remotesize(tp, 0);
+ restart_point = (ret < 0) ? 0 : ret;
+ }
+#endif /* !SMALL */
+ cmd = restartit ? "APPE" : ((sunique) ?
+ "STOU" : "STOR");
+ sendrequest(cmd, *cpp, tp,
+ *cpp != tp || !interactive);
+ restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with", "mput", 1))
+ if (confirm("Continue with",
+ argv[0], 1))
mflag = 1;
}
}
@@ -416,12 +515,14 @@ mput(int argc, char *argv[])
mflag = 0;
}
+#ifndef SMALL
void
reget(int argc, char *argv[])
{
(void)getit(argc, argv, 1, "r+w");
}
+#endif /* !SMALL */
void
get(int argc, char *argv[])
@@ -483,6 +584,7 @@ usage:
argv[2] = dotrans(argv[2]);
if (loc && mapflag)
argv[2] = domap(argv[2]);
+#ifndef SMALL
if (restartit) {
struct stat stbuf;
int ret;
@@ -508,6 +610,7 @@ usage:
}
}
}
+#endif /* !SMALL */
recvrequest("RETR", argv[2], argv[1], mode,
argv[1] != oldargv1 || argv[2] != oldargv2, loc);
@@ -527,7 +630,7 @@ mabort(int signo)
putc('\n', ttyout);
(void)fflush(ttyout);
if (mflag && fromatty)
- if (confirm("Continue with", mname, 0))
+ if (confirm("Continue with", mname, 1))
longjmp(jabort, 1);
mflag = 0;
longjmp(jabort, 1);
@@ -539,15 +642,39 @@ mabort(int signo)
void
mget(int argc, char *argv[])
{
+ extern int optind, optreset;
sig_t oldintr;
- int ch;
+ int ch, restartit = 0;
char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN], localcwd[MAXPATHLEN];
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- fprintf(ttyout, "usage: %s remote-files\n", argv[0]);
+ optind = optreset = 1;
+
+#ifndef SMALL
+ while ((ch = getopt(argc, argv, "c")) != -1) {
+ switch(ch) {
+ case 'c':
+ restartit = 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+#endif /* !SMALL */
+
+ if (argc - optind < 1 && !another(&argc, &argv, "remote-files")) {
+usage:
+ fprintf(ttyout, "usage: %s [-c] remote-files\n", argv[0]);
code = -1;
return;
}
+
+#ifndef SMALL
+ optind--;
+ argv[optind] = argv[0];
+ argc -= optind;
+ argv += optind;
+#endif /* !SMALL */
+
mname = argv[0];
mflag = 1;
if (getcwd(localcwd, sizeof(localcwd)) == NULL)
@@ -579,10 +706,20 @@ mget(int argc, char *argv[])
tp = dotrans(tp);
if (mapflag)
tp = domap(tp);
- recvrequest("RETR", tp, cp, "w",
+#ifndef SMALL
+ if (restartit == 1) {
+ struct stat stbuf;
+ int ret;
+
+ ret = stat(tp, &stbuf);
+ restart_point = (ret < 0) ? 0 : stbuf.st_size;
+ }
+#endif /* !SMALL */
+ recvrequest("RETR", tp, cp, restart_point ? "r+w" : "w",
tp != cp || !interactive, 1);
+ restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with", "mget", 1))
+ if (confirm("Continue with", argv[0], 1))
mflag = 1;
}
}
@@ -1024,7 +1161,7 @@ mdelete(int argc, char *argv[])
if (mflag && confirm(argv[0], cp, 0)) {
(void)command("DELE %s", cp);
if (!mflag && fromatty) {
- if (confirm("Continue with", "mdelete", 0))
+ if (confirm("Continue with", argv[0], 1))
mflag = 1;
}
}
diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c
index 7f8f8abf005..eef9f473ba8 100644
--- a/usr.bin/ftp/cmdtab.c
+++ b/usr.bin/ftp/cmdtab.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmdtab.c,v 1.20 2006/04/25 05:45:20 tedu Exp $ */
+/* $OpenBSD: cmdtab.c,v 1.21 2008/06/25 18:07:00 martynas Exp $ */
/* $NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.20 2006/04/25 05:45:20 tedu Exp $";
+static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.21 2008/06/25 18:07:00 martynas Exp $";
#endif /* not lint and not SMALL */
#include <stdio.h>
@@ -95,6 +95,7 @@ char quithelp[] = "terminate ftp session and exit";
char quotehelp[] = "send arbitrary ftp command";
char receivehelp[] = "receive file";
char regethelp[] = "get file restarting at end of local file";
+char reputhelp[] = "put file restarting at end of remote file";
char remotehelp[] = "get help from remote server";
char renamehelp[] = "rename file";
char resethelp[] = "clear queued command replies";
@@ -196,8 +197,13 @@ struct cmd cmdtab[] = {
{ "quit", H(quithelp), 0, 0, 0, CMPL0 quit },
{ "quote", H(quotehelp), 1, 1, 1, CMPL0 quote },
{ "recv", H(receivehelp), 1, 1, 1, CMPL(rl) get },
+#ifndef SMALL
{ "reget", H(regethelp), 1, 1, 1, CMPL(rl) reget },
+#endif /* !SMALL */
{ "rename", H(renamehelp), 0, 1, 1, CMPL(rr) renamefile },
+#ifndef SMALL
+ { "reput", H(reputhelp), 1, 1, 1, CMPL(lr) reput },
+#endif /* !SMALL */
{ "reset", H(resethelp), 0, 1, 1, CMPL0 reset },
{ "restart", H(restarthelp), 1, 1, 1, CMPL0 restart },
{ "rhelp", H(remotehelp), 0, 1, 1, CMPL0 rmthelp },
diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h
index fec76b821d1..d26150b805b 100644
--- a/usr.bin/ftp/extern.h
+++ b/usr.bin/ftp/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.32 2008/06/16 12:03:51 martynas Exp $ */
+/* $OpenBSD: extern.h,v 1.33 2008/06/25 18:07:00 martynas Exp $ */
/* $NetBSD: extern.h,v 1.17 1997/08/18 10:20:19 lukem Exp $ */
/*
@@ -133,6 +133,7 @@ void psummary(int);
void pswitch(int);
void ptransfer(int);
void put(int, char **);
+void putit(int, char **, int);
void pwd(int, char **);
void quit(int, char **);
void quote(int, char **);
@@ -145,6 +146,7 @@ off_t remotesize(const char *, int);
time_t remotemodtime(const char *, int);
void removedir(int, char **);
void renamefile(int, char **);
+void reput(int, char **);
void reset(int, char **);
void restart(int, char **);
void rmthelp(int, char **);
diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1
index 9340f04228a..7471497603e 100644
--- a/usr.bin/ftp/ftp.1
+++ b/usr.bin/ftp/ftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ftp.1,v 1.69 2008/06/16 19:56:04 martynas Exp $
+.\" $OpenBSD: ftp.1,v 1.70 2008/06/25 18:07:00 martynas Exp $
.\" $NetBSD: ftp.1,v 1.22 1997/08/18 10:20:22 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
-.Dd $Mdocdate: June 16 2008 $
+.Dd $Mdocdate: June 25 2008 $
.Dt FTP 1
.Os
.Sh NAME
@@ -556,13 +556,21 @@ on the remote machine.
.It Ic mdir Ar remote-files local-file
A synonym for
.Ic mls .
-.It Ic mget Ar remote-files
+.It Xo Ic mget
+.Op Fl c
+.Ar remote-files
+.Xc
Expand the
.Ar remote-files
on the remote machine
and do a
.Ic get
for each file name thus produced.
+If the
+.Fl c
+flag is specified, then
+.Ic reget
+is used instead for the partially transferred files.
See
.Ic glob
for details on the filename expansion.
@@ -605,11 +613,19 @@ Show the last modification time of the file on the remote machine.
.It Ic more Ar file
A synonym for
.Ic page .
-.It Ic mput Ar local-files
+.It Xo Ic mput
+.Op Fl c
+.Ar local-files
+.Xc
Expand wild cards in the list of local files given as arguments
and do a
.Ic put
for each file in the resulting list.
+If the
+.Fl c
+flag is specified, then
+.Ic reput
+is used instead for the partially transferred files.
See
.Ic glob
for details of filename expansion.
@@ -968,6 +984,21 @@ Rename the file
.Ar from
on the remote machine to the file
.Ar to .
+.It Ic reput Ar local-file Op Ar remote-file
+Reput acts like put, except that if
+.Ar remote-file
+exists and is
+smaller than
+.Ar local-file ,
+.Ar remote-file
+is presumed to be
+a partially transferred copy of
+.Ar local-file
+and the transfer
+is continued from the apparent point of failure.
+This command
+is useful when transferring very large files over networks that
+are prone to dropping connections.
.It Ic reset
Clear reply queue.
This command re-synchronizes command/reply sequencing with the remote
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c
index 3ad6cd3a69d..298f00a1f6c 100644
--- a/usr.bin/ftp/ftp.c
+++ b/usr.bin/ftp/ftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp.c,v 1.70 2008/05/24 00:42:35 pyr Exp $ */
+/* $OpenBSD: ftp.c,v 1.71 2008/06/25 18:07:00 martynas Exp $ */
/* $NetBSD: ftp.c,v 1.27 1997/08/18 10:20:23 lukem Exp $ */
/*
@@ -60,7 +60,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: ftp.c,v 1.70 2008/05/24 00:42:35 pyr Exp $";
+static const char rcsid[] = "$OpenBSD: ftp.c,v 1.71 2008/06/25 18:07:00 martynas Exp $";
#endif /* not lint and not SMALL */
#include <sys/types.h>
@@ -448,9 +448,9 @@ getreply(int expecteof)
return (4);
}
if (c != '\r' && (verbose > 0 ||
- ((verbose > -1 && n == '5' && dig > 4)) &&
+ ((verbose > -1 && n == '5' && dig > 4) &&
(((!n && c < '5') || (n && n < '5'))
- || !retry_connect))) {
+ || !retry_connect)))) {
if (proxflag &&
(dig == 1 || (dig == 5 && verbose == 0)))
fprintf(ttyout, "%s:", hostname);
@@ -656,7 +656,6 @@ sendrequest(const char *cmd, const char *local, const char *remote,
}
if (rc == -1) {
warn("local: %s", local);
- restart_point = 0;
progress = oprogress;
if (closefunc != NULL)
(*closefunc)(fin);
@@ -664,13 +663,11 @@ sendrequest(const char *cmd, const char *local, const char *remote,
}
if (command("REST %lld", (long long) restart_point)
!= CONTINUE) {
- restart_point = 0;
progress = oprogress;
if (closefunc != NULL)
(*closefunc)(fin);
return;
}
- restart_point = 0;
lmode = "r+w";
}
if (remote) {