BSD 4_4 release
[unix-history] / usr / src / usr.bin / tip / cmds.c
index 575b780..63bfee2 100644 (file)
@@ -1,8 +1,43 @@
+/*
+ * Copyright (c) 1983, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * 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     4.12 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)cmds.c     8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
 
 #include "tip.h"
 
 #include "tip.h"
+#include "pathnames.h"
+
 /*
  * tip
  *
 /*
  * tip
  *
@@ -15,10 +50,9 @@ char null = '\0';
 char   *sep[] = { "second", "minute", "hour" };
 static char *argv[10];         /* argument vector for take and put */
 
 char   *sep[] = { "second", "minute", "hour" };
 static char *argv[10];         /* argument vector for take and put */
 
-int    timeout();              /* timeout function called on alarm */
-int    stopsnd();              /* SIGINT handler during file transfers */
-int    intprompt();            /* used in handling SIG_INT during prompt */
-int    intcopy();              /* interrupt routine for file transfers */
+void   timeout();              /* timeout function called on alarm */
+void   stopsnd();              /* SIGINT handler during file transfers */
+void   intcopy();              /* interrupt routine for file transfers */
 
 /*
  * FTP - remote ==> local
 
 /*
  * FTP - remote ==> local
@@ -90,7 +124,8 @@ 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)();
+       sig_t f;
+       char r;
 
        pwrite(FD, buf, size(buf));
        quit = 0;
 
        pwrite(FD, buf, size(buf));
        quit = 0;
@@ -100,15 +135,16 @@ transfer(buf, fd, eofchars)
        /*
         * finish command
         */
        /*
         * finish command
         */
-       pwrite(FD, "\r", 1);
+       r = '\r';
+       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);
        
+       (void) setjmp(intbuf);
        f = signal(SIGINT, intcopy);
        start = time(0);
        f = signal(SIGINT, intcopy);
        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;
@@ -140,7 +176,7 @@ transfer(buf, fd, eofchars)
                prtime(" lines transferred in ", time(0)-start);
        ioctl(0, TIOCSETC, &tchars);
        write(fildes[1], (char *)&ccc, 1);
                prtime(" lines transferred in ", time(0)-start);
        ioctl(0, TIOCSETC, &tchars);
        write(fildes[1], (char *)&ccc, 1);
-       signal(SIGINT, SIG_DFL);
+       signal(SIGINT, f);
        close(fd);
 }
 
        close(fd);
 }
 
@@ -194,6 +230,7 @@ pipefile()
 /*
  * Interrupt service routine for FTP
  */
 /*
  * Interrupt service routine for FTP
  */
+void
 stopsnd()
 {
 
 stopsnd()
 {
 
@@ -248,10 +285,11 @@ transmit(fd, eofchars, command)
        char *pc, lastc;
        int c, ccount, lcount;
        time_t start_t, stop_t;
        char *pc, lastc;
        int c, ccount, lcount;
        time_t start_t, stop_t;
+       sig_t f;
 
        kill(pid, SIGIOT);      /* put TIPOUT into a wait state */
 
        kill(pid, SIGIOT);      /* put TIPOUT into a wait state */
-       signal(SIGINT, stopsnd);
        stop = 0;
        stop = 0;
+       f = signal(SIGINT, stopsnd);
        ioctl(0, TIOCSETC, &defchars);
        read(repdes[0], (char *)&ccc, 1);
        if (command != NULL) {
        ioctl(0, TIOCSETC, &defchars);
        read(repdes[0], (char *)&ccc, 1);
        if (command != NULL) {
@@ -304,8 +342,8 @@ transmit(fd, eofchars, command)
                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(value(ETIMEOUT));
                        timedout = 0;
                        timedout = 0;
+                       alarm((int)value(ETIMEOUT));
                        do {    /* wait for prompt */
                                read(FD, (char *)&c, 1);
                                if (timedout || stop) {
                        do {    /* wait for prompt */
                                read(FD, (char *)&c, 1);
                                if (timedout || stop) {
@@ -325,7 +363,7 @@ out:
                send(*pc);
        stop_t = time(0);
        fclose(fd);
                send(*pc);
        stop_t = time(0);
        fclose(fd);
-       signal(SIGINT, SIG_DFL);
+       signal(SIGINT, f);
        if (boolean(value(VERBOSE)))
                if (boolean(value(RAWFTP)))
                        prtime(" chars transferred in ", stop_t-start_t);
        if (boolean(value(VERBOSE)))
                if (boolean(value(RAWFTP)))
                        prtime(" chars transferred in ", stop_t-start_t);
@@ -392,7 +430,7 @@ send(c)
        }
 tryagain:
        timedout = 0;
        }
 tryagain:
        timedout = 0;
-       alarm(value(ETIMEOUT));
+       alarm((int)value(ETIMEOUT));
        read(FD, &cc, 1);
        alarm(0);
        if (timedout) {
        read(FD, &cc, 1);
        alarm(0);
        if (timedout) {
@@ -404,20 +442,67 @@ tryagain:
        }
 }
 
        }
 }
 
+void
 timeout()
 {
        signal(SIGALRM, timeout);
        timedout = 1;
 }
 
 timeout()
 {
        signal(SIGALRM, timeout);
        timedout = 1;
 }
 
+/*
+ * Stolen from consh() -- puts a remote file on the output of a local command.
+ *     Identical to consh() except for where stdout goes.
+ */
+pipeout(c)
+{
+       char buf[256];
+       int cpid, status, p;
+       time_t start;
+
+       putchar(c);
+       if (prompt("Local command? ", buf))
+               return;
+       kill(pid, SIGIOT);      /* put TIPOUT into a wait state */
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       ioctl(0, TIOCSETC, &defchars);
+       read(repdes[0], (char *)&ccc, 1);
+       /*
+        * Set up file descriptors in the child and
+        *  let it go...
+        */
+       if ((cpid = fork()) < 0)
+               printf("can't fork!\r\n");
+       else if (cpid) {
+               start = time(0);
+               while ((p = wait(&status)) > 0 && p != cpid)
+                       ;
+       } else {
+               register int i;
+
+               dup2(FD, 1);
+               for (i = 3; i < 20; i++)
+                       close(i);
+               signal(SIGINT, SIG_DFL);
+               signal(SIGQUIT, SIG_DFL);
+               execute(buf);
+               printf("can't find `%s'\r\n", buf);
+               exit(0);
+       }
+       if (boolean(value(VERBOSE)))
+               prtime("away for ", time(0)-start);
+       write(fildes[1], (char *)&ccc, 1);
+       ioctl(0, TIOCSETC, &tchars);
+       signal(SIGINT, SIG_DFL);
+       signal(SIGQUIT, SIG_DFL);
+}
+
 #ifdef CONNECT
 /*
  * Fork a program with:
 #ifdef CONNECT
 /*
  * Fork a program with:
- *  0 <-> local tty in
- *  1 <-> local tty out
+ *  0 <-> remote tty in
+ *  1 <-> remote tty out
  *  2 <-> local tty out
  *  2 <-> local tty out
- *  3 <-> remote tty in
- *  4 <-> remote tty out
  */
 consh(c)
 {
  */
 consh(c)
 {
@@ -446,9 +531,9 @@ consh(c)
        } else {
                register int i;
 
        } else {
                register int i;
 
-               dup2(FD, 3);
-               dup2(3, 4);
-               for (i = 5; i < 20; i++)
+               dup2(FD, 0);
+               dup2(3, 1);
+               for (i = 3; i < 20; i++)
                        close(i);
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
                        close(i);
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
@@ -492,6 +577,7 @@ shell()
                        cp = value(SHELL);
                else
                        cp++;
                        cp = value(SHELL);
                else
                        cp++;
+               shell_uid();
                execl(value(SHELL), cp, 0);
                printf("\r\ncan't execl!\r\n");
                exit(1);
                execl(value(SHELL), cp, 0);
                printf("\r\ncan't execl!\r\n");
                exit(1);
@@ -539,25 +625,35 @@ chdirectory()
        printf("!\r\n");
 }
 
        printf("!\r\n");
 }
 
+tipabort(msg)
+       char *msg;
+{
+
+       kill(pid, SIGTERM);
+       disconnect(msg);
+       if (msg != NOSTR)
+               printf("\r\n%s", msg);
+       printf("\r\n[EOT]\r\n");
+       daemon_uid();
+       (void)uu_unlock(uucplock);
+       unraw();
+       exit(0);
+}
+
 finish()
 {
        char *dismsg;
 
        if ((dismsg = value(DISCONNECT)) != NOSTR) {
 finish()
 {
        char *dismsg;
 
        if ((dismsg = value(DISCONNECT)) != NOSTR) {
-               write(FD,dismsg,strlen(dismsg));
+               write(FD, dismsg, strlen(dismsg));
                sleep(5);
        }
                sleep(5);
        }
-       kill(pid, SIGTERM);
-       disconnect();
-       printf("\r\n[EOT]\r\n");
-       delock(uucplock);
-       unraw();
-       exit(0);
+       tipabort(NOSTR);
 }
 
 }
 
+void
 intcopy()
 {
 intcopy()
 {
-
        raw();
        quit = 1;
        longjmp(intbuf, 1);
        raw();
        quit = 1;
        longjmp(intbuf, 1);
@@ -572,6 +668,7 @@ execute(s)
                cp = value(SHELL);
        else
                cp++;
                cp = value(SHELL);
        else
                cp++;
+       shell_uid();
        execl(value(SHELL), cp, "-c", s, 0);
 }
 
        execl(value(SHELL), cp, "-c", s, 0);
 }
 
@@ -612,7 +709,7 @@ prtime(s, a)
        }
        printf("%s", s);
        while (--i >= 0)
        }
        printf("%s", s);
        while (--i >= 0)
-               if (nums[i])
+               if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0)
                        printf("%d %s%c ", nums[i], sep[i],
                                nums[i] == 1 ? '\0' : 's');
        printf("\r\n!\r\n");
                        printf("%d %s%c ", nums[i], sep[i],
                                nums[i] == 1 ? '\0' : 's');
        printf("\r\n!\r\n");
@@ -695,11 +792,12 @@ genbrk()
 /*
  * Suspend tip
  */
 /*
  * Suspend tip
  */
-suspend()
+suspend(c)
+       char c;
 {
 
        unraw();
 {
 
        unraw();
-       kill(0, SIGTSTP);
+       kill(c == CTRL('y') ? getpid() : 0, SIGTSTP);
        raw();
 }
 
        raw();
 }
 
@@ -729,12 +827,13 @@ expand(name)
        if ((pid = vfork()) == 0) {
                Shell = value(SHELL);
                if (Shell == NOSTR)
        if ((pid = vfork()) == 0) {
                Shell = value(SHELL);
                if (Shell == NOSTR)
-                       Shell = "/bin/sh";
+                       Shell = _PATH_BSHELL;
                close(pivec[0]);
                close(1);
                dup(pivec[1]);
                close(pivec[1]);
                close(2);
                close(pivec[0]);
                close(1);
                dup(pivec[1]);
                close(pivec[1]);
                close(2);
+               shell_uid();
                execl(Shell, Shell, "-c", cmdbuf, 0);
                _exit(1);
        }
                execl(Shell, Shell, "-c", cmdbuf, 0);
                _exit(1);
        }