checked in for rick: add restart, size, modtime, newer, syst;
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Wed, 1 Mar 1989 06:09:33 +0000 (22:09 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Wed, 1 Mar 1989 06:09:33 +0000 (22:09 -0800)
switch to binary if both sides are unix; ls uses LIST, (new) nlist uses NLST;
add default token to .netrc as wildcard machine

SCCS-vsn: usr.bin/ftp/cmds.c 5.13
SCCS-vsn: usr.bin/ftp/cmdtab.c 5.7
SCCS-vsn: usr.bin/ftp/domacro.c 1.6
SCCS-vsn: usr.bin/ftp/ftp.1 6.11
SCCS-vsn: usr.bin/ftp/ftp.c 5.23
SCCS-vsn: usr.bin/ftp/main.c 5.12
SCCS-vsn: usr.bin/ftp/ruserpass.c 1.7

usr/src/usr.bin/ftp/cmds.c
usr/src/usr.bin/ftp/cmdtab.c
usr/src/usr.bin/ftp/domacro.c
usr/src/usr.bin/ftp/ftp.1
usr/src/usr.bin/ftp/ftp.c
usr/src/usr.bin/ftp/main.c
usr/src/usr.bin/ftp/ruserpass.c

index b7946a3..00dea2d 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmds.c     5.12 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmds.c     5.13 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -32,17 +32,22 @@ static char sccsid[] = "@(#)cmds.c  5.12 (Berkeley) %G%";
 #include <errno.h>
 #include <netdb.h>
 #include <ctype.h>
 #include <errno.h>
 #include <netdb.h>
 #include <ctype.h>
+#include <time.h>
 #include <sys/wait.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/param.h>
 
 
 extern char *globerr;
 extern char **glob();
 extern char *home;
 
 
 extern char *globerr;
 extern char **glob();
 extern char *home;
-extern short gflag;
 extern char *remglob();
 extern char *getenv();
 extern char *index();
 extern char *rindex();
 extern char *remglob();
 extern char *getenv();
 extern char *index();
 extern char *rindex();
+extern off_t restart_point;
+extern char reply_string[];
+
 char *mname;
 jmp_buf jabort;
 char *dotrans(), *domap();
 char *mname;
 jmp_buf jabort;
 char *dotrans(), *domap();
@@ -91,8 +96,44 @@ setpeer(argc, argv)
        host = hookup(argv[1], port);
        if (host) {
                connected = 1;
        host = hookup(argv[1], port);
        if (host) {
                connected = 1;
-               if (autologin)
+               if (autologin) {
+                       int overbose;
                        (void) login(argv[1]);
                        (void) login(argv[1]);
+#if defined(unix) && NBBY == 8
+/*
+ * this ifdef is to keep someone form "porting" this to an incompatible
+ * system and not checking this out. This way they have to think about it.
+ */
+                       overbose = verbose, verbose = -1;
+                       if (command("SYST") == COMPLETE && overbose) {
+                               register char *cp, c;
+                               cp = index(reply_string+4, ' ');
+                               if (cp == NULL)
+                                       cp = index(reply_string+4, '\r');
+                               if (cp) {
+                                       if (cp[-1] == '.')
+                                               cp--;
+                                       c = *cp;
+                                       *cp = '\0';
+                               }
+
+                               printf("Remote system type is %s.\n",
+                                       reply_string+4);
+                               if (cp)
+                                       *cp = c;
+                       }
+                       if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
+                               setbinary();
+                               if (overbose)
+                                       printf("Using %s mode to transfer files.\n",
+                                               typename);
+                       } else if (overbose && 
+                           !strncmp(reply_string, "215 TOPS20", 10)) {
+                               printf("Remember to set tenex mode when transfering binary files from this machine.\n");
+                       }
+                       verbose = overbose;
+#endif /* unix */
+               }
        }
 }
 
        }
 }
 
@@ -424,11 +465,24 @@ mput(argc, argv)
        mflag = 0;
 }
 
        mflag = 0;
 }
 
+reget(argc, argv)
+       char *argv[];
+{
+       (void) getit(argc, argv, 1, "r+w");
+}
+
+get(argc, argv)
+       char *argv[];
+{
+       (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
+}
+
 /*
  * Receive one file.
  */
 /*
  * Receive one file.
  */
-get(argc, argv)
+getit(argc, argv, restartit, mode)
        char *argv[];
        char *argv[];
+       char *mode;
 {
        int loc = 0;
 
 {
        int loc = 0;
 
@@ -449,7 +503,7 @@ get(argc, argv)
 usage:
                printf("usage: %s remote-file [ local-file ]\n", argv[0]);
                code = -1;
 usage:
                printf("usage: %s remote-file [ local-file ]\n", argv[0]);
                code = -1;
-               return;
+               return 0;
        }
        if (argc < 3) {
                (void) strcat(line, " ");
        }
        if (argc < 3) {
                (void) strcat(line, " ");
@@ -463,7 +517,7 @@ usage:
                goto usage;
        if (!globulize(&argv[2])) {
                code = -1;
                goto usage;
        if (!globulize(&argv[2])) {
                code = -1;
-               return;
+               return 0;
        }
        if (loc && mcase) {
                char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
        }
        if (loc && mcase) {
                char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
@@ -490,7 +544,59 @@ usage:
        if (loc && mapflag) {
                argv[2] = domap(argv[2]);
        }
        if (loc && mapflag) {
                argv[2] = domap(argv[2]);
        }
-       recvrequest("RETR", argv[2], argv[1], "w");
+       if (restartit) {
+               struct stat stbuf;
+               int ret;
+               ret = stat(argv[2], &stbuf);
+               if (restartit == 1) {
+                       if (ret < 0) {
+                               perror(argv[2]);
+                               return 0;
+                       }
+                       restart_point = stbuf.st_size;
+               } else {
+                       if (ret == 0) {
+                               int overbose;
+                               overbose = verbose; verbose = -1;
+                               if (command("MDTM %s", argv[1]) == COMPLETE) {
+                                       int yy, mo, day, hour, min, sec;
+                                       struct tm *tm;
+                                       verbose = overbose;
+                                       sscanf(reply_string,
+                                           "%*s %04d%02d%02d%02d%02d%02d",
+                                           &yy, &mo, &day, &hour, &min, &sec);
+                                       tm = gmtime(&stbuf.st_mtime);
+                                       tm->tm_mon++;
+                                       if (tm->tm_year > yy%100)
+                                               return 1;
+                                       else if (tm->tm_year == yy%100) {
+                                               if (tm->tm_mon > mo)
+                                                       return 1;
+                                       } else if (tm->tm_mon == mo) {
+                                               if (tm->tm_mday > day)
+                                                       return 1;
+                                       } else if (tm->tm_mday == day) {
+                                               if (tm->tm_hour > hour)
+                                                       return 1;
+                                       } else if (tm->tm_hour == hour) {
+                                               if (tm->tm_min > min)
+                                                       return 1;
+                                       } else if (tm->tm_min == min) {
+                                               if (tm->tm_sec > sec)
+                                                       return 1;
+                                       }
+                               } else {
+                                       fputs(reply_string, stdout);
+                                       verbose = overbose;
+                                       return 0;
+                               }
+                       }
+               }
+       }
+
+       recvrequest("RETR", argv[2], argv[1], mode);
+       restart_point = 0;
+       return 0;
 }
 
 mabort()
 }
 
 mabort()
@@ -1002,7 +1108,7 @@ ls(argc, argv)
                code = -1;
                return;
        }
                code = -1;
                return;
        }
-       cmd = argv[0][0] == 'l' ? "NLST" : "LIST";
+       cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
        if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
                code = -1;
                return;
        if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
                code = -1;
                return;
@@ -1054,7 +1160,7 @@ mls(argc, argv)
                        code = -1;
                        return;
        }
                        code = -1;
                        return;
        }
-       cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
+       cmd = argv[0][1] == 'n' ? "NLST" : "LIST";
        mname = argv[0];
        mflag = 1;
        oldintr = signal(SIGINT, mabort);
        mname = argv[0];
        mflag = 1;
        oldintr = signal(SIGINT, mabort);
@@ -1618,7 +1724,7 @@ domap(name)
                                        cp2++;
                                        break;
                                }
                                        cp2++;
                                        break;
                                }
-                               /* intentional drop through */
+                               /* FALLTHROUGH */
                        default:
                                if (*cp2 != *cp1) {
                                        match = 0;
                        default:
                                if (*cp2 != *cp1) {
                                        match = 0;
@@ -1777,6 +1883,27 @@ cdup()
        (void) command("CDUP");
 }
 
        (void) command("CDUP");
 }
 
+/* restart transfer at specific point */
+restart(argc, argv)
+       int argc;
+       char *argv[];
+{
+       extern long atol();
+       if (argc != 2)
+               printf("restart: offset not specified\n");
+       else {
+               restart_point = atol(argv[1]);
+               printf("restarting at %ld. execute get, put or append to initiate transfer\n",
+                       restart_point);
+       }
+}
+
+/* show remote system type */
+syst()
+{
+       (void) command("SYST");
+}
+
 macdef(argc, argv)
        int argc;
        char *argv[];
 macdef(argc, argv)
        int argc;
        char *argv[];
@@ -1835,7 +1962,8 @@ macdef(argc, argv)
                tmp++;
        }
        while (1) {
                tmp++;
        }
        while (1) {
-               while ((c = getchar()) != '\n' && c != EOF);
+               while ((c = getchar()) != '\n' && c != EOF)
+                       /* LOOP */;
                if (c == EOF || getchar() == '\n') {
                        printf("Macro not defined - 4k buffer exceeded\n");
                        code = -1;
                if (c == EOF || getchar() == '\n') {
                        printf("Macro not defined - 4k buffer exceeded\n");
                        code = -1;
@@ -1843,3 +1971,80 @@ macdef(argc, argv)
                }
        }
 }
                }
        }
 }
+
+/*
+ * get size of file on remote machine
+ */
+sizecmd(argc, argv)
+       char *argv[];
+{
+
+       if (argc < 2) {
+               (void) strcat(line, " ");
+               printf("(filename) ");
+               (void) gets(&line[strlen(line)]);
+               makeargv();
+               argc = margc;
+               argv = margv;
+       }
+       if (argc < 2) {
+               printf("usage:%s filename\n", argv[0]);
+               code = -1;
+               return;
+       }
+       (void) command("SIZE %s", argv[1]);
+}
+
+/*
+ * get last modification time of file on remote machine
+ */
+modtime(argc, argv)
+       char *argv[];
+{
+       int overbose;
+
+       if (argc < 2) {
+               (void) strcat(line, " ");
+               printf("(filename) ");
+               (void) gets(&line[strlen(line)]);
+               makeargv();
+               argc = margc;
+               argv = margv;
+       }
+       if (argc < 2) {
+               printf("usage:%s filename\n", argv[0]);
+               code = -1;
+               return;
+       }
+       overbose = verbose; verbose = -1;
+       if (command("MDTM %s", argv[1]) == COMPLETE) {
+               int yy, mo, day, hour, min, sec;
+               sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
+                       &day, &hour, &min, &sec);
+               /* might want to print this in local time */
+               printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
+                       mo, day, yy, hour, min, sec);
+       } else
+               fputs(reply_string, stdout);
+       verbose = overbose;
+}
+
+/*
+ * show status on reomte machine
+ */
+rmtstatus(argc, argv)
+       char *argv[];
+{
+       (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
+}
+
+/*
+ * get file if modtime is more recent than current file
+ */
+newer(argc, argv)
+       char *argv[];
+{
+       if (getit(argc, argv, -1, "w"))
+               printf("Local file \"%s\" is newer than remote file \"%s\"\n",
+                       argv[1], argv[2]);
+}
index df1c399..2d2ad3f 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmdtab.c   5.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmdtab.c   5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ftp_var.h"
 #endif /* not lint */
 
 #include "ftp_var.h"
@@ -28,7 +28,7 @@ int   setascii(), setbell(), setbinary(), setdebug(), setform();
 int    setglob(), sethash(), setmode(), setpeer(), setport();
 int    setprompt(), setstruct();
 int    settenex(), settrace(), settype(), setverbose();
 int    setglob(), sethash(), setmode(), setpeer(), setport();
 int    setprompt(), setstruct();
 int    settenex(), settrace(), settype(), setverbose();
-int    disconnect();
+int    disconnect(), restart(), reget(), syst();
 int    cd(), lcd(), delete(), mdelete(), user();
 int    ls(), mls(), get(), mget(), help(), append(), put(), mput();
 int    quit(), renamefile(), status();
 int    cd(), lcd(), delete(), mdelete(), user();
 int    ls(), mls(), get(), mget(), help(), append(), put(), mput();
 int    quit(), renamefile(), status();
@@ -36,6 +36,7 @@ int   quote(), rmthelp(), shell();
 int    pwd(), makedir(), removedir(), setcr();
 int    account(), doproxy(), reset(), setcase(), setntrans(), setnmap();
 int    setsunique(), setrunique(), cdup(), macdef(), domacro();
 int    pwd(), makedir(), removedir(), setcr();
 int    account(), doproxy(), reset(), setcase(), setntrans(), setnmap();
 int    setsunique(), setrunique(), cdup(), macdef(), domacro();
+int    sizecmd(), modtime(), newer(), rmtstatus();
 
 char   accounthelp[] = "send account command to remote server";
 char   appendhelp[] =  "append to a file";
 
 char   accounthelp[] = "send account command to remote server";
 char   appendhelp[] =  "append to a file";
@@ -57,15 +58,18 @@ char        globhelp[] =    "toggle metacharacter expansion of local file names";
 char   hashhelp[] =    "toggle printing `#' for each buffer transferred";
 char   helphelp[] =    "print local help information";
 char   lcdhelp[] =     "change local working directory";
 char   hashhelp[] =    "toggle printing `#' for each buffer transferred";
 char   helphelp[] =    "print local help information";
 char   lcdhelp[] =     "change local working directory";
-char   lshelp[] =      "nlist contents of remote directory";
+char   lshelp[] =      "list contents of remote directory";
 char   macdefhelp[] =  "define a macro";
 char   mdeletehelp[] = "delete multiple files";
 char   mdirhelp[] =    "list contents of multiple remote directories";
 char   mgethelp[] =    "get multiple files";
 char   mkdirhelp[] =   "make directory on the remote machine";
 char   macdefhelp[] =  "define a macro";
 char   mdeletehelp[] = "delete multiple files";
 char   mdirhelp[] =    "list contents of multiple remote directories";
 char   mgethelp[] =    "get multiple files";
 char   mkdirhelp[] =   "make directory on the remote machine";
-char   mlshelp[] =     "nlist contents of multiple remote directories";
+char   mlshelp[] =     "list contents of multiple remote directories";
+char   modtimehelp[] = "show last modification time of remote file";
 char   modehelp[] =    "set file transfer mode";
 char   mputhelp[] =    "send multiple files";
 char   modehelp[] =    "set file transfer mode";
 char   mputhelp[] =    "send multiple files";
+char   newerhelp[] =   "get file if remote file is newer than local file ";
+char   nlisthelp[] =   "nlist contents of remote directory";
 char   nmaphelp[] =    "set templates for default file name mapping";
 char   ntranshelp[] =  "set translation table for default file name mapping";
 char   porthelp[] =    "toggle use of PORT cmd for each data connection";
 char   nmaphelp[] =    "set templates for default file name mapping";
 char   ntranshelp[] =  "set translation table for default file name mapping";
 char   porthelp[] =    "toggle use of PORT cmd for each data connection";
@@ -75,16 +79,21 @@ char        pwdhelp[] =     "print working directory on remote machine";
 char   quithelp[] =    "terminate ftp session and exit";
 char   quotehelp[] =   "send arbitrary ftp command";
 char   receivehelp[] = "receive file";
 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   remotehelp[] =  "get help from remote server";
 char   renamehelp[] =  "rename file";
 char   remotehelp[] =  "get help from remote server";
 char   renamehelp[] =  "rename file";
+char   restarthelp[]=  "restart file transfer at bytecount";
 char   rmdirhelp[] =   "remove directory on the remote machine";
 char   rmdirhelp[] =   "remove directory on the remote machine";
+char   rmtstatushelp[]="show status of remote machine";
 char   runiquehelp[] = "toggle store unique for local files";
 char   resethelp[] =   "clear queued command replies";
 char   sendhelp[] =    "send one file";
 char   shellhelp[] =   "escape to the shell";
 char   runiquehelp[] = "toggle store unique for local files";
 char   resethelp[] =   "clear queued command replies";
 char   sendhelp[] =    "send one file";
 char   shellhelp[] =   "escape to the shell";
+char   sizecmdhelp[] = "show size of remote file";
 char   statushelp[] =  "show current status";
 char   structhelp[] =  "set file transfer structure";
 char   suniquehelp[] = "toggle store unique on remote machine";
 char   statushelp[] =  "show current status";
 char   structhelp[] =  "set file transfer structure";
 char   suniquehelp[] = "toggle store unique on remote machine";
+char   systemhelp[] =  "show remote system type";
 char   tenexhelp[] =   "set tenex file transfer type";
 char   tracehelp[] =   "toggle packet tracing";
 char   typehelp[] =    "set file transfer type";
 char   tenexhelp[] =   "set tenex file transfer type";
 char   tracehelp[] =   "toggle packet tracing";
 char   typehelp[] =    "set file transfer type";
@@ -124,8 +133,11 @@ struct cmd cmdtab[] = {
        { "mkdir",      mkdirhelp,      0,      1,      1,      makedir },
        { "mls",        mlshelp,        1,      1,      1,      mls },
        { "mode",       modehelp,       0,      1,      1,      setmode },
        { "mkdir",      mkdirhelp,      0,      1,      1,      makedir },
        { "mls",        mlshelp,        1,      1,      1,      mls },
        { "mode",       modehelp,       0,      1,      1,      setmode },
+       { "modtime",    modtimehelp,    0,      1,      1,      modtime },
        { "mput",       mputhelp,       1,      1,      1,      mput },
        { "mput",       mputhelp,       1,      1,      1,      mput },
+       { "newer",      newerhelp,      1,      1,      1,      newer },
        { "nmap",       nmaphelp,       0,      0,      1,      setnmap },
        { "nmap",       nmaphelp,       0,      0,      1,      setnmap },
+       { "nlist",      nlisthelp,      1,      1,      1,      ls },
        { "ntrans",     ntranshelp,     0,      0,      1,      setntrans },
        { "open",       connecthelp,    0,      0,      1,      setpeer },
        { "prompt",     prompthelp,     0,      0,      0,      setprompt },
        { "ntrans",     ntranshelp,     0,      0,      1,      setntrans },
        { "open",       connecthelp,    0,      0,      1,      setpeer },
        { "prompt",     prompthelp,     0,      0,      0,      setprompt },
@@ -136,14 +148,19 @@ struct cmd cmdtab[] = {
        { "quit",       quithelp,       0,      0,      0,      quit },
        { "quote",      quotehelp,      1,      1,      1,      quote },
        { "recv",       receivehelp,    1,      1,      1,      get },
        { "quit",       quithelp,       0,      0,      0,      quit },
        { "quote",      quotehelp,      1,      1,      1,      quote },
        { "recv",       receivehelp,    1,      1,      1,      get },
+       { "reget",      regethelp,      1,      1,      1,      reget },
+       { "remotestatus",rmtstatushelp, 0,      1,      1,      rmtstatus },
        { "remotehelp", remotehelp,     0,      1,      1,      rmthelp },
        { "rename",     renamehelp,     0,      1,      1,      renamefile },
        { "reset",      resethelp,      0,      1,      1,      reset },
        { "remotehelp", remotehelp,     0,      1,      1,      rmthelp },
        { "rename",     renamehelp,     0,      1,      1,      renamefile },
        { "reset",      resethelp,      0,      1,      1,      reset },
+       { "restart",    restarthelp,    1,      1,      1,      restart },
        { "rmdir",      rmdirhelp,      0,      1,      1,      removedir },
        { "runique",    runiquehelp,    0,      0,      1,      setrunique },
        { "send",       sendhelp,       1,      1,      1,      put },
        { "rmdir",      rmdirhelp,      0,      1,      1,      removedir },
        { "runique",    runiquehelp,    0,      0,      1,      setrunique },
        { "send",       sendhelp,       1,      1,      1,      put },
+       { "size",       sizecmdhelp,    1,      1,      1,      sizecmd },
        { "status",     statushelp,     0,      0,      1,      status },
        { "struct",     structhelp,     0,      1,      1,      setstruct },
        { "status",     statushelp,     0,      0,      1,      status },
        { "struct",     structhelp,     0,      1,      1,      setstruct },
+       { "system",     systemhelp,     0,      1,      1,      syst },
        { "sunique",    suniquehelp,    0,      0,      1,      setsunique },
        { "tenex",      tenexhelp,      0,      1,      1,      settenex },
        { "trace",      tracehelp,      0,      0,      0,      settrace },
        { "sunique",    suniquehelp,    0,      0,      1,      setsunique },
        { "tenex",      tenexhelp,      0,      1,      1,      settenex },
        { "trace",      tracehelp,      0,      0,      0,      settrace },
index 4cebf59..8d1ac88 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)domacro.c  1.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)domacro.c  1.6 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ftp_var.h"
 #endif /* not lint */
 
 #include "ftp_var.h"
@@ -127,7 +127,7 @@ TOP:
                        }
                        (*c->c_handler)(margc, margv);
                        if (bell && c->c_bell) {
                        }
                        (*c->c_handler)(margc, margv);
                        if (bell && c->c_bell) {
-                               (void) putchar(CTRL('g'));
+                               (void) putchar('\007');
                        }
                        (void) strcpy(line, line2);
                        makeargv();
                        }
                        (void) strcpy(line, line2);
                        makeargv();
index c0071eb..290e8e3 100644 (file)
 .\" from this software without specific prior written permission.
 .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 .\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 .\" from this software without specific prior written permission.
 .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 .\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
 .\"
-.\"    @(#)ftp.1       6.10 (Berkeley) %G%
+.\"    @(#)ftp.1       6.11 (Berkeley) %G%
 .\"
 .\"
-.TH FTP 1 ""
+.TH FTP 1 "February 23, 1989"
 .UC 5
 .SH NAME
 ftp \- ARPANET file transfer program
 .UC 5
 .SH NAME
 ftp \- ARPANET file transfer program
@@ -243,7 +243,7 @@ no
 is specified, the user's home directory is used.
 .TP
 \fBls\fP [ \fIremote-directory\fP ] [ \fIlocal-file\fP ]
 is specified, the user's home directory is used.
 .TP
 \fBls\fP [ \fIremote-directory\fP ] [ \fIlocal-file\fP ]
-Print an abbreviated listing of the contents of a
+Print a listing of the contents of a
 directory on the remote machine.  If
 .I remote-directory
 is left unspecified, the current working directory is used.
 directory on the remote machine.  If
 .I remote-directory
 is left unspecified, the current working directory is used.
@@ -322,6 +322,9 @@ to
 .IR mode-name .
 The default mode is \*(lqstream\*(rq mode.
 .TP
 .IR mode-name .
 The default mode is \*(lqstream\*(rq mode.
 .TP
+\fBmodtime\fP \fIfile-name\fP
+Show the last modification time of the file on the remote machine.
+.TP
 \fBmput\fP \fIlocal-files\fP
 Expand wild cards in the list of local files given as arguments
 and do a \fBput\fR for each file in the resulting list.
 \fBmput\fP \fIlocal-files\fP
 Expand wild cards in the list of local files given as arguments
 and do a \fBput\fR for each file in the resulting list.
@@ -332,6 +335,26 @@ and
 .I nmap
 settings.
 .TP
 .I nmap
 settings.
 .TP
+\fBnewer\fP \fIfile-name\fP
+Get the file only if the modification time of the remote file is more
+recent that the file on the current system. If the file does not
+exist on the current syste, the remote file is considered \fInewer\fP.
+Otherwise, this command is identical to \fBget\fP.
+.TP
+\fBnlist\fP [ \fIremote-directory\fP ] [ \fIlocal-file\fP ]
+Print an abbreviated listing of the contents of a
+directory on the remote machine.  If
+.I remote-directory
+is left unspecified, the current working directory is used.
+If interactive prompting is on,
+.I ftp
+will prompt the user to verify that the last argument is indeed the
+target local file for receiving
+.B nlist
+output.
+If no local file is specified, or if \fIlocal-file\fR is \fB-\fR,
+the output is sent to the terminal.
+.TP
 \fBnmap\fP [ \fIinpattern\fP \fIoutpattern\fP ]
 Set or unset the filename mapping mechanism.
 If no arguments are specified, the filename mapping mechanism is unset.
 \fBnmap\fP [ \fIinpattern\fP \fIoutpattern\fP ]
 Set or unset the filename mapping mechanism.
 If no arguments are specified, the filename mapping mechanism is unset.
@@ -365,7 +388,7 @@ All other characters are treated literally, and are used to determine the
 .B nmap
 .I inpattern
 variable values.
 .B nmap
 .I inpattern
 variable values.
-For exmaple, given
+For example, given
 .I inpattern
 $1.$2 and the remote file name "mydata.data", $1 would have the value
 "mydata", and $2 would have the value "data".
 .I inpattern
 $1.$2 and the remote file name "mydata.data", $1 would have the value
 "mydata", and $2 would have the value "data".
@@ -505,11 +528,23 @@ server.
 \fBrecv\fP \fIremote-file\fP [ \fIlocal-file\fP ]
 A synonym for get.
 .TP
 \fBrecv\fP \fIremote-file\fP [ \fIlocal-file\fP ]
 A synonym for get.
 .TP
+\fBreget\fP \fIremote-file\fP [ \fIlocal-file\fP ]
+Reget acts like get, except that if \fIlocal-file\fP exists and is
+smaller than \fIremote-file\fP, \fIlocal-file\fP is presumed to be
+a partially transferred copy of \fIremote-file\fP 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.
+.TP
 \fBremotehelp\fP [ \fIcommand-name\fP ]
 Request help from the remote FTP server.  If a 
 .I command-name
 is specified it is supplied to the server as well.
 .TP
 \fBremotehelp\fP [ \fIcommand-name\fP ]
 Request help from the remote FTP server.  If a 
 .I command-name
 is specified it is supplied to the server as well.
 .TP
+\fBremotestatus\fP [ \fIfile-name\fP ]
+With no arguments, show status of remote machine. If \fIfile-name\fP
+is specified, show status of \fIfile-name\fP on remote machine.
+.TP
 \fBrename\fP [ \fIfrom\fP ] [ \fIto\fP ]
 Rename the file
 .I from
 \fBrename\fP [ \fIfrom\fP ] [ \fIto\fP ]
 Rename the file
 .I from
@@ -520,9 +555,14 @@ on the remote machine, to the file
 Clear reply queue.
 This command re-synchronizes command/reply sequencing with the remote
 ftp server.
 Clear reply queue.
 This command re-synchronizes command/reply sequencing with the remote
 ftp server.
-Resynchronization may be neccesary following a violation of the ftp protocol
+Resynchronization may be necessary following a violation of the ftp protocol
 by the remote server.
 .TP
 by the remote server.
 .TP
+.BI restart " marker"
+Restart the immediately following \fBget\fP or \fBput\fP at the
+indicated \fImarker\fP. On UNIX systems, marker is usually a byte
+offset into the file.
+.TP
 .BI rmdir " directory-name"
 Delete a directory on the remote machine.
 .TP
 .BI rmdir " directory-name"
 Delete a directory on the remote machine.
 .TP
@@ -563,6 +603,9 @@ PORT commands for each data transfer.  This is useful
 for certain FTP implementations which do ignore PORT
 commands but, incorrectly, indicate they've been accepted.
 .TP
 for certain FTP implementations which do ignore PORT
 commands but, incorrectly, indicate they've been accepted.
 .TP
+.BI size " file-name"
+Return size of \fIfile-name\fP on remote machine.
+.TP
 .B status
 Show the current status of
 .IR ftp .
 .B status
 Show the current status of
 .IR ftp .
@@ -581,6 +624,9 @@ successful completion.
 The remote server will report unique name.
 Default value is off.
 .TP
 The remote server will report unique name.
 Default value is off.
 .TP
+.B system
+Show the type of operating system running on the remote machine.
+.TP
 .B tenex
 Set the file transfer type to that needed to
 talk to TENEX machines.
 .B tenex
 Set the file transfer type to that needed to
 talk to TENEX machines.
@@ -792,6 +838,15 @@ stopping when the end of file is reached or another
 .B machine
 token is encountered.
 .TP
 .B machine
 token is encountered.
 .TP
+\fBdefault\fP \fIname\fP
+This is the same as \fBmachine\fP except that \fBdefault\fP always
+matches the machine \fIname\fP. This is normally used as:
+.ce
+default login anonymous password user@site
+thereby giving the user \fIautomatic\fP anonymous ftp login to
+machines not specified in \fB.netrc\fP. This can be overridden
+by using the \fB\-n\fP flag to disable auto-login.
+.TP
 \fBlogin\fP \fIname\fP
 Identify a user on the remote machine.
 If this token is present, the auto-login process will initiate
 \fBlogin\fP \fIname\fP
 Identify a user on the remote machine.
 If this token is present, the auto-login process will initiate
index d50edea..caf501c 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftp.c      5.22 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftp.c      5.23 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ftp_var.h"
 #endif /* not lint */
 
 #include "ftp_var.h"
@@ -26,6 +26,7 @@ static char sccsid[] = "@(#)ftp.c     5.22 (Berkeley) %G%";
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/param.h>
+#include <sys/file.h>
 
 #include <netinet/in.h>
 #include <arpa/ftp.h>
 
 #include <netinet/in.h>
 #include <arpa/ftp.h>
@@ -46,6 +47,7 @@ int   ptflag = 0;
 int    connected;
 struct sockaddr_in myctladdr;
 uid_t  getuid();
 int    connected;
 struct sockaddr_in myctladdr;
 uid_t  getuid();
+off_t  restart_point = 0;
 
 FILE   *cin, *cout;
 FILE   *dataconn();
 
 FILE   *cin, *cout;
 FILE   *dataconn();
@@ -257,6 +259,8 @@ command(fmt, args)
        return(r);
 }
 
        return(r);
 }
 
+char reply_string[BUFSIZ];
+
 #include <ctype.h>
 
 getreply(expecteof)
 #include <ctype.h>
 
 getreply(expecteof)
@@ -264,10 +268,12 @@ getreply(expecteof)
 {
        register int c, n;
        register int dig;
 {
        register int c, n;
        register int dig;
+       register char *cp;
        int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
        int pflag = 0;
        char *pt = pasv;
 
        int originalcode = 0, continuation = 0, (*oldintr)(), cmdabort();
        int pflag = 0;
        char *pt = pasv;
 
+       cp = reply_string;
        oldintr = signal(SIGINT,cmdabort);
        for (;;) {
                dig = n = code = 0;
        oldintr = signal(SIGINT,cmdabort);
        for (;;) {
                dig = n = code = 0;
@@ -334,6 +340,7 @@ getreply(expecteof)
                        }
                        if (n == 0)
                                n = c;
                        }
                        if (n == 0)
                                n = c;
+                       *cp++ = c;
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
                        (void) putchar(c);
                }
                if (verbose > 0 || verbose > -1 && n == '5') {
                        (void) putchar(c);
@@ -344,6 +351,7 @@ getreply(expecteof)
                                originalcode = code;
                        continue;
                }
                                originalcode = code;
                        continue;
                }
+               *cp = '\0';
                if (n != '1')
                        cpend = 0;
                (void) signal(SIGINT,oldintr);
                if (n != '1')
                        cpend = 0;
                (void) signal(SIGINT,oldintr);
@@ -389,6 +397,7 @@ sendrequest(cmd, local, remote)
        register int c, d;
        struct stat st;
        struct timeval start, stop;
        register int c, d;
        struct stat st;
        struct timeval start, stop;
+       char *mode;
 
        if (proxy) {
                proxtrans(cmd, local, remote);
 
        if (proxy) {
                proxtrans(cmd, local, remote);
@@ -397,6 +406,7 @@ sendrequest(cmd, local, remote)
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
+       mode = "w";
        if (setjmp(sendabort)) {
                while (cpend) {
                        (void) getreply(0);
        if (setjmp(sendabort)) {
                while (cpend) {
                        (void) getreply(0);
@@ -439,6 +449,7 @@ sendrequest(cmd, local, remote)
                    (st.st_mode&S_IFMT) != S_IFREG) {
                        fprintf(stdout, "%s: not a plain file.\n", local);
                        (void) signal(SIGINT, oldintr);
                    (st.st_mode&S_IFMT) != S_IFREG) {
                        fprintf(stdout, "%s: not a plain file.\n", local);
                        (void) signal(SIGINT, oldintr);
+                       fclose(fin);
                        code = -1;
                        return;
                }
                        code = -1;
                        return;
                }
@@ -448,15 +459,40 @@ sendrequest(cmd, local, remote)
                if (oldintp)
                        (void) signal(SIGPIPE, oldintp);
                code = -1;
                if (oldintp)
                        (void) signal(SIGPIPE, oldintp);
                code = -1;
+               if (closefunc != NULL)
+                       (*closefunc)(fin);
                return;
        }
        if (setjmp(sendabort))
                goto abort;
                return;
        }
        if (setjmp(sendabort))
                goto abort;
+
+       if (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0) {
+               if (restart_point) {
+                       if (fseek(fin, (long) restart_point, 0) < 0) {
+                               perror(local);
+                               restart_point = 0;
+                               if (closefunc != NULL)
+                                       (*closefunc)(fin);
+                               return;
+                       }
+                       if (command("REST %ld", (long) restart_point)
+                               != CONTINUE) {
+                               restart_point = 0;
+                               if (closefunc != NULL)
+                                       (*closefunc)(fin);
+                               return;
+                       }
+                       restart_point = 0;
+                       mode = "r+w";
+               }
+       }
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
+                       if (closefunc != NULL)
+                               (*closefunc)(fin);
                        return;
                }
        } else
                        return;
                }
        } else
@@ -464,19 +500,22 @@ sendrequest(cmd, local, remote)
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
                        (void) signal(SIGINT, oldintr);
                        if (oldintp)
                                (void) signal(SIGPIPE, oldintp);
+                       if (closefunc != NULL)
+                               (*closefunc)(fin);
                        return;
                }
                        return;
                }
-       dout = dataconn("w");
+       dout = dataconn(mode);
        if (dout == NULL)
                goto abort;
        (void) gettimeofday(&start, (struct timezone *)0);
        if (dout == NULL)
                goto abort;
        (void) gettimeofday(&start, (struct timezone *)0);
+       oldintp = signal(SIGPIPE, SIG_IGN);
        switch (type) {
 
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
                while ((c = read(fileno (fin), buf, sizeof (buf))) > 0) {
        switch (type) {
 
        case TYPE_I:
        case TYPE_L:
                errno = d = 0;
                while ((c = read(fileno (fin), buf, sizeof (buf))) > 0) {
-                       if ((d = write(fileno (dout), buf, c)) < 0)
+                       if ((d = write(fileno (dout), buf, c)) != c)
                                break;
                        bytes += c;
                        if (hash) {
                                break;
                        bytes += c;
                        if (hash) {
@@ -490,8 +529,11 @@ sendrequest(cmd, local, remote)
                }
                if (c < 0)
                        perror(local);
                }
                if (c < 0)
                        perror(local);
-               if (d < 0)
-                       perror("netout");
+               if (d < 0) {
+                       if (errno != EPIPE) 
+                               perror("netout");
+                       bytes = -1;
+               }
                break;
 
        case TYPE_A:
                break;
 
        case TYPE_A:
@@ -522,8 +564,11 @@ sendrequest(cmd, local, remote)
                }
                if (ferror(fin))
                        perror(local);
                }
                if (ferror(fin))
                        perror(local);
-               if (ferror(dout))
-                       perror("netout");
+               if (ferror(dout)) {
+                       if (errno != EPIPE)
+                               perror("netout");
+                       bytes = -1;
+               }
                break;
        }
        (void) gettimeofday(&stop, (struct timezone *)0);
                break;
        }
        (void) gettimeofday(&stop, (struct timezone *)0);
@@ -532,6 +577,8 @@ sendrequest(cmd, local, remote)
        (void) fclose(dout);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
        (void) fclose(dout);
        (void) getreply(0);
        (void) signal(SIGINT, oldintr);
+       if (oldintp)
+               (void) signal(SIGPIPE, oldintp);
        if (bytes > 0)
                ptransfer("sent", bytes, &start, &stop, local, remote);
        return;
        if (bytes > 0)
                ptransfer("sent", bytes, &start, &stop, local, remote);
        return;
@@ -575,21 +622,22 @@ recvrequest(cmd, local, remote, mode)
 {
        FILE *fout, *din = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); 
 {
        FILE *fout, *din = 0, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)(), (*oldintp)(); 
-       int abortrecv(), oldverbose, oldtype = 0, tcrflag, nfnd;
+       int abortrecv(), oldverbose, oldtype = 0, is_retr, tcrflag, nfnd;
        char buf[BUFSIZ], *gunique(), msg;
        long bytes = 0, hashbytes = sizeof (buf);
        struct fd_set mask;
        register int c, d;
        struct timeval start, stop;
 
        char buf[BUFSIZ], *gunique(), msg;
        long bytes = 0, hashbytes = sizeof (buf);
        struct fd_set mask;
        register int c, d;
        struct timeval start, stop;
 
-       if (proxy && strcmp(cmd,"RETR") == 0) {
+       is_retr = strcmp(cmd, "RETR") == 0;
+       if (proxy && is_retr) {
                proxtrans(cmd, local, remote);
                return;
        }
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
                proxtrans(cmd, local, remote);
                return;
        }
        closefunc = NULL;
        oldintr = NULL;
        oldintp = NULL;
-       tcrflag = !crflag && !strcmp(cmd, "RETR");
+       tcrflag = !crflag && is_retr;
        if (setjmp(recvabort)) {
                while (cpend) {
                        (void) getreply(0);
        if (setjmp(recvabort)) {
                while (cpend) {
                        (void) getreply(0);
@@ -626,7 +674,7 @@ recvrequest(cmd, local, remote, mode)
                                return;
                        }
                        if (!runique && errno == EACCES &&
                                return;
                        }
                        if (!runique && errno == EACCES &&
-                           chmod(local,0600) < 0) {
+                           chmod(local, 0600) < 0) {
                                perror(local);
                                (void) signal(SIGINT, oldintr);
                                code = -1;
                                perror(local);
                                (void) signal(SIGINT, oldintr);
                                code = -1;
@@ -652,13 +700,18 @@ recvrequest(cmd, local, remote, mode)
        }
        if (setjmp(recvabort))
                goto abort;
        }
        if (setjmp(recvabort))
                goto abort;
-       if (strcmp(cmd, "RETR") && type != TYPE_A) {
-               oldtype = type;
-               oldverbose = verbose;
-               if (!debug)
-                       verbose = 0;
-               setascii();
-               verbose = oldverbose;
+       if (!is_retr) {
+               if (type != TYPE_A) {
+                       oldtype = type;
+                       oldverbose = verbose;
+                       if (!debug)
+                               verbose = 0;
+                       setascii();
+                       verbose = oldverbose;
+               }
+       } else if (restart_point) {
+               if (command("REST %ld", (long) restart_point) != CONTINUE)
+                       return;
        }
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
        }
        if (remote) {
                if (command("%s %s", cmd, remote) != PRELIM) {
@@ -676,7 +729,7 @@ recvrequest(cmd, local, remote, mode)
                                        case TYPE_L:
                                                settenex();
                                                break;
                                        case TYPE_L:
                                                settenex();
                                                break;
-                               }
+                                       }
                                verbose = oldverbose;
                        }
                        return;
                                verbose = oldverbose;
                        }
                        return;
@@ -697,7 +750,7 @@ recvrequest(cmd, local, remote, mode)
                                        case TYPE_L:
                                                settenex();
                                                break;
                                        case TYPE_L:
                                                settenex();
                                                break;
-                               }
+                                       }
                                verbose = oldverbose;
                        }
                        return;
                                verbose = oldverbose;
                        }
                        return;
@@ -730,9 +783,16 @@ recvrequest(cmd, local, remote, mode)
 
        case TYPE_I:
        case TYPE_L:
 
        case TYPE_I:
        case TYPE_L:
+               if (restart_point &&
+                   lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
+                       perror(local);
+                       if (closefunc != NULL)
+                               (*closefunc)(fout);
+                       return;
+               }
                errno = d = 0;
                while ((c = read(fileno(din), buf, sizeof (buf))) > 0) {
                errno = d = 0;
                while ((c = read(fileno(din), buf, sizeof (buf))) > 0) {
-                       if ((d = write(fileno(fout), buf, c)) < 0)
+                       if ((d = write(fileno(fout), buf, c)) != c)
                                break;
                        bytes += c;
                        if (hash) {
                                break;
                        bytes += c;
                        if (hash) {
@@ -744,13 +804,36 @@ recvrequest(cmd, local, remote, mode)
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
-               if (c < 0)
-                       perror("netin");
+               if (c < 0) {
+                       if (errno != EPIPE)
+                               perror("netin");
+                       bytes = -1;
+               }
                if (d < 0)
                        perror(local);
                break;
 
        case TYPE_A:
                if (d < 0)
                        perror(local);
                break;
 
        case TYPE_A:
+               if (restart_point) {
+                       register int i, n, c;
+                       if (fseek(fout, 0L, L_SET) < 0)
+                               goto done;
+                       n = restart_point;
+                       i = 0;
+                       while(i++ < n) {
+                               if ((c=getc(fout)) == EOF)
+                                       goto done;
+                               if (c == '\n')
+                                       i++;
+                       }       
+                       if (fseek(fout, 0L, L_INCR) < 0) {
+done:
+                               perror(local);
+                               if (closefunc != NULL)
+                                       (*closefunc)(fout);
+                               return;
+                       }
+               }
                while ((c = getc(din)) != EOF) {
                        while (c == '\r') {
                                while (hash && (bytes >= hashbytes)) {
                while ((c = getc(din)) != EOF) {
                        while (c == '\r') {
                                while (hash && (bytes >= hashbytes)) {
@@ -764,10 +847,6 @@ recvrequest(cmd, local, remote, mode)
                                                break;
                                        (void) putc ('\r', fout);
                                }
                                                break;
                                        (void) putc ('\r', fout);
                                }
-                               /*if (c == '\0') {
-                                       bytes++;
-                                       continue;
-                               }*/
                        }
                        (void) putc (c, fout);
                        bytes++;
                        }
                        (void) putc (c, fout);
                        bytes++;
@@ -778,8 +857,11 @@ recvrequest(cmd, local, remote, mode)
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
                        (void) putchar('\n');
                        (void) fflush(stdout);
                }
-               if (ferror (din))
-                       perror ("netin");
+               if (ferror (din)){
+                       if (errno != EPIPE)
+                               perror ("netin");
+                       bytes = -1;
+               }
                if (ferror (fout))
                        perror (local);
                break;
                if (ferror (fout))
                        perror (local);
                break;
@@ -792,7 +874,7 @@ recvrequest(cmd, local, remote, mode)
        (void) gettimeofday(&stop, (struct timezone *)0);
        (void) fclose(din);
        (void) getreply(0);
        (void) gettimeofday(&stop, (struct timezone *)0);
        (void) fclose(din);
        (void) getreply(0);
-       if (bytes > 0)
+       if (bytes > 0 && is_retr)
                ptransfer("received", bytes, &start, &stop, local, remote);
        if (oldtype) {
                if (!debug)
                ptransfer("received", bytes, &start, &stop, local, remote);
        if (oldtype) {
                if (!debug)
index 722d795..022cea6 100644 (file)
@@ -12,7 +12,7 @@
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -22,7 +22,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.11 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.12 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -244,7 +244,7 @@ cmdscanner(top)
                }
                (*c->c_handler)(margc, margv);
                if (bell && c->c_bell)
                }
                (*c->c_handler)(margc, margv);
                if (bell && c->c_bell)
-                       (void) putchar(CTRL('g'));
+                       (void) putchar('\007');
                if (c->c_handler != help)
                        break;
        }
                if (c->c_handler != help)
                        break;
        }
@@ -321,7 +321,7 @@ slurpstring()
                                slrflag++;
                                stringbase++;
                                return ((*sb == '!') ? "!" : "$");
                                slrflag++;
                                stringbase++;
                                return ((*sb == '!') ? "!" : "$");
-                               break;
+                               /* NOTREACHED */
                        case 1:
                                slrflag++;
                                altarg = stringbase;
                        case 1:
                                slrflag++;
                                altarg = stringbase;
index a3bfa83..396b85f 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ruserpass.c        1.6 (Berkeley) %G%";
+static char sccsid[] = "@(#)ruserpass.c        1.7 (Berkeley) %G%";
 #endif /* not lint */
 
 struct macel {
 #endif /* not lint */
 
 struct macel {
@@ -78,7 +78,7 @@ rnetrc(host, aname, apass, aacct)
        char *host, **aname, **apass, **aacct;
 {
        char *hdir, buf[BUFSIZ], *tmp;
        char *host, **aname, **apass, **aacct;
 {
        char *hdir, buf[BUFSIZ], *tmp;
-       int t, i, c;
+       int t, i, c, usedefault = 0;
        struct stat stb;
        extern int errno;
 
        struct stat stb;
        extern int errno;
 
@@ -96,11 +96,11 @@ next:
        while ((t = token())) switch(t) {
 
        case DEFAULT:
        while ((t = token())) switch(t) {
 
        case DEFAULT:
-               (void) token();
-               continue;
+               usedefault = 1;
+               /* FALL THROUGH */
 
        case MACHINE:
 
        case MACHINE:
-               if (token() != ID || strcmp(host, tokval))
+               if (!usedefault && (token() != ID || strcmp(host, tokval)))
                        continue;
                while ((t = token()) && t != MACHINE) switch(t) {
 
                        continue;
                while ((t = token()) && t != MACHINE) switch(t) {