diff options
-rw-r--r-- | usr.bin/ftp/cmds.c | 185 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 10 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 4 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 39 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 11 |
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) { |