recognize and handle carrier loss
[unix-history] / usr / src / usr.bin / tip / cmds.c
index b6aa514..f4911a1 100644 (file)
@@ -1,4 +1,7 @@
-/*     cmds.c  4.9     82/07/29        */
+#ifndef lint
+static char sccsid[] = "@(#)cmds.c     4.13 (Berkeley) %G%";
+#endif
+
 #include "tip.h"
 /*
  * tip
 #include "tip.h"
 /*
  * tip
@@ -24,7 +27,7 @@ int   intcopy();              /* interrupt routine for file transfers */
 getfl(c)
        char c;
 {
 getfl(c)
        char c;
 {
-       char buf[256];
+       char buf[256], *cp, *expand();
        
        putchar(c);
        /*
        
        putchar(c);
        /*
@@ -32,7 +35,8 @@ getfl(c)
         */
        if (prompt("Local file name? ", copyname))
                return;
         */
        if (prompt("Local file name? ", copyname))
                return;
-       if ((sfd = creat(copyname, 0666)) < 0) {
+       cp = expand(copyname);
+       if ((sfd = creat(cp, 0666)) < 0) {
                printf("\r\n%s: cannot creat\r\n", copyname);
                return;
        }
                printf("\r\n%s: cannot creat\r\n", copyname);
                return;
        }
@@ -54,7 +58,7 @@ cu_take(cc)
        char cc;
 {
        int fd, argc;
        char cc;
 {
        int fd, argc;
-       char line[BUFSIZ];
+       char line[BUFSIZ], *expand(), *cp;
 
        if (prompt("[take] ", copyname))
                return;
 
        if (prompt("[take] ", copyname))
                return;
@@ -64,14 +68,16 @@ cu_take(cc)
        }
        if (argc == 1)
                argv[1] = argv[0];
        }
        if (argc == 1)
                argv[1] = argv[0];
-       if ((fd = creat(argv[1], 0666)) < 0) {
+       cp = expand(argv[1]);
+       if ((fd = creat(cp, 0666)) < 0) {
                printf("\r\n%s: cannot create\r\n", argv[1]);
                return;
        }
                printf("\r\n%s: cannot create\r\n", argv[1]);
                return;
        }
-       sprintf(line, "cat '%s';echo \01", argv[0]);
+       sprintf(line, "cat %s;echo \01", argv[0]);
        transfer(line, fd, "\01");
 }
 
        transfer(line, fd, "\01");
 }
 
+static jmp_buf intbuf;
 /*
  * Bulk transfer routine --
  *  used by getfl(), cu_take(), and pipefile()
 /*
  * Bulk transfer routine --
  *  used by getfl(), cu_take(), and pipefile()
@@ -84,23 +90,25 @@ transfer(buf, fd, eofchars)
        register char *p = buffer;
        register int cnt, eof;
        time_t start;
        register char *p = buffer;
        register int cnt, eof;
        time_t start;
+       int (*f)();
 
 
-       write(FD, buf, size(buf));
+       pwrite(FD, buf, size(buf));
        quit = 0;
        quit = 0;
-       signal(SIGINT, intcopy);
        kill(pid, SIGIOT);
        read(repdes[0], (char *)&ccc, 1);  /* Wait until read process stops */
        
        /*
         * finish command
         */
        kill(pid, SIGIOT);
        read(repdes[0], (char *)&ccc, 1);  /* Wait until read process stops */
        
        /*
         * finish command
         */
-       write(FD, "\r", 1);
+       pwrite(FD, "\r", 1);
        do
                read(FD, &c, 1); 
        while ((c&0177) != '\n');
        ioctl(0, TIOCSETC, &defchars);
        
        do
                read(FD, &c, 1); 
        while ((c&0177) != '\n');
        ioctl(0, TIOCSETC, &defchars);
        
+       f = signal(SIGINT, intcopy);
        start = time(0);
        start = time(0);
+       (void) setjmp(intbuf);
        for (ct = 0; !quit;) {
                eof = read(FD, &c, 1) <= 0;
                c &= 0177;
        for (ct = 0; !quit;) {
                eof = read(FD, &c, 1) <= 0;
                c &= 0177;
@@ -188,6 +196,7 @@ pipefile()
  */
 stopsnd()
 {
  */
 stopsnd()
 {
+
        stop = 1;
        signal(SIGINT, SIG_IGN);
 }
        stop = 1;
        signal(SIGINT, SIG_IGN);
 }
@@ -201,6 +210,8 @@ sendfile(cc)
        char cc;
 {
        FILE *fd;
        char cc;
 {
        FILE *fd;
+       char *fnamex;
+       char *expand();
 
        putchar(cc);
        /*
 
        putchar(cc);
        /*
@@ -212,7 +223,8 @@ sendfile(cc)
        /*
         * look up file
         */
        /*
         * look up file
         */
-       if ((fd = fopen(fname, "r")) == NULL) {
+       fnamex = expand(fname);
+       if ((fd = fopen(fnamex, "r")) == NULL) {
                printf("%s: cannot open\r\n", fname);
                return;
        }
                printf("%s: cannot open\r\n", fname);
                return;
        }
@@ -233,7 +245,7 @@ transmit(fd, eofchars, command)
        FILE *fd;
        char *eofchars, *command;
 {
        FILE *fd;
        char *eofchars, *command;
 {
-       char *pc, lastc, rc;
+       char *pc, lastc;
        int c, ccount, lcount;
        time_t start_t, stop_t;
 
        int c, ccount, lcount;
        time_t start_t, stop_t;
 
@@ -266,43 +278,48 @@ transmit(fd, eofchars, command)
                                goto out;
                        if (c == EOF)
                                goto out;
                                goto out;
                        if (c == EOF)
                                goto out;
-                       if (c == 0177)
+                       if (c == 0177 && !boolean(value(RAWFTP)))
                                continue;
                        lastc = c;
                        if (c < 040) {
                                continue;
                        lastc = c;
                        if (c < 040) {
-                               if (c == '\n')
-                                       c = '\r';
+                               if (c == '\n') {
+                                       if (!boolean(value(RAWFTP)))
+                                               c = '\r';
+                               }
                                else if (c == '\t') {
                                else if (c == '\t') {
-                                       if (boolean(value(TABEXPAND))) {
-                                               send(' ');
-                                               while ((++ccount % 8) != 0)
+                                       if (!boolean(value(RAWFTP))) {
+                                               if (boolean(value(TABEXPAND))) {
                                                        send(' ');
                                                        send(' ');
-                                               continue;
+                                                       while ((++ccount % 8) != 0)
+                                                               send(' ');
+                                                       continue;
+                                               }
                                        }
                                        }
-                               } else if (!any(c, value(EXCEPTIONS)))
-                                       continue;
+                               } else
+                                       if (!boolean(value(RAWFTP)))
+                                               continue;
                        }
                        send(c);
                        }
                        send(c);
-               } while (c != '\r');
+               } while (c != '\r' && !boolean(value(RAWFTP)));
                if (boolean(value(VERBOSE)))
                        printf("\r%d", ++lcount);
                if (boolean(value(ECHOCHECK))) {
                if (boolean(value(VERBOSE)))
                        printf("\r%d", ++lcount);
                if (boolean(value(ECHOCHECK))) {
-                       alarm(10);
+                       alarm(value(ETIMEOUT));
                        timedout = 0;
                        do {    /* wait for prompt */
                        timedout = 0;
                        do {    /* wait for prompt */
-                               read(FD, (char *)&rc, 1);
+                               read(FD, (char *)&c, 1);
                                if (timedout || stop) {
                                        if (timedout)
                                                printf("\r\ntimed out at eol\r\n");
                                        alarm(0);
                                        goto out;
                                }
                                if (timedout || stop) {
                                        if (timedout)
                                                printf("\r\ntimed out at eol\r\n");
                                        alarm(0);
                                        goto out;
                                }
-                       } while ((rc&0177) != character(value(PROMPT)));
+                       } while ((c&0177) != character(value(PROMPT)));
                        alarm(0);
                }
        }
 out:
                        alarm(0);
                }
        }
 out:
-       if (lastc != '\n')
+       if (lastc != '\n' && !boolean(value(RAWFTP)))
                send('\r');
        for (pc = eofchars; *pc; pc++)
                send(*pc);
                send('\r');
        for (pc = eofchars; *pc; pc++)
                send(*pc);
@@ -310,7 +327,10 @@ out:
        fclose(fd);
        signal(SIGINT, SIG_DFL);
        if (boolean(value(VERBOSE)))
        fclose(fd);
        signal(SIGINT, SIG_DFL);
        if (boolean(value(VERBOSE)))
-               prtime(" lines transferred in ", stop_t-start_t);
+               if (boolean(value(RAWFTP)))
+                       prtime(" chars transferred in ", stop_t-start_t);
+               else
+                       prtime(" lines transferred in ", stop_t-start_t);
        write(fildes[1], (char *)&ccc, 1);
        ioctl(0, TIOCSETC, &tchars);
 }
        write(fildes[1], (char *)&ccc, 1);
        ioctl(0, TIOCSETC, &tchars);
 }
@@ -324,6 +344,8 @@ cu_put(cc)
        FILE *fd;
        char line[BUFSIZ];
        int argc;
        FILE *fd;
        char line[BUFSIZ];
        int argc;
+       char *expand();
+       char *copynamex;
 
        if (prompt("[put] ", copyname))
                return;
 
        if (prompt("[put] ", copyname))
                return;
@@ -333,14 +355,15 @@ cu_put(cc)
        }
        if (argc == 1)
                argv[1] = argv[0];
        }
        if (argc == 1)
                argv[1] = argv[0];
-       if ((fd = fopen(argv[0], "r")) == NULL) {
-               printf("%s: cannot open\r\n", argv[0]);
+       copynamex = expand(argv[0]);
+       if ((fd = fopen(copynamex, "r")) == NULL) {
+               printf("%s: cannot open\r\n", copynamex);
                return;
        }
        if (boolean(value(ECHOCHECK)))
                return;
        }
        if (boolean(value(ECHOCHECK)))
-               sprintf(line, "cat>'%s'\r", argv[1]);
+               sprintf(line, "cat>%s\r", argv[1]);
        else
        else
-               sprintf(line, "stty -echo;cat>'%s';stty echo\r", argv[1]);
+               sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]);
        transmit(fd, "\04", line);
 }
 
        transmit(fd, "\04", line);
 }
 
@@ -355,19 +378,28 @@ send(c)
        int retry = 0;
 
        cc = c;
        int retry = 0;
 
        cc = c;
-       write(FD, (char *)&cc, 1);
-       if (!boolean(value(ECHOCHECK)))
+       pwrite(FD, &cc, 1);
+#ifdef notdef
+       if (number(value(CDELAY)) > 0 && c != '\r')
+               nap(number(value(CDELAY)));
+#endif
+       if (!boolean(value(ECHOCHECK))) {
+#ifdef notdef
+               if (number(value(LDELAY)) > 0 && c == '\r')
+                       nap(number(value(LDELAY)));
+#endif
                return;
                return;
+       }
 tryagain:
        timedout = 0;
 tryagain:
        timedout = 0;
-       alarm(10);
-       read(FD, (char *)&cc, 1);
+       alarm(value(ETIMEOUT));
+       read(FD, &cc, 1);
        alarm(0);
        if (timedout) {
                printf("\r\ntimeout error (%s)\r\n", ctrl(c));
                if (retry++ > 3)
                        return;
        alarm(0);
        if (timedout) {
                printf("\r\ntimeout error (%s)\r\n", ctrl(c));
                if (retry++ > 3)
                        return;
-               write(FD, &null, 1); /* poke it */
+               pwrite(FD, &null, 1); /* poke it */
                goto tryagain;
        }
 }
                goto tryagain;
        }
 }
@@ -494,33 +526,50 @@ setscript()
  */
 chdirectory()
 {
  */
 chdirectory()
 {
-       char    dirname[80];
+       char dirname[80];
        register char *cp = dirname;
 
        register char *cp = dirname;
 
-       if (prompt("[cd] ", dirname))
+       if (prompt("[cd] ", dirname)) {
                if (stoprompt)
                        return;
                if (stoprompt)
                        return;
-               else
-                       cp = value(HOME);
+               cp = value(HOME);
+       }
        if (chdir(cp) < 0)
                printf("%s: bad directory\r\n", cp);
        printf("!\r\n");
 }
 
        if (chdir(cp) < 0)
                printf("%s: bad directory\r\n", cp);
        printf("!\r\n");
 }
 
-finish()
+abort(msg)
+       char *msg;
 {
 {
+
        kill(pid, SIGTERM);
        kill(pid, SIGTERM);
-       disconnect();
+       disconnect(msg);
+       if (msg != NOSTR)
+               printf("\r\n%s", msg);
        printf("\r\n[EOT]\r\n");
        delock(uucplock);
        unraw();
        exit(0);
 }
 
        printf("\r\n[EOT]\r\n");
        delock(uucplock);
        unraw();
        exit(0);
 }
 
+finish()
+{
+       char *dismsg;
+
+       if ((dismsg = value(DISCONNECT)) != NOSTR) {
+               write(FD, dismsg, strlen(dismsg));
+               sleep(5);
+       }
+       abort(NOSTR);
+}
+
 intcopy()
 {
 intcopy()
 {
+
        raw();
        quit = 1;
        raw();
        quit = 1;
+       longjmp(intbuf, 1);
 }
 
 execute(s)
 }
 
 execute(s)
@@ -604,41 +653,146 @@ variable()
                if (boolean(value(SCRIPT)))
                        setscript();
        }
                if (boolean(value(SCRIPT)))
                        setscript();
        }
+       if (vtable[TAND].v_access&CHANGED) {
+               vtable[TAND].v_access &= ~CHANGED;
+               if (boolean(value(TAND)))
+                       tandem("on");
+               else
+                       tandem("off");
+       }
+       if (vtable[LECHO].v_access&CHANGED) {
+               vtable[LECHO].v_access &= ~CHANGED;
+               HD = boolean(value(LECHO));
+       }
+       if (vtable[PARITY].v_access&CHANGED) {
+               vtable[PARITY].v_access &= ~CHANGED;
+               setparity();
+       }
+}
+
+/*
+ * Turn tandem mode on or off for remote tty.
+ */
+tandem(option)
+       char *option;
+{
+       struct sgttyb rmtty;
+
+       ioctl(FD, TIOCGETP, &rmtty);
+       if (strcmp(option,"on") == 0) {
+               rmtty.sg_flags |= TANDEM;
+               arg.sg_flags |= TANDEM;
+       } else {
+               rmtty.sg_flags &= ~TANDEM;
+               arg.sg_flags &= ~TANDEM;
+       }
+       ioctl(FD, TIOCSETP, &rmtty);
+       ioctl(0,  TIOCSETP, &arg);
 }
 
 /*
  * Send a break.
 }
 
 /*
  * Send a break.
- * If we can't do it directly (as on VMUNIX), then simulate it.
  */
 genbrk()
 {
  */
 genbrk()
 {
-#ifdef VMUNIX
+
        ioctl(FD, TIOCSBRK, NULL);
        sleep(1);
        ioctl(FD, TIOCCBRK, NULL);
        ioctl(FD, TIOCSBRK, NULL);
        sleep(1);
        ioctl(FD, TIOCCBRK, NULL);
-#else
-       struct sgttyb ttbuf;
-       int sospeed;
-
-       ioctl(FD, TIOCGETP, &ttbuf);
-       sospeed = ttbuf.sg_ospeed;
-       ttbuf.sg_ospeed = B150;
-       ioctl(FD, TIOCSETP, &ttbuf);
-       write(FD, "\0\0\0\0\0\0\0\0\0\0", 10);
-       ttbuf.sg_ospeed = sospeed;
-       ioctl(FD, TIOCSETP, &ttbuf);
-       write(FD, "@", 1);
-#endif
 }
 
 }
 
-#ifdef SIGTSTP
 /*
  * Suspend tip
  */
 suspend()
 {
 /*
  * Suspend tip
  */
 suspend()
 {
+
        unraw();
        kill(0, SIGTSTP);
        raw();
 }
        unraw();
        kill(0, SIGTSTP);
        raw();
 }
-#endif
+
+/*
+ *     expand a file name if it includes shell meta characters
+ */
+
+char *
+expand(name)
+       char name[];
+{
+       static char xname[BUFSIZ];
+       char cmdbuf[BUFSIZ];
+       register int pid, l, rc;
+       register char *cp, *Shell;
+       int s, pivec[2], (*sigint)();
+
+       if (!anyof(name, "~{[*?$`'\"\\"))
+               return(name);
+       /* sigint = signal(SIGINT, SIG_IGN); */
+       if (pipe(pivec) < 0) {
+               perror("pipe");
+               /* signal(SIGINT, sigint) */
+               return(name);
+       }
+       sprintf(cmdbuf, "echo %s", name);
+       if ((pid = vfork()) == 0) {
+               Shell = value(SHELL);
+               if (Shell == NOSTR)
+                       Shell = "/bin/sh";
+               close(pivec[0]);
+               close(1);
+               dup(pivec[1]);
+               close(pivec[1]);
+               close(2);
+               execl(Shell, Shell, "-c", cmdbuf, 0);
+               _exit(1);
+       }
+       if (pid == -1) {
+               perror("fork");
+               close(pivec[0]);
+               close(pivec[1]);
+               return(NOSTR);
+       }
+       close(pivec[1]);
+       l = read(pivec[0], xname, BUFSIZ);
+       close(pivec[0]);
+       while (wait(&s) != pid);
+               ;
+       s &= 0377;
+       if (s != 0 && s != SIGPIPE) {
+               fprintf(stderr, "\"Echo\" failed\n");
+               return(NOSTR);
+       }
+       if (l < 0) {
+               perror("read");
+               return(NOSTR);
+       }
+       if (l == 0) {
+               fprintf(stderr, "\"%s\": No match\n", name);
+               return(NOSTR);
+       }
+       if (l == BUFSIZ) {
+               fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name);
+               return(NOSTR);
+       }
+       xname[l] = 0;
+       for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
+               ;
+       *++cp = '\0';
+       return(xname);
+}
+
+/*
+ * Are any of the characters in the two strings the same?
+ */
+
+anyof(s1, s2)
+       register char *s1, *s2;
+{
+       register int c;
+
+       while (c = *s1++)
+               if (any(c, s2))
+                       return(1);
+       return(0);
+}