BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / ftp / cmds.c
index 5c42548..56cc428 100644 (file)
@@ -2,11 +2,37 @@
  * Copyright (c) 1985, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1985, 1989 Regents of the University of California.
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmds.c     5.26 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmds.c     5.26 (Berkeley) 3/5/91";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -39,6 +65,7 @@ extern        char *index();
 extern char *rindex();
 extern char *strerror();
 extern int  errno;
 extern char *rindex();
 extern char *strerror();
 extern int  errno;
+extern off_t restart_point;
 extern char reply_string[];
 
 char *mname;
 extern char reply_string[];
 
 char *mname;
@@ -527,12 +554,27 @@ mput(argc, argv)
        mflag = 0;
 }
 
        mflag = 0;
 }
 
+reget(argc, argv)
+       int argc;
+       char *argv[];
+{
+       (void) getit(argc, argv, 1, "r+w");
+}
+
+get(argc, argv)
+       int argc;
+       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)
+       int argc;
        char *argv[];
        char *argv[];
+       char *mode;
 {
        int loc = 0;
        char *oldargv1, *oldargv2;
 {
        int loc = 0;
        char *oldargv1, *oldargv2;
@@ -548,13 +590,13 @@ 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);
        }
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        if (!globulize(&argv[2])) {
                code = -1;
        }
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        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];
@@ -579,7 +621,65 @@ usage:
                argv[2] = dotrans(argv[2]);
        if (loc && mapflag)
                argv[2] = domap(argv[2]);
                argv[2] = dotrans(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) {
+                               fprintf(stderr, "local: %s: %s\n", argv[2],
+                                       strerror(errno));
+                               return (0);
+                       }
+                       restart_point = stbuf.st_size;
+               } else {
+                       if (ret == 0) {
+                               int overbose;
+
+                               overbose = verbose;
+                               if (debug == 0)
+                                       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 {
+                                       printf("%s\n", reply_string);
+                                       verbose = overbose;
+                                       return (0);
+                               }
+                       }
+               }
+       }
+
+       recvrequest("RETR", argv[2], argv[1], mode,
+           argv[1] != oldargv1 || argv[2] != oldargv2);
+       restart_point = 0;
+       return (0);
 }
 
 void
 }
 
 void
@@ -1886,6 +1986,20 @@ 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. %s\n", restart_point,
+                   "execute get, put or append to initiate transfer");
+       }
+}
 
 /* show remote system type */
 syst()
 
 /* show remote system type */
 syst()
@@ -1999,7 +2113,7 @@ modtime(argc, argv)
 }
 
 /*
 }
 
 /*
- * show status on remote machine
+ * show status on reomte machine
  */
 rmtstatus(argc, argv)
        int argc;
  */
 rmtstatus(argc, argv)
        int argc;
@@ -2007,3 +2121,15 @@ rmtstatus(argc, argv)
 {
        (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
 }
 {
        (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
 }
+
+/*
+ * get file if modtime is more recent than current file
+ */
+newer(argc, argv)
+       int argc;
+       char *argv[];
+{
+       if (getit(argc, argv, -1, "w"))
+               printf("Local file \"%s\" is newer than remote file \"%s\"\n",
+                       argv[1], argv[2]);
+}