check for error on socket()
[unix-history] / usr / src / usr.bin / uucp / uucico / cico.c
index ed60920..db7fb33 100644 (file)
@@ -1,50 +1,74 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)cico.c     5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)cico.c     5.10 (Berkeley) %G%";
 #endif
 
 #endif
 
-#include "uucp.h"
 #include <signal.h>
 #include <signal.h>
+#include "uucp.h"
 #include <setjmp.h>
 #include <setjmp.h>
-#include <sys/types.h>
-#ifdef SYSIII
+#ifdef USG
 #include <termio.h>
 #endif
 #include <termio.h>
 #endif
-#ifndef        SYSIII
+#ifndef        USG
 #include <sgtty.h>
 #endif
 #include <sgtty.h>
 #endif
+#ifdef BSDTCP
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif BSDTCP
+#include <sys/stat.h>
+#include "uust.h"
+#include "uusub.h"
+
+#if defined(VMS) && defined(BSDTCP)
+#define NOGETPEER
+#endif
 
 
-
-#ifdef UNET
-#include <UNET/unetio.h>
-#include <UNET/tcp.h>
-static struct uiocstate ust;
+#ifdef BSD2_9
+#define NOGETPEER
 #endif
 
 jmp_buf Sjbuf;
 #endif
 
 jmp_buf Sjbuf;
-       /*  call fail text  */
+jmp_buf Pipebuf;
+
+/*  call fail text  */
 char *Stattext[] = {
        "",
        "BAD SYSTEM",
 char *Stattext[] = {
        "",
        "BAD SYSTEM",
-       "WRONG TIME",
+       "WRONG TIME TO CALL",
        "SYSTEM LOCKED",
        "NO DEVICE",
        "DIAL FAILED",
        "LOGIN FAILED",
        "BAD SEQUENCE"
        "SYSTEM LOCKED",
        "NO DEVICE",
        "DIAL FAILED",
        "LOGIN FAILED",
        "BAD SEQUENCE"
-       };
-
-int Role = 0;
-       /*  call fail codes  */
-int Stattype[] = {0, 0, 0, 0,
-       SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ
-       };
-
-
-int Errorrate = 0;
-#ifdef SYSIII
+};
+
+/*  call fail codes  */
+int Stattype[] = {
+       0,
+       0,
+       SS_WRONGTIME,
+       0,
+       SS_NODEVICE,
+       SS_FAIL,
+       SS_FAIL,
+       SS_BADSEQ
+};
+
+
+int ReverseRole = 0;
+int StdErrIsTty = 0;
+int Role = SLAVE;
+int onesys = 0;
+int turntime = 30 * 60;        /* 30 minutes expressed in seconds */
+extern int LocalOnly;
+extern char MaxGrade, DefMaxGrade;
+extern char Myfullname[];
+
+#ifdef USG
 struct termio Savettyb;
 #endif
 struct termio Savettyb;
 #endif
-#ifndef        SYSIII
+#ifndef        USG
 struct sgttyb Savettyb;
 #endif
 
 struct sgttyb Savettyb;
 #endif
 
@@ -58,32 +82,19 @@ register char *argv[];
 {
        register int ret;
        int seq;
 {
        register int ret;
        int seq;
-       int onesys = 0;
        char wkpre[NAMESIZE], file[NAMESIZE];
        char wkpre[NAMESIZE], file[NAMESIZE];
-       char msg[BUFSIZ], *q;
+       char msg[MAXFULLNAME], *q, **alias;
        register char *p;
        extern onintr(), timeout(), setdebug();
        register char *p;
        extern onintr(), timeout(), setdebug();
-       extern intrEXIT();
        extern char *pskip();
        extern char *pskip();
-       char rflags[30];
+       char rflags[MAXFULLNAME];
        char *ttyn;
        char *ttyn;
-       int orig_uid = getuid();
+#ifdef NOGETPEER
+       u_long Hostnumber = 0;
+#endif NOGETPEER
 
        strcpy(Progname, "uucico");
 
        strcpy(Progname, "uucico");
-       uucpname(Myname);
-
-       /* Try to run as uucp -- rti!trt */
-       setgid(getegid());
-       setuid(geteuid());
 
 
-       signal(SIGILL, intrEXIT);
-       signal(SIGTRAP, intrEXIT);
-       signal(SIGIOT, intrEXIT);
-       signal(SIGEMT, intrEXIT);
-       signal(SIGFPE, intrEXIT);
-       signal(SIGBUS, intrEXIT);
-       signal(SIGSEGV, intrEXIT);
-       signal(SIGSYS, intrEXIT);
        signal(SIGINT, onintr);
        signal(SIGHUP, onintr);
        signal(SIGQUIT, onintr);
        signal(SIGINT, onintr);
        signal(SIGHUP, onintr);
        signal(SIGQUIT, onintr);
@@ -92,9 +103,12 @@ register char *argv[];
        signal(SIGFPE, setdebug);
        ret = guinfo(getuid(), User, msg);
        strcpy(Loginuser, User);
        signal(SIGFPE, setdebug);
        ret = guinfo(getuid(), User, msg);
        strcpy(Loginuser, User);
-       ASSERT(ret == 0, "BAD UID ", "", ret);
+       uucpname(Myname);
+       ASSERT(ret == 0, "BAD UID", CNULL, ret);
 
 
-       rflags[0] = '\0';
+#ifdef BSD4_2
+       setlinebuf(stderr);
+#endif
        umask(WFMASK);
        strcpy(Rmtname, Myname);
        Ifn = Ofn = -1;
        umask(WFMASK);
        strcpy(Rmtname, Myname);
        Ifn = Ofn = -1;
@@ -103,105 +117,151 @@ register char *argv[];
                case 'd':
                        Spool = &argv[1][2];
                        break;
                case 'd':
                        Spool = &argv[1][2];
                        break;
-#ifdef PROTODEBUG
-               case 'E':
-                       Errorrate = atoi(&argv[1][2]);
-                       if (Errorrate <= 0)
-                               Errorrate = 100;
-                       break;
                case 'g':
                case 'g':
-                       Pkdrvon = 1;
+               case 'p':
+                       MaxGrade = DefMaxGrade = argv[1][2];
                        break;
                        break;
-               case 'G':
-                       Pkdrvon = 1;
-                       strcat(rflags, " -g ");
-                       break;
-#endif
                case 'r':
                        Role = atoi(&argv[1][2]);
                        break;
                case 'r':
                        Role = atoi(&argv[1][2]);
                        break;
+               case 'R':
+                       ReverseRole++;
+                       Role = MASTER;
+                       break;
                case 's':
                case 's':
-                       sprintf(Rmtname, "%.7s", &argv[1][2]);
+                       strncpy(Rmtname, &argv[1][2], MAXBASENAME);
+                       Rmtname[MAXBASENAME] = '\0';
                        if (Rmtname[0] != '\0')
                                onesys = 1;
                        break;
                case 'x':
                        if (Rmtname[0] != '\0')
                                onesys = 1;
                        break;
                case 'x':
-                       chkdebug(orig_uid);
+                       chkdebug();
                        Debug = atoi(&argv[1][2]);
                        if (Debug <= 0)
                                Debug = 1;
                        Debug = atoi(&argv[1][2]);
                        if (Debug <= 0)
                                Debug = 1;
-                       strcat(rflags, argv[1]);
                        logent("ENABLED", "DEBUG");
                        break;
                        logent("ENABLED", "DEBUG");
                        break;
+               case 't':
+                       turntime = atoi(&argv[1][2])*60;/* minutes to seconds */
+                       break;
+               case 'L':       /* local calls only */
+                       LocalOnly++;
+                       break;
+#ifdef NOGETPEER
+               case 'h':
+                       Hostnumber = inet_addr(&argv[1][2]);
+                       break;
+#endif NOGETPEER
                default:
                default:
-                       printf("unknown flag %s\n", argv[1]);
+                       printf("unknown flag %s (ignored)\n", argv[1]);
                        break;
                }
                --argc;  argv++;
        }
 
                        break;
                }
                --argc;  argv++;
        }
 
-       subchdir(Spool);
-       strcpy(Wrkdir, Spool);
+       while (argc > 1) {
+               printf("unknown argument %s (ignored)\n", argv[1]);
+               --argc; argv++;
+       }
 
 
-#ifdef UNET
-/*
- * Determine if we are on UNET
- */
-       ret = ioctl(0, UIOCSTATE, &ust);
-       if (ret == 0) {
-               Unet = 1;
-               DEBUG(4, "UNET connection -- ioctl-s disabled\n", "");
+       /* Try to run as uucp */
+       setgid(getegid());
+       setuid(geteuid());
+#ifdef TIOCNOTTY
+       /*
+        * detach uucico from controlling terminal
+        * to defend against rlogind sending us a SIGKILL (!!!)
+        */
+       if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) {
+               ioctl(ret, TIOCNOTTY, STBNULL);
+               close(ret);
        }
        }
-#endif
+#endif TIOCNOTTY
+#ifdef BSD4_2
+       if (getpgrp(0) == 0) { /* We have no controlling terminal */
+               setpgrp(0, getpid());
+       }
+#endif BSD4_2
+
+       ret = subchdir(Spool);
+       ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret);
+       strcpy(Wrkdir, Spool);
+
        if (Role == SLAVE) {
        if (Role == SLAVE) {
+               /* check for /etc/nologin */
+               if (access(NOLOGIN, 0) == 0) {
+                       logent(NOLOGIN, "UUCICO SHUTDOWN");
+                       if (Debug > 4)
+                               logent("DEBUGGING", "continuing anyway");
+                       else
+                               cleanup(1);
+               }
+#ifdef TCPIP
+               /*
+                * Determine if we are on TCPIP
+                */
+               if (isatty(0) ==  0) {
+                       IsTcpIp = 1;
+                       DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
+               } else
+                       IsTcpIp = 0;
+#endif TCPIP
                /* initial handshake */
                onesys = 1;
                /* initial handshake */
                onesys = 1;
-               if (!Unet) {
-#ifdef SYSIII
+               if (!IsTcpIp) {
+#ifdef USG
                        ret = ioctl(0, TCGETA, &Savettyb);
                        Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
                        Savettyb.c_oflag |= OPOST;
                        Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
                        ret = ioctl(0, TCGETA, &Savettyb);
                        Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
                        Savettyb.c_oflag |= OPOST;
                        Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
-#endif
-#ifndef        SYSIII
+#else !USG
                        ret = ioctl(0, TIOCGETP, &Savettyb);
                        Savettyb.sg_flags |= ECHO;
                        Savettyb.sg_flags &= ~RAW;
                        ret = ioctl(0, TIOCGETP, &Savettyb);
                        Savettyb.sg_flags |= ECHO;
                        Savettyb.sg_flags &= ~RAW;
-#endif
+#endif !USG
                }
                Ifn = 0;
                Ofn = 1;
                fixmode(Ifn);
                }
                Ifn = 0;
                Ofn = 1;
                fixmode(Ifn);
-               fclose(stderr);
-               fopen(RMTDEBUG, "w");
-               omsg('S', "here", Ofn);
+               getbaud(Ifn);
+               sprintf(file,"%s/%d", RMTDEBUG, getpid());
+#ifdef VMS
+               /* hold the version number down */
+               unlink(file);
+#endif VMS
+               freopen(file, "w", stderr);
+#ifdef BSD4_2
+               setlinebuf(stderr);
+#else  !BSD4_2
+               setbuf(stderr, NULL);
+#endif !BSD4_2
+               sprintf(msg, "here=%s", Myfullname);
+               omsg('S', msg, Ofn);
                signal(SIGALRM, timeout);
                alarm(MAXMSGTIME);
                if (setjmp(Sjbuf)) {
                        /* timed out */
                signal(SIGALRM, timeout);
                alarm(MAXMSGTIME);
                if (setjmp(Sjbuf)) {
                        /* timed out */
-                       if (!Unet) {
-#ifdef SYSIII
+                       if (!IsTcpIp) {
+#ifdef USG
                                ret = ioctl(0, TCSETA, &Savettyb);
                                ret = ioctl(0, TCSETA, &Savettyb);
-#endif
-#ifndef        SYSIII
+#else  !USG
                                ret = ioctl(0, TIOCSETP, &Savettyb);
                                ret = ioctl(0, TIOCSETP, &Savettyb);
-#endif
+#endif !USG
                        }
                        }
-                       exit(0);
+                       cleanup(0);
                }
                for (;;) {
                        ret = imsg(msg, Ifn);
                        if (ret != 0) {
                                alarm(0);
                }
                for (;;) {
                        ret = imsg(msg, Ifn);
                        if (ret != 0) {
                                alarm(0);
-                               if (!Unet) {
-#ifdef SYSIII
+                               if (!IsTcpIp) {
+#ifdef USG
                                        ret = ioctl(0, TCSETA, &Savettyb);
                                        ret = ioctl(0, TCSETA, &Savettyb);
-#endif
-#ifndef        SYSIII
+#else  !USG
                                        ret = ioctl(0, TIOCSETP, &Savettyb);
                                        ret = ioctl(0, TIOCSETP, &Savettyb);
-#endif
+#endif !USG
                                }
                                }
-                               exit(0);
+                               cleanup(0);
                        }
                        if (msg[0] == 'S')
                                break;
                        }
                        if (msg[0] == 'S')
                                break;
@@ -209,9 +269,88 @@ register char *argv[];
                alarm(0);
                q = &msg[1];
                p = pskip(q);
                alarm(0);
                q = &msg[1];
                p = pskip(q);
-               sprintf(Rmtname, "%.7s", q);
+               strncpy(Rmtname, q, MAXBASENAME);
+               Rmtname[MAXBASENAME] = '\0';
+               sprintf(wkpre,"%s/%s", RMTDEBUG, Rmtname);
+               unlink(wkpre);
+               if (link(file, wkpre) == 0)
+                       unlink(file);
                DEBUG(4, "sys-%s\n", Rmtname);
                DEBUG(4, "sys-%s\n", Rmtname);
-               if (mlock(Rmtname)) {
+               /* The versys will also do an alias on the incoming name */
+               if (versys(&Rmtname)) {
+                       /* If we don't know them, we won't talk to them... */
+#ifdef NOSTRANGERS
+                       logent(Rmtname, "UNKNOWN HOST");
+                       omsg('R', "You are unknown to me", Ofn);
+                       cleanup(0);
+#endif NOSTRANGERS
+               }
+#ifdef BSDTCP
+               /* we must make sure they are really who they say they
+                * are. We compare the hostnumber with the number in the hosts
+                * table for the site they claim to be.
+                */
+               if (IsTcpIp) {
+                       struct hostent *hp;
+                       char *cpnt, *inet_ntoa();
+                       int len;
+                       struct sockaddr_in from;
+                       extern char PhoneNumber[];
+
+#ifdef NOGETPEER
+                       from.sin_addr.s_addr = Hostnumber;
+                       from.sin_family = AF_INET;
+#else  !NOGETPEER
+                       len = sizeof(from);
+                       if (getpeername(0, &from, &len) < 0) {
+                               logent(Rmtname, "NOT A TCP CONNECTION");
+                               omsg('R', "NOT TCP", Ofn);
+                               cleanup(0);
+                       }
+#endif !NOGETPEER
+                       hp = gethostbyaddr(&from.sin_addr,
+                               sizeof (struct in_addr), from.sin_family);
+                       if (hp == 0) {
+                               /* security break or just old host table? */
+                               logent(Rmtname, "UNKNOWN IP-HOST Name =");
+                               cpnt = inet_ntoa(from.sin_addr),
+                               logent(cpnt, "UNKNOWN IP-HOST Number =");
+                               sprintf(wkpre, "%s/%s isn't in my host table",
+                                       Rmtname, cpnt);
+                               omsg('R' ,wkpre ,Ofn);
+                               cleanup(0);
+                       }
+                       if (Debug>99)
+                               logent(Rmtname,"Request from IP-Host name =");
+                       /*
+                        * The following is to determine if the name given us by
+                        * the Remote uucico matches any of the names
+                        * given its network number (remote machine) in our
+                        * host table.
+                        * We could check the aliases, but that won't work in
+                        * all cases (like if you are running the domain
+                        * server, where you don't get any aliases). The only
+                        * reliable way I can think of that works in ALL cases
+                        * is too look up the site in L.sys and see if the
+                        * sitename matches what we would call him if we
+                        * originated the call.
+                        */
+                       /* PhoneNumber contains the official network name of the                           host we are checking. (set in versys.c) */
+                       if (sncncmp(PhoneNumber, hp->h_name, SYSNSIZE) == 0) {
+                               if (Debug > 99)
+                                       logent(q,"Found in host Tables");
+                       } else {
+                               logent(hp->h_name, "FORGED HOSTNAME");
+                               logent(inet_ntoa(from.sin_addr), "ORIGINATED AT");
+                               logent(PhoneNumber, "SHOULD BE");
+                               sprintf(wkpre, "You're not who you claim to be: %s !=  %s", hp->h_name, PhoneNumber);
+                               omsg('R', wkpre, Ofn);
+                               cleanup(0);
+                       }
+               }
+#endif BSDTCP
+
+               if (mlock(Rmtname) == FAIL) {
                        omsg('R', "LCK", Ofn);
                        cleanup(0);
                }
                        omsg('R', "LCK", Ofn);
                        cleanup(0);
                }
@@ -221,7 +360,7 @@ register char *argv[];
                        omsg('R', "CB", Ofn);
                        logent("CALLBACK", "REQUIRED");
                        /*  set up for call back  */
                        omsg('R', "CB", Ofn);
                        logent("CALLBACK", "REQUIRED");
                        /*  set up for call back  */
-                       systat(Rmtname, SS_CALLBACK, "CALL BACK");
+                       systat(Rmtname, SS_CALLBACK, "CALLING BACK");
                        gename(CMDPRE, Rmtname, 'C', file);
                        close(creat(subfile(file), 0666));
                        xuucico(Rmtname);
                        gename(CMDPRE, Rmtname, 'C', file);
                        close(creat(subfile(file), 0666));
                        xuucico(Rmtname);
@@ -231,9 +370,6 @@ register char *argv[];
                while (*p == '-') {
                        q = pskip(p);
                        switch(*(++p)) {
                while (*p == '-') {
                        q = pskip(p);
                        switch(*(++p)) {
-                       case 'g':
-                               Pkdrvon = 1;
-                               break;
                        case 'x':
                                Debug = atoi(++p);
                                if (Debug <= 0)
                        case 'x':
                                Debug = atoi(++p);
                                if (Debug <= 0)
@@ -242,6 +378,17 @@ register char *argv[];
                        case 'Q':
                                seq = atoi(++p);
                                break;
                        case 'Q':
                                seq = atoi(++p);
                                break;
+                       case 'p':
+                               MaxGrade = DefMaxGrade = *++p;
+                               DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
+                               break;
+                       case 'v':
+                               if (strncmp(p, "grade", 5) == 0) {
+                                       p += 6;
+                                       MaxGrade = DefMaxGrade = *p++;
+                                       DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
+                               }
+                               break;
                        default:
                                break;
                        }
                        default:
                                break;
                        }
@@ -252,45 +399,78 @@ register char *argv[];
                        omsg('R', "BADSEQ", Ofn);
                        cleanup(0);
                }
                        omsg('R', "BADSEQ", Ofn);
                        cleanup(0);
                }
+#ifdef GNXSEQ
                if ((ret = gnxseq(Rmtname)) == seq) {
                        omsg('R', "OK", Ofn);
                        cmtseq();
                if ((ret = gnxseq(Rmtname)) == seq) {
                        omsg('R', "OK", Ofn);
                        cmtseq();
-               }
+               } else {
+#else !GNXSEQ
+               if (seq == 0)
+                       omsg('R', "OK", Ofn);
                else {
                else {
+#endif !GNXSEQ
                        systat(Rmtname, Stattype[7], Stattext[7]);
                        systat(Rmtname, Stattype[7], Stattext[7]);
-                       logent("BAD SEQ", "HANDSHAKE FAILED");
+                       logent("BAD SEQ", "FAILED HANDSHAKE");
+#ifdef GNXSEQ
                        ulkseq();
                        ulkseq();
+#endif GNXSEQ
                        omsg('R', "BADSEQ", Ofn);
                        cleanup(0);
                }
                ttyn = ttyname(Ifn);
                if (ttyn != NULL)
                        chmod(ttyn, 0600);
                        omsg('R', "BADSEQ", Ofn);
                        cleanup(0);
                }
                ttyn = ttyname(Ifn);
                if (ttyn != NULL)
                        chmod(ttyn, 0600);
+       } else { /* Role == MASTER */
+               struct stat stbuf;
+               if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0
+                   && stbuf.st_mode&S_IFREG) )
+                       StdErrIsTty =  1;
+               setdebug(0);
        }
        }
+
 loop:
 loop:
+       if(setjmp(Pipebuf)) {   /* come here on SIGPIPE */
+               clsacu();
+               close(Ofn);
+               close(Ifn);
+               Ifn = Ofn = -1;
+               rmlock(CNULL);
+               sleep(3);
+       }
        if (!onesys) {
        if (!onesys) {
+               struct stat sbuf;
+
+               if (!StdErrIsTty) {
+                       sprintf(file, "%s/%s", RMTDEBUG, Rmtname);
+                       if (stat(file, &sbuf) == 0 && sbuf.st_size == 0)
+                               unlink(file);
+               }
                ret = gnsys(Rmtname, Spool, CMDPRE);
                ret = gnsys(Rmtname, Spool, CMDPRE);
+               setdebug(0);
                if (ret == FAIL)
                        cleanup(100);
                if (ret == FAIL)
                        cleanup(100);
-               if (ret == 0)
+               if (ret == SUCCESS)
                        cleanup(0);
                        cleanup(0);
-       }
-       else if (Role == MASTER && callok(Rmtname) != 0) {
+       } else if (Role == MASTER && callok(Rmtname) != 0) {
                logent("SYSTEM STATUS", "CAN NOT CALL");
                cleanup(0);
        }
 
                logent("SYSTEM STATUS", "CAN NOT CALL");
                cleanup(0);
        }
 
-       sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname);
+       sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname);
 
 
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
        if (Role == MASTER) {
        if (Role == MASTER) {
+               /* check for /etc/nologin */
+               if (access(NOLOGIN, 0) == 0) {
+                       logent(NOLOGIN, "UUCICO SHUTDOWN");
+                       if (Debug > 4)
+                               logent("DEBUGGING", "continuing anyway");
+                       else
+                               cleanup(1);
+               }
                /*  master part */
                /*  master part */
-               signal(SIGINT, SIG_IGN);
                signal(SIGHUP, SIG_IGN);
                signal(SIGHUP, SIG_IGN);
-               signal(SIGQUIT, SIG_IGN);
-               if (!iswrk(file, "chk", Spool, wkpre) && !onesys) {
-                       logent(Rmtname, "NO WORK");
-                       goto next;
-               }
                if (Ifn != -1 && Role == MASTER) {
                        write(Ofn, EOTMSG, strlen(EOTMSG));
                        clsacu();
                if (Ifn != -1 && Role == MASTER) {
                        write(Ofn, EOTMSG, strlen(EOTMSG));
                        clsacu();
@@ -301,21 +481,38 @@ loop:
                        sleep(3);
                }
                sprintf(msg, "call to %s ", Rmtname);
                        sleep(3);
                }
                sprintf(msg, "call to %s ", Rmtname);
-               if (mlock(Rmtname) != 0) {
+               if (mlock(Rmtname) != SUCCESS) {
                        logent(msg, "LOCKED");
                        logent(msg, "LOCKED");
+                       US_SST(us_s_lock);
                        goto next;
                }
                Ofn = Ifn = conn(Rmtname);
                if (Ofn < 0) {
                        goto next;
                }
                Ofn = Ifn = conn(Rmtname);
                if (Ofn < 0) {
-                       logent(msg, "FAILED");
-                       systat(Rmtname, Stattype[-Ofn],
-                               Stattext[-Ofn]);
+                       if (Ofn != CF_TIME)
+                               logent(msg, _FAILED);
+                       /* avoid excessive 'wrong time' info */
+                       if (Stattype[-Ofn] != SS_WRONGTIME){
+                               systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]);
+                               US_SST(-Ofn);
+                               UB_SST(-Ofn);
+                       }
                        goto next;
                        goto next;
-               }
-               else {
+               } else {
                        logent(msg, "SUCCEEDED");
                        logent(msg, "SUCCEEDED");
+                       US_SST(us_s_cok);
+                       UB_SST(ub_ok);
                }
                }
-       
+#ifdef TCPIP
+               /*
+                * Determine if we are on TCPIP
+                */
+               if (isatty(Ifn) ==  0) {
+                       IsTcpIp = 1;
+                       DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
+               } else
+                       IsTcpIp = 0;
+#endif
+
                if (setjmp(Sjbuf))
                        goto next;
                signal(SIGALRM, timeout);
                if (setjmp(Sjbuf))
                        goto next;
                signal(SIGALRM, timeout);
@@ -324,24 +521,43 @@ loop:
                        ret = imsg(msg, Ifn);
                        if (ret != 0) {
                                alarm(0);
                        ret = imsg(msg, Ifn);
                        if (ret != 0) {
                                alarm(0);
-                               logent("imsg 1", "FAILED");
-                               goto next;
+                               logent("imsg 1", _FAILED);
+                               goto Failure;
                        }
                        if (msg[0] == 'S')
                                break;
                }
                alarm(MAXMSGTIME);
                        }
                        if (msg[0] == 'S')
                                break;
                }
                alarm(MAXMSGTIME);
+#ifdef GNXSEQ
                seq = gnxseq(Rmtname);
                seq = gnxseq(Rmtname);
-               sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags);
+#else !GNXSEQ
+               seq = 0;
+#endif !GNXSEQ
+               if (Debug)
+                       sprintf(rflags, "-x%d", Debug);
+               else
+                       rflags[0] = '\0';
+
+               if (MaxGrade != '\177') {
+                       char buf[MAXFULLNAME];
+                       sprintf(buf, " -p%c -vgrade=%c", MaxGrade, MaxGrade);
+                       strcat(rflags, buf);
+               }
+
+               sprintf(msg, "%s -Q%d %s", Myname, seq, rflags);
+               if (MaxGrade != '\177')
+                       DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade);
                omsg('S', msg, Ofn);
                for (;;) {
                        ret = imsg(msg, Ifn);
                        DEBUG(4, "msg-%s\n", msg);
                omsg('S', msg, Ofn);
                for (;;) {
                        ret = imsg(msg, Ifn);
                        DEBUG(4, "msg-%s\n", msg);
-                       if (ret != 0) {
+                       if (ret != SUCCESS) {
                                alarm(0);
                                alarm(0);
+#ifdef GNXSEQ
                                ulkseq();
                                ulkseq();
-                               logent("imsg 2", "FAILED");
-                               goto next;
+#endif GNXSEQ
+                               logent("imsg 2", _FAILED);
+                               goto Failure;
                        }
                        if (msg[0] == 'R')
                                break;
                        }
                        if (msg[0] == 'R')
                                break;
@@ -349,53 +565,66 @@ loop:
                alarm(0);
                if (msg[1] == 'B') {
                        /* bad sequence */
                alarm(0);
                if (msg[1] == 'B') {
                        /* bad sequence */
-                       logent("BAD SEQ", "HANDSHAKE FAILED");
-                       systat(Rmtname, Stattype[7], Stattext[7]);
+                       logent("BAD SEQ", "FAILED HANDSHAKE");
+                       US_SST(us_s_hand);
+                       systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]);
+#ifdef GNXSEQ
                        ulkseq();
                        ulkseq();
+#endif GNXSEQ
                        goto next;
                }
                if (strcmp(&msg[1], "OK") != SAME)  {
                        goto next;
                }
                if (strcmp(&msg[1], "OK") != SAME)  {
-                       logent(&msg[1], "HANDSHAKE FAILED");
+                       logent(&msg[1], "FAILED HANDSHAKE");
+                       US_SST(us_s_hand);
+#ifdef GNXSEQ
                        ulkseq();
                        ulkseq();
+#endif GNXSEQ
+                       systat(Rmtname, SS_INPROGRESS,
+                               strcmp(&msg[1], "CB") == SAME?
+                               "AWAITING CALLBACK": "FAILED HANDSHAKE");
                        goto next;
                }
                        goto next;
                }
+#ifdef GNXSEQ
                cmtseq();
                cmtseq();
+#endif GNXSEQ
        }
        }
-       DEBUG(1, " Rmtname %s, ", Rmtname);
+       DEBUG(1, "Rmtname %s, ", Rmtname);
        DEBUG(1, "Role %s,  ", Role ? "MASTER" : "SLAVE");
        DEBUG(1, "Ifn - %d, ", Ifn);
        DEBUG(1, "Loginuser - %s\n", Loginuser);
 
        alarm(MAXMSGTIME);
        DEBUG(1, "Role %s,  ", Role ? "MASTER" : "SLAVE");
        DEBUG(1, "Ifn - %d, ", Ifn);
        DEBUG(1, "Loginuser - %s\n", Loginuser);
 
        alarm(MAXMSGTIME);
-       if (setjmp(Sjbuf))
+       if (ret=setjmp(Sjbuf))
                goto Failure;
        ret = startup(Role);
        alarm(0);
        if (ret != SUCCESS) {
                goto Failure;
        ret = startup(Role);
        alarm(0);
        if (ret != SUCCESS) {
+               logent("startup", _FAILED);
 Failure:
 Failure:
-               logent("startup", "FAILED");
-               systat(Rmtname, SS_FAIL, "STARTUP");
+               US_SST(us_s_start);
+               systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" :
+                       "STARTUP FAILED");
                goto next;
                goto next;
-       }
-       else {
+       } else {
                logent("startup", "OK");
                logent("startup", "OK");
+               US_SST(us_s_gress);
                systat(Rmtname, SS_INPROGRESS, "TALKING");
                ret = cntrl(Role, wkpre);
                DEBUG(1, "cntrl - %d\n", ret);
                signal(SIGINT, SIG_IGN);
                signal(SIGHUP, SIG_IGN);
                signal(SIGALRM, timeout);
                systat(Rmtname, SS_INPROGRESS, "TALKING");
                ret = cntrl(Role, wkpre);
                DEBUG(1, "cntrl - %d\n", ret);
                signal(SIGINT, SIG_IGN);
                signal(SIGHUP, SIG_IGN);
                signal(SIGALRM, timeout);
-               if (ret == 0) {
+               if (ret == SUCCESS) {
                        logent("conversation complete", "OK");
                        logent("conversation complete", "OK");
+                       US_SST(us_s_ok);
                        rmstat(Rmtname);
 
                        rmstat(Rmtname);
 
-               }
-               else {
-                       logent("conversation complete", "FAILED");
-                       systat(Rmtname, SS_FAIL, "CONVERSATION");
+               } else {
+                       logent("conversation complete", _FAILED);
+                       US_SST(us_s_cf);
+                       systat(Rmtname, SS_FAIL, "CONVERSATION FAILED");
                }
                alarm(MAXMSGTIME);
                }
                alarm(MAXMSGTIME);
-               omsg('O', "OOOOO", Ofn);
                DEBUG(4, "send OO %d,", ret);
                if (!setjmp(Sjbuf)) {
                        for (;;) {
                DEBUG(4, "send OO %d,", ret);
                if (!setjmp(Sjbuf)) {
                        for (;;) {
@@ -408,7 +637,8 @@ Failure:
                        }
                }
                alarm(0);
                        }
                }
                alarm(0);
-               clsacu();       /* rti!trt: is this needed? */
+               clsacu();
+               rmlock(CNULL);
        }
 next:
        if (!onesys) {
        }
 next:
        if (!onesys) {
@@ -417,7 +647,7 @@ next:
        cleanup(0);
 }
 
        cleanup(0);
 }
 
-#ifndef        SYSIII
+#ifndef        USG
 struct sgttyb Hupvec;
 #endif
 
 struct sgttyb Hupvec;
 #endif
 
@@ -429,8 +659,9 @@ struct sgttyb Hupvec;
 cleanup(code)
 register int code;
 {
 cleanup(code)
 register int code;
 {
-       register int ret;
        register char *ttyn;
        register char *ttyn;
+       char bfr[BUFSIZ];
+       struct stat sbuf;
 
        signal(SIGINT, SIG_IGN);
        signal(SIGHUP, SIG_IGN);
 
        signal(SIGINT, SIG_IGN);
        signal(SIGHUP, SIG_IGN);
@@ -438,22 +669,27 @@ register int code;
        clsacu();
        logcls();
        if (Role == SLAVE) {
        clsacu();
        logcls();
        if (Role == SLAVE) {
-               if (!Unet) {
-#ifdef SYSIII
+               if (!IsTcpIp) {
+#ifdef USG
                        Savettyb.c_cflag |= HUPCL;
                        Savettyb.c_cflag |= HUPCL;
-                       ret = ioctl(0, TCSETA, &Savettyb);
-#endif
-#ifndef        SYSIII
-                       /* rti!trt:  use more robust hang up sequence */
-                       ret = ioctl(0, TIOCHPCL, STBNULL);
-                       ret = ioctl(0, TIOCGETP, &Hupvec);
+                       (void) ioctl(0, TCSETA, &Savettyb);
+#else !USG
+                       (void) ioctl(0, TIOCHPCL, STBNULL);
+#ifdef TIOCSDTR
+                       (void) ioctl(0, TIOCCDTR, STBNULL);
+                       sleep(2);
+                       (void) ioctl(0, TIOCSDTR, STBNULL);
+#else !TIOCSDTR
+                       (void) ioctl(0, TIOCGETP, &Hupvec);
+#endif !TIOCSDTR
                        Hupvec.sg_ispeed = B0;
                        Hupvec.sg_ospeed = B0;
                        Hupvec.sg_ispeed = B0;
                        Hupvec.sg_ospeed = B0;
-                       ret = ioctl(0, TIOCSETP, &Hupvec);
+                       (void) ioctl(0, TIOCSETP, &Hupvec);
                        sleep(2);
                        sleep(2);
-                       ret = ioctl(0, TIOCSETP, &Savettyb);
-#endif
-                       DEBUG(4, "ret ioctl - %d\n", ret);
+                       (void) ioctl(0, TIOCSETP, &Savettyb);
+                       /* make *sure* exclusive access is off */
+                       (void) ioctl(0, TIOCNXCL, STBNULL);
+#endif !USG
                }
                ttyn = ttyname(Ifn);
                if (ttyn != NULL)
                }
                ttyn = ttyname(Ifn);
                if (ttyn != NULL)
@@ -465,9 +701,19 @@ register int code;
                close(Ifn);
                close(Ofn);
        }
                close(Ifn);
                close(Ofn);
        }
-       DEBUG(1, "exit code %d\n", code);
+#ifdef DIALINOUT
+       /* reenable logins on dialout */
+       reenable();
+#endif DIALINOUT
        if (code == 0)
                xuuxqt();
        if (code == 0)
                xuuxqt();
+       else
+               DEBUG(1, "exit code %d\n", code);
+       sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname);
+       if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0)
+               unlink(bfr);
+       sprintf(bfr, "%s/%d", RMTDEBUG, getpid());
+       unlink(bfr);
        exit(code);
 }
 
        exit(code);
 }
 
@@ -482,30 +728,40 @@ register int inter;
        signal(inter, SIG_IGN);
        sprintf(str, "SIGNAL %d", inter);
        logent(str, "CAUGHT");
        signal(inter, SIG_IGN);
        sprintf(str, "SIGNAL %d", inter);
        logent(str, "CAUGHT");
-       systat(Rmtname, SS_FAIL, str);
+       US_SST(us_s_intr);
+       if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME))
+               systat(Rmtname, SS_FAIL, str);
+       if (inter == SIGPIPE && !onesys)
+               longjmp(Pipebuf, 1);
        cleanup(inter);
 }
 
        cleanup(inter);
 }
 
-/* changed to single version of intrEXIT.  Is this okay? rti!trt */
-intrEXIT(signo)
-int signo;
-{
-       signal(signo, SIG_DFL);
-       setgid(getgid());
-       setuid(getuid());
-       abort();
-}
 /*
  * Catch a special signal
  * (SIGFPE, ugh), and toggle debugging between 0 and 30.
  * Handy for looking in on long running uucicos.
  */
 /*
  * Catch a special signal
  * (SIGFPE, ugh), and toggle debugging between 0 and 30.
  * Handy for looking in on long running uucicos.
  */
-setdebug()
+setdebug(code)
+int code;
 {
 {
-       if (Debug < 30)
-               Debug = 30;
-       else
-               Debug = 0;
+       char buf[BUFSIZ];
+
+       if (code) {
+               if (Debug == 0)
+                       Debug = 30;
+               else
+                       Debug = 0;
+       }
+       if (Debug && !StdErrIsTty) {
+               sprintf(buf,"%s/%s", RMTDEBUG, Rmtname);
+               unlink(buf);
+               freopen(buf, "w", stderr);
+#ifdef BSD4_2
+               setlinebuf(stderr);
+#else  !BSD4_2
+               setbuf(stderr, NULL);
+#endif !BSD4_2
+       }
 }
 
 
 }
 
 
@@ -518,45 +774,49 @@ setdebug()
 fixmode(tty)
 register int tty;
 {
 fixmode(tty)
 register int tty;
 {
-#ifdef SYSIII
+#ifdef USG
        struct termio ttbuf;
 #endif
        struct termio ttbuf;
 #endif
-#ifndef        SYSIII
+#ifndef        USG
        struct sgttyb ttbuf;
 #endif
        struct sgttyb ttbuf;
 #endif
-       register int ret;
 
 
-       if (Unet)
+       if (IsTcpIp)
                return;
                return;
-#ifdef SYSIII
+#ifdef USG
        ioctl(tty, TCGETA, &ttbuf);
        ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0;
        ttbuf.c_cflag &= (CBAUD);
        ttbuf.c_cflag |= (CS8|CREAD);
        ttbuf.c_cc[VMIN] = 6;
        ttbuf.c_cc[VTIME] = 1;
        ioctl(tty, TCGETA, &ttbuf);
        ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0;
        ttbuf.c_cflag &= (CBAUD);
        ttbuf.c_cflag |= (CS8|CREAD);
        ttbuf.c_cc[VMIN] = 6;
        ttbuf.c_cc[VTIME] = 1;
-       ret = ioctl(tty, TCSETA, &ttbuf);
+       ioctl(tty, TCSETA, &ttbuf);
 #endif
 #endif
-#ifndef        SYSIII
+#ifndef        USG
        ioctl(tty, TIOCGETP, &ttbuf);
        ttbuf.sg_flags = (ANYP | RAW);
        ioctl(tty, TIOCGETP, &ttbuf);
        ttbuf.sg_flags = (ANYP | RAW);
-       ret = ioctl(tty, TIOCSETP, &ttbuf);
+       ioctl(tty, TIOCSETP, &ttbuf);
 #endif
 #endif
-       ASSERT(ret >= 0, "STTY FAILED", "", ret);
-#ifndef        SYSIII
+#ifndef        USG
        ioctl(tty, TIOCEXCL, STBNULL);
 #endif
 }
 
 
        ioctl(tty, TIOCEXCL, STBNULL);
 #endif
 }
 
 
-/***
+/*
  *     timeout()       catch SIGALRM routine
  */
 
 timeout()
 {
  *     timeout()       catch SIGALRM routine
  */
 
 timeout()
 {
-       logent(Rmtname, "TIMEOUT");
-       systat(Rmtname, SS_FAIL, "TIMEOUT");
+       extern int HaveSentHup;
+       if (!HaveSentHup) {
+               logent(Rmtname, "TIMEOUT");
+               if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) {
+                       US_SST(us_s_tmot);
+                       systat(Rmtname, SS_FAIL, "TIMEOUT");
+               }
+       }
        longjmp(Sjbuf, 1);
 }
 
        longjmp(Sjbuf, 1);
 }
 
@@ -564,8 +824,9 @@ static char *
 pskip(p)
 register char *p;
 {
 pskip(p)
 register char *p;
 {
-       while( *p && *p != ' ' )
+       while(*p && *p != ' ')
                ++p;
                ++p;
-       if( *p ) *p++ = 0;
-       return(p);
+       while(*p && *p == ' ')
+               *p++ = 0;
+       return p;
 }
 }