add 1994 copyright
[unix-history] / usr / src / usr.bin / ftp / main.c
index 1f1431a..3b5b846 100644 (file)
 /*
 /*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1985, 1989, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1983 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif not lint
+static char copyright[] =
+"@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
      The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.2 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)main.c     8.3 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * FTP User Program -- Command Interface.
  */
 
 /*
  * FTP User Program -- Command Interface.
  */
-#include <sys/param.h>
+/*#include <sys/ioctl.h>*/
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
 
 #include <arpa/ftp.h>
 
 
 #include <arpa/ftp.h>
 
-#include <signal.h>
-#include <stdio.h>
-#include <errno.h>
 #include <ctype.h>
 #include <ctype.h>
+#include <err.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <netdb.h>
 #include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #include "ftp_var.h"
 
 
 #include "ftp_var.h"
 
-int    intr();
-int    lostpeer();
-extern char *home;
-
+int
 main(argc, argv)
 main(argc, argv)
+       int argc;
        char *argv[];
 {
        char *argv[];
 {
-       register char *cp;
-       int top;
-       struct passwd *pw;
-       char homedir[MAXPATHLEN];
+       int ch, top;
+       struct passwd *pw = NULL;
+       char *cp, homedir[MAXPATHLEN];
 
        sp = getservbyname("ftp", "tcp");
 
        sp = getservbyname("ftp", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
-               exit(1);
-       }
+       if (sp == 0)
+               errx(1, "ftp/tcp: unknown service");
        doglob = 1;
        interactive = 1;
        autologin = 1;
        doglob = 1;
        interactive = 1;
        autologin = 1;
-       argc--, argv++;
-       while (argc > 0 && **argv == '-') {
-               for (cp = *argv + 1; *cp; cp++)
-                       switch (*cp) {
-
-                       case 'd':
-                               options |= SO_DEBUG;
-                               debug++;
-                               break;
+
+       while ((ch = getopt(argc, argv, "dgintv")) != EOF) {
+               switch (*cp) {
+               case 'd':
+                       options |= SO_DEBUG;
+                       debug++;
+                       break;
                        
                        
-                       case 'v':
-                               verbose++;
-                               break;
+               case 'g':
+                       doglob = 0;
+                       break;
 
 
-                       case 't':
-                               trace++;
-                               break;
+               case 'i':
+                       interactive = 0;
+                       break;
 
 
-                       case 'i':
-                               interactive = 0;
-                               break;
+               case 'n':
+                       autologin = 0;
+                       break;
 
 
-                       case 'n':
-                               autologin = 0;
-                               break;
+               case 't':
+                       trace++;
+                       break;
 
 
-                       case 'g':
-                               doglob = 0;
-                               break;
+               case 'v':
+                       verbose++;
+                       break;
 
 
-                       default:
-                               fprintf(stderr,
-                                 "ftp: %c: unknown option\n", *cp);
-                               exit(1);
-                       }
-               argc--, argv++;
+               default:
+                       (void)fprintf(stderr,
+                               "usage: ftp [-dgintv] [host [port]]\n");
+                       exit(1);
+               }
        }
        }
+       argc -= optind;
+       argv += optind;
+
        fromatty = isatty(fileno(stdin));
        fromatty = isatty(fileno(stdin));
-       /*
-        * Set up defaults for FTP.
-        */
-       strcpy(typename, "ascii"), type = TYPE_A;
-       strcpy(formname, "non-print"), form = FORM_N;
-       strcpy(modename, "stream"), mode = MODE_S;
-       strcpy(structname, "file"), stru = STRU_F;
-       strcpy(bytename, "8"), bytesize = 8;
        if (fromatty)
                verbose++;
        if (fromatty)
                verbose++;
+       cpend = 0;      /* no pending replies */
+       proxy = 0;      /* proxy not active */
+       crflag = 1;     /* strip c.r. on ascii gets */
+       sendport = -1;  /* not using ports */
        /*
         * Set up the home directory in case we're globbing.
         */
        /*
         * Set up the home directory in case we're globbing.
         */
-       pw = getpwnam(getlogin());
+       cp = getlogin();
+       if (cp != NULL) {
+               pw = getpwnam(cp);
+       }
        if (pw == NULL)
                pw = getpwuid(getuid());
        if (pw != NULL) {
                home = homedir;
        if (pw == NULL)
                pw = getpwuid(getuid());
        if (pw != NULL) {
                home = homedir;
-               strcpy(home, pw->pw_dir);
+               (void) strcpy(home, pw->pw_dir);
        }
        if (argc > 0) {
        }
        if (argc > 0) {
+               char *xargv[3];
+               extern char *__progname;
+
                if (setjmp(toplevel))
                        exit(0);
                if (setjmp(toplevel))
                        exit(0);
-               signal(SIGINT, intr);
-               signal(SIGPIPE, lostpeer);
-               setpeer(argc + 1, argv - 1);
+               (void) signal(SIGINT, intr);
+               (void) signal(SIGPIPE, lostpeer);
+               xargv[0] = __progname;
+               xargv[1] = argv[0];
+               xargv[2] = argv[1];
+               xargv[3] = argv[2];
+               setpeer(argc+1, xargv);
        }
        top = setjmp(toplevel) == 0;
        if (top) {
        }
        top = setjmp(toplevel) == 0;
        if (top) {
-               signal(SIGINT, intr);
-               signal(SIGPIPE, lostpeer);
+               (void) signal(SIGINT, intr);
+               (void) signal(SIGPIPE, lostpeer);
        }
        for (;;) {
                cmdscanner(top);
        }
        for (;;) {
                cmdscanner(top);
@@ -128,41 +132,52 @@ main(argc, argv)
        }
 }
 
        }
 }
 
+void
 intr()
 {
 
        longjmp(toplevel, 1);
 }
 
 intr()
 {
 
        longjmp(toplevel, 1);
 }
 
+void
 lostpeer()
 {
 lostpeer()
 {
-       extern FILE *cout;
-       extern int data;
 
        if (connected) {
                if (cout != NULL) {
 
        if (connected) {
                if (cout != NULL) {
-                       shutdown(fileno(cout), 1+1);
-                       fclose(cout);
+                       (void) shutdown(fileno(cout), 1+1);
+                       (void) fclose(cout);
                        cout = NULL;
                }
                if (data >= 0) {
                        cout = NULL;
                }
                if (data >= 0) {
-                       shutdown(data, 1+1);
+                       (void) shutdown(data, 1+1);
                        (void) close(data);
                        data = -1;
                }
                connected = 0;
        }
                        (void) close(data);
                        data = -1;
                }
                connected = 0;
        }
-       longjmp(toplevel, 1);
+       pswitch(1);
+       if (connected) {
+               if (cout != NULL) {
+                       (void) shutdown(fileno(cout), 1+1);
+                       (void) fclose(cout);
+                       cout = NULL;
+               }
+               connected = 0;
+       }
+       proxflag = 0;
+       pswitch(0);
 }
 
 }
 
+/*
 char *
 tail(filename)
        char *filename;
 {
 char *
 tail(filename)
        char *filename;
 {
-       register char *s;
+       char *s;
        
        while (*filename) {
        
        while (*filename) {
-               s = rindex(filename, '/');
+               s = strrchr(filename, '/');
                if (s == NULL)
                        break;
                if (s[1])
                if (s == NULL)
                        break;
                if (s[1])
@@ -171,33 +186,44 @@ tail(filename)
        }
        return (filename);
 }
        }
        return (filename);
 }
+*/
 
 /*
  * Command parser.
  */
 
 /*
  * Command parser.
  */
+void
 cmdscanner(top)
        int top;
 {
 cmdscanner(top)
        int top;
 {
-       register struct cmd *c;
-       struct cmd *getcmd();
-       extern struct cmd cmdtab[];
-       extern int help();
+       struct cmd *c;
+       int l;
 
        if (!top)
 
        if (!top)
-               putchar('\n');
+               (void) putchar('\n');
        for (;;) {
                if (fromatty) {
                        printf("ftp> ");
        for (;;) {
                if (fromatty) {
                        printf("ftp> ");
-                       fflush(stdout);
+                       (void) fflush(stdout);
                }
                }
-               if (gets(line) == 0) {
-                       if (feof(stdin))
-                               quit();
+               if (fgets(line, sizeof line, stdin) == NULL)
+                       quit(0, 0);
+               l = strlen(line);
+               if (l == 0)
                        break;
                        break;
-               }
-               if (line[0] == 0)
+               if (line[--l] == '\n') {
+                       if (l == 0)
+                               break;
+                       line[l] = '\0';
+               } else if (l == sizeof(line) - 2) {
+                       printf("sorry, input line too long\n");
+                       while ((l = getchar()) != '\n' && l != EOF)
+                               /* void */;
                        break;
                        break;
+               } /* else it was a line without a newline */
                makeargv();
                makeargv();
+               if (margc == 0) {
+                       continue;
+               }
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
                        printf("?Ambiguous command\n");
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
                        printf("?Ambiguous command\n");
@@ -208,25 +234,26 @@ cmdscanner(top)
                        continue;
                }
                if (c->c_conn && !connected) {
                        continue;
                }
                if (c->c_conn && !connected) {
-                       printf ("Not connected.\n");
+                       printf("Not connected.\n");
                        continue;
                }
                (*c->c_handler)(margc, margv);
                if (bell && c->c_bell)
                        continue;
                }
                (*c->c_handler)(margc, margv);
                if (bell && c->c_bell)
-                       putchar(CTRL(g));
+                       (void) putchar('\007');
                if (c->c_handler != help)
                        break;
        }
                if (c->c_handler != help)
                        break;
        }
-       longjmp(toplevel, 0);
+       (void) signal(SIGINT, intr);
+       (void) signal(SIGPIPE, lostpeer);
 }
 
 struct cmd *
 getcmd(name)
 }
 
 struct cmd *
 getcmd(name)
-       register char *name;
+       char *name;
 {
 {
-       register char *p, *q;
-       register struct cmd *c, *found;
-       register int nmatches, longest;
+       char *p, *q;
+       struct cmd *c, *found;
+       int nmatches, longest;
 
        longest = 0;
        nmatches = 0;
 
        longest = 0;
        nmatches = 0;
@@ -252,15 +279,19 @@ getcmd(name)
 /*
  * Slice a string up into argc/argv.
  */
 /*
  * Slice a string up into argc/argv.
  */
+
+int slrflag;
+
+void
 makeargv()
 {
        char **argp;
 makeargv()
 {
        char **argp;
-       char *slurpstring();
 
        margc = 0;
        argp = margv;
        stringbase = line;              /* scan from first of buffer */
        argbase = argbuf;               /* store from first of buffer */
 
        margc = 0;
        argp = margv;
        stringbase = line;              /* scan from first of buffer */
        argbase = argbuf;               /* store from first of buffer */
+       slrflag = 0;
        while (*argp++ = slurpstring())
                margc++;
 }
        while (*argp++ = slurpstring())
                margc++;
 }
@@ -274,14 +305,26 @@ char *
 slurpstring()
 {
        int got_one = 0;
 slurpstring()
 {
        int got_one = 0;
-       register char *sb = stringbase;
-       register char *ap = argbase;
+       char *sb = stringbase;
+       char *ap = argbase;
        char *tmp = argbase;            /* will return this if token found */
 
        char *tmp = argbase;            /* will return this if token found */
 
-       if (*sb == '!') {               /* recognize ! as a token for shell */
-               stringbase++;
-               return ("!");
+       if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
+               switch (slrflag) {      /* and $ as token for macro invoke */
+                       case 0:
+                               slrflag++;
+                               stringbase++;
+                               return ((*sb == '!') ? "!" : "$");
+                               /* NOTREACHED */
+                       case 1:
+                               slrflag++;
+                               altarg = stringbase;
+                               break;
+                       default:
+                               break;
+               }
        }
        }
+
 S0:
        switch (*sb) {
 
 S0:
        switch (*sb) {
 
@@ -293,6 +336,17 @@ S0:
                sb++; goto S0;
 
        default:
                sb++; goto S0;
 
        default:
+               switch (slrflag) {
+                       case 0:
+                               slrflag++;
+                               break;
+                       case 1:
+                               slrflag++;
+                               altarg = sb;
+                               break;
+                       default:
+                               break;
+               }
                goto S1;
        }
 
                goto S1;
        }
 
@@ -348,27 +402,39 @@ OUT:
                *ap++ = '\0';
        argbase = ap;                   /* update storage pointer */
        stringbase = sb;                /* update scan pointer */
                *ap++ = '\0';
        argbase = ap;                   /* update storage pointer */
        stringbase = sb;                /* update scan pointer */
-       if (got_one)
-               return(tmp);
-       return((char *)0);
+       if (got_one) {
+               return (tmp);
+       }
+       switch (slrflag) {
+               case 0:
+                       slrflag++;
+                       break;
+               case 1:
+                       slrflag++;
+                       altarg = (char *) 0;
+                       break;
+               default:
+                       break;
+       }
+       return ((char *)0);
 }
 
 }
 
-#define HELPINDENT (sizeof ("directory"))
+#define HELPINDENT ((int) sizeof ("directory"))
 
 /*
  * Help command.
  * Call each command handler with argc == 0 and argv[0] == name.
  */
 
 /*
  * Help command.
  * Call each command handler with argc == 0 and argv[0] == name.
  */
+void
 help(argc, argv)
        int argc;
        char *argv[];
 {
 help(argc, argv)
        int argc;
        char *argv[];
 {
-       register struct cmd *c;
+       struct cmd *c;
 
        if (argc == 1) {
 
        if (argc == 1) {
-               register int i, j, w;
+               int i, j, w, k;
                int columns, width = 0, lines;
                int columns, width = 0, lines;
-               extern int NCMDS;
 
                printf("Commands may be abbreviated.  Commands are:\n\n");
                for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
 
                printf("Commands may be abbreviated.  Commands are:\n\n");
                for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
@@ -385,7 +451,14 @@ help(argc, argv)
                for (i = 0; i < lines; i++) {
                        for (j = 0; j < columns; j++) {
                                c = cmdtab + j * lines + i;
                for (i = 0; i < lines; i++) {
                        for (j = 0; j < columns; j++) {
                                c = cmdtab + j * lines + i;
-                               printf("%s", c->c_name);
+                               if (c->c_name && (!proxy || c->c_proxy)) {
+                                       printf("%s", c->c_name);
+                               }
+                               else if (c->c_name) {
+                                       for (k=0; k < strlen(c->c_name); k++) {
+                                               (void) putchar(' ');
+                                       }
+                               }
                                if (c + lines >= &cmdtab[NCMDS]) {
                                        printf("\n");
                                        break;
                                if (c + lines >= &cmdtab[NCMDS]) {
                                        printf("\n");
                                        break;
@@ -393,14 +466,14 @@ help(argc, argv)
                                w = strlen(c->c_name);
                                while (w < width) {
                                        w = (w + 8) &~ 7;
                                w = strlen(c->c_name);
                                while (w < width) {
                                        w = (w + 8) &~ 7;
-                                       putchar('\t');
+                                       (void) putchar('\t');
                                }
                        }
                }
                return;
        }
        while (--argc > 0) {
                                }
                        }
                }
                return;
        }
        while (--argc > 0) {
-               register char *arg;
+               char *arg;
                arg = *++argv;
                c = getcmd(arg);
                if (c == (struct cmd *)-1)
                arg = *++argv;
                c = getcmd(arg);
                if (c == (struct cmd *)-1)
@@ -412,19 +485,3 @@ help(argc, argv)
                                c->c_name, c->c_help);
        }
 }
                                c->c_name, c->c_help);
        }
 }
-
-/*
- * Call routine with argc, argv set from args (terminated by 0).
- */
-/* VARARGS2 */
-call(routine, args)
-       int (*routine)();
-       int args;
-{
-       register int *argp;
-       register int argc;
-
-       for (argc = 0, argp = &args; *argp++ != 0; argc++)
-               ;
-       (*routine)(argc, &args);
-}