Annotation of 43BSDReno/usr.bin/uucp/cico.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)cico.c     5.19    (Berkeley) 5/11/89";
                      3: #endif
                      4: 
                      5: #include <signal.h>
                      6: #include "uucp.h"
                      7: #include <setjmp.h>
                      8: #ifdef USG
                      9: #include <termio.h>
                     10: #include <fcntl.h>
                     11: #endif
                     12: #ifndef        USG
                     13: #include <sgtty.h>
                     14: #endif
                     15: #ifdef BSDTCP
                     16: #include <netdb.h>
                     17: #include <netinet/in.h>
                     18: #include <sys/socket.h>
                     19: #endif BSDTCP
                     20: #include <sys/stat.h>
                     21: #ifdef BSD4_2
                     22: #include <sys/time.h>
                     23: #include <fcntl.h>
                     24: #else
                     25: #include <time.h>
                     26: #endif
                     27: #include "uust.h"
                     28: #include "uusub.h"
                     29: #include "pathnames.h"
                     30: 
                     31: #if defined(VMS) && defined(BSDTCP)
                     32: #define NOGETPEER
                     33: #endif
                     34: 
                     35: jmp_buf Sjbuf;
                     36: jmp_buf Pipebuf;
                     37: 
                     38: /*  call fail text  */
                     39: char *Stattext[] = {
                     40:        "",
                     41:        "BAD SYSTEM",
                     42:        "WRONG TIME TO CALL",
                     43:        "SYSTEM LOCKED",
                     44:        "NO DEVICE",
                     45:        "CALL FAILED",
                     46:        "LOGIN FAILED",
                     47:        "BAD SEQUENCE"
                     48: };
                     49: 
                     50: /*  call fail codes  */
                     51: int Stattype[] = {
                     52:        0,
                     53:        0,
                     54:        SS_WRONGTIME,
                     55:        0,
                     56:        SS_NODEVICE,
                     57:        SS_FAIL,
                     58:        SS_FAIL,
                     59:        SS_BADSEQ
                     60: };
                     61: 
                     62:                                /* Arguments to setdebug():                  */
                     63: #define DBG_TEMP  0            /*   Create a temporary audit file           */
                     64: #define DBG_PERM  1            /*   Create a permanent audit file           */
                     65: #define DBG_CLEAN 2            /*   Cleanup, discard temp file              */
                     66: 
                     67: int ReverseRole = 0;
                     68: int Role = SLAVE;
                     69: int InitialRole = SLAVE;
                     70: long StartTime;
                     71: int onesys = 0;
                     72: int turntime = 30 * 60;        /* 30 minutes expressed in seconds */
                     73: char *ttyn = NULL;
                     74: extern int LocalOnly;
                     75: extern int errno;
                     76: extern char MaxGrade, DefMaxGrade;
                     77: extern char Myfullname[];
                     78: 
                     79: long Bytes_Sent, Bytes_Received;
                     80: 
                     81: #ifdef USG
                     82: struct termio Savettyb;
                     83: #endif
                     84: #ifndef        USG
                     85: struct sgttyb Savettyb;
                     86: #endif
                     87: 
                     88: #define SETPROCTITLE
                     89: #ifdef SETPROCTITLE
                     90: char   **Argv = NULL;          /* pointer to argument vector */
                     91: char   *LastArgv = NULL;       /* end of argv */
                     92: #endif SETPROCTITLE
                     93: 
                     94: /*
                     95:  *     this program is used  to place a call to a
                     96:  *     remote machine, login, and copy files between the two machines.
                     97:  */
                     98: main(argc, argv, envp)
                     99: int argc;
                    100: char **argv;
                    101: char **envp;
                    102: {
                    103:        register int ret;
                    104:        int seq;
                    105:        char wkpre[NAMESIZE], file[NAMESIZE];
                    106:        char msg[MAXFULLNAME], *q;
                    107:        register char *p;
                    108:        extern onintr(), timeout(), dbg_signal();
                    109:        extern char *pskip();
                    110:        extern char *optarg;
                    111:        extern int optind;
                    112:        char rflags[MAXFULLNAME];
                    113: #ifdef NOGETPEER
                    114:        u_long Hostnumber = 0;
                    115: #endif NOGETPEER
                    116: 
                    117:        strcpy(Progname, "uucico");
                    118: 
                    119: #ifdef BSD4_2
                    120:        sigsetmask(0L); /* in case we inherit blocked signals */
                    121: #endif BSD4_2
                    122:        signal(SIGINT, onintr);
                    123:        signal(SIGHUP, onintr);
                    124:        signal(SIGQUIT, onintr);
                    125:        signal(SIGTERM, onintr);
                    126:        signal(SIGPIPE, onintr);        /* 4.1a tcp-ip stupidity */
                    127:        signal(SIGUSR1, dbg_signal);
                    128:        ret = guinfo(getuid(), User, msg);
                    129:        strcpy(Loginuser, User);
                    130:        uucpname(Myname);
                    131:        if (ret == FAIL) {
                    132:                syslog(LOG_ERR, "can't get uid");
                    133:                cleanup(FAIL);
                    134:        }
                    135: 
                    136:        setbuf (stderr, CNULL);
                    137: 
                    138:        rflags[0] = '\0';
                    139:        umask(WFMASK);
                    140:        strcpy(Rmtname, Myname);
                    141:        Ifn = Ofn = -1;
                    142:        while ((ret = getopt(argc, argv, "RLd:g:p:r:s:x:t:")) != EOF)
                    143:                switch(ret){
                    144:                case 'd':
                    145:                        Spool = optarg;
                    146:                        break;
                    147:                case 'g':
                    148:                case 'p':
                    149:                        MaxGrade = DefMaxGrade = *optarg;
                    150:                        break;
                    151:                case 'r':
                    152:                        Role = atoi(optarg);
                    153:                        break;
                    154:                case 'R':
                    155:                        ReverseRole++;
                    156:                        Role = MASTER;
                    157:                        break;
                    158:                case 's':
                    159:                        strncpy(Rmtname, optarg, MAXBASENAME);
                    160:                        Rmtname[MAXBASENAME] = '\0';
                    161:                        if (Rmtname[0] != '\0')
                    162:                                onesys = 1;
                    163:                        break;
                    164:                case 'x':
                    165:                        Debug = atoi(optarg);
                    166:                        if (Debug <= 0)
                    167:                                Debug = 1;
                    168:                        strcat(rflags, argv[optind-1]);
                    169:                        break;
                    170:                case 't':
                    171:                        turntime = atoi(optarg)*60;/* minutes to seconds */
                    172:                        break;
                    173:                case 'L':       /* local calls only */
                    174:                        LocalOnly++;
                    175:                        break;
                    176: #ifdef NOGETPEER
                    177:                case 'h':
                    178:                        Hostnumber = inet_addr(&argv[1][2]);
                    179:                        break;
                    180: #endif NOGETPEER
                    181:                case '?':
                    182:                default:
                    183:                        fprintf(stderr, "unknown flag %s (ignored)\n",
                    184:                                argv[optind-1]);
                    185:                        break;
                    186:                }
                    187: 
                    188:        while (optind < argc)
                    189:                fprintf(stderr, "unknown argument %s (ignored)\n",
                    190:                        argv[optind++]);
                    191: 
                    192:        if (Debug && Role == MASTER)
                    193:                chkdebug();
                    194: 
                    195: #ifdef SETPROCTITLE
                    196:        /*
                    197:         *  Save start and extent of argv for setproctitle.
                    198:         */
                    199: 
                    200:        Argv = argv;
                    201:        LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
                    202: #endif SETPROCTITLE
                    203: 
                    204:        /* Try to run as uucp */
                    205:        setgid(getegid());
                    206:        setuid(geteuid());
                    207: #ifdef TIOCNOTTY
                    208:        /*
                    209:         * detach uucico from controlling terminal
                    210:         * to defend against rlogind sending us a SIGKILL (!!!)
                    211:         */
                    212:        if (Role == MASTER && (ret = open(_PATH_TTY, 2)) >= 0) {
                    213:                ioctl(ret, TIOCNOTTY, STBNULL);
                    214:                close(ret);
                    215:        }
                    216: #endif TIOCNOTTY
                    217: #ifdef BSD4_2
                    218:        if (getpgrp(0) == 0) { /* We have no controlling terminal */
                    219:                setpgrp(0, getpid());
                    220:        }
                    221: #ifdef USE_SYSLOG
                    222: #ifdef BSD4_3
                    223:        openlog("uucico", LOG_PID, LOG_UUCP);
                    224: #else /* !BSD4_3 */
                    225:        openlog("uucico", LOG_PID);
                    226: #endif /* !BSD4_3 */
                    227: #endif /* USE_SYSLOG */
                    228: #endif BSD4_2
                    229: 
                    230: #ifdef BSD4_3
                    231:        unsetenv("TZ");         /* We don't want him resetting our time zone */
                    232: #endif /* !BSD4_3 */
                    233: 
                    234:        if (subchdir(Spool) < 0) {
                    235:                syslog(LOG_ERR, "chdir(%s) failed: %m", Spool);
                    236:                cleanup(FAIL);
                    237:        }
                    238: 
                    239:        strcpy(Wrkdir, Spool);
                    240: 
                    241:        if (Debug) {
                    242:                setdebug ((Role == SLAVE) ? DBG_TEMP : DBG_PERM);
                    243:                if (Debug > 0)
                    244:                        logent ("Local Enabled", "DEBUG");
                    245:        }
                    246: 
                    247:        /*
                    248:         * First time through: If we're the slave, do initial checking.
                    249:         */
                    250:        if (Role == SLAVE) {
                    251:                /* check for /etc/nologin */
                    252:                if (access(NOLOGIN, 0) == 0) {
                    253:                        logent(NOLOGIN, "UUCICO SHUTDOWN");
                    254:                        if (Debug > 4)
                    255:                                logent("DEBUGGING", "continuing anyway");
                    256:                        else
                    257:                                cleanup(1);
                    258:                }
                    259:                Ifn = 0;
                    260:                Ofn = 1;
                    261: #ifdef TCPIP
                    262:                /*
                    263:                 * Determine if we are on TCPIP
                    264:                 */
                    265:                if (isatty(Ifn) == 0) {
                    266:                        IsTcpIp = 1;
                    267:                        DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
                    268:                } else
                    269:                        IsTcpIp = 0;
                    270: #endif TCPIP
                    271:                /* initial handshake */
                    272:                onesys = 1;
                    273:                if (!IsTcpIp) {
                    274: #ifdef USG
                    275:                        ret = ioctl(Ifn, TCGETA, &Savettyb);
                    276:                        Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
                    277:                        Savettyb.c_oflag |= OPOST;
                    278:                        Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
                    279: #else !USG
                    280:                        ret = ioctl(Ifn, TIOCGETP, &Savettyb);
                    281:                        Savettyb.sg_flags |= ECHO;
                    282:                        Savettyb.sg_flags &= ~RAW;
                    283: #endif !USG
                    284:                        ttyn = ttyname(Ifn);
                    285:                }
                    286:                fixmode(Ifn);
                    287: 
                    288:                /*
                    289:                 * Initial Message -- tell them we're here, and who we are.
                    290:                 */
                    291:                sprintf(msg, "here=%s", Myfullname);
                    292:                omsg('S', msg, Ofn);
                    293:                signal(SIGALRM, timeout);
                    294:                alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
                    295:                if (setjmp(Sjbuf)) {
                    296:                        /* timed out */
                    297:                        if (!IsTcpIp) {
                    298: #ifdef USG
                    299:                                ret = ioctl(Ifn, TCSETA, &Savettyb);
                    300: 
                    301: #else  !USG
                    302:                                ret = ioctl(Ifn, TIOCSETP, &Savettyb);
                    303: #endif !USG
                    304:                        }
                    305:                        cleanup(0);
                    306:                }
                    307:                for (;;) {
                    308:                        ret = imsg(msg, Ifn);
                    309:                        if (ret != SUCCESS) {
                    310:                                alarm(0);
                    311:                                if (!IsTcpIp) {
                    312: #ifdef USG
                    313:                                        ret = ioctl(Ifn, TCSETA, &Savettyb);
                    314: #else  !USG
                    315:                                        ret = ioctl(Ifn, TIOCSETP, &Savettyb);
                    316: #endif !USG
                    317:                                }
                    318:                                cleanup(0);
                    319:                        }
                    320:                        if (msg[0] == 'S')
                    321:                                break;
                    322:                }
                    323:                alarm(0);
                    324:                q = &msg[1];
                    325:                p = pskip(q);
                    326:                strncpy(Rmtname, q, MAXBASENAME);
                    327:                Rmtname[MAXBASENAME] = '\0';
                    328: 
                    329:                /*
                    330:                 * Now that we know who they are, give the audit file the right
                    331:                 * name.
                    332:                 */
                    333:                setdebug (DBG_PERM);
                    334:                DEBUG(4, "sys-%s\n", Rmtname);
                    335:                /* The versys will also do an alias on the incoming name */
                    336:                if (versys(&Rmtname)) {
                    337: #ifdef NOSTRANGERS
                    338:                        /* If we don't know them, we won't talk to them... */
                    339:                        syslog(LOG_WARNING, "Unknown host: %s", Rmtname);
                    340:                        omsg('R', "You are unknown to me", Ofn);
                    341:                        cleanup(0);
                    342: #endif NOSTRANGERS
                    343:                }
                    344: #ifdef BSDTCP
                    345:                /* we must make sure they are really who they say they
                    346:                 * are. We compare the hostnumber with the number in the hosts
                    347:                 * table for the site they claim to be.
                    348:                 */
                    349:                if (IsTcpIp) {
                    350:                        struct hostent *hp;
                    351:                        char *cpnt, *inet_ntoa();
                    352:                        int fromlen;
                    353:                        struct sockaddr_in from;
                    354:                        extern char PhoneNumber[];
                    355: 
                    356: #ifdef NOGETPEER
                    357:                        from.sin_addr.s_addr = Hostnumber;
                    358:                        from.sin_family = AF_INET;
                    359: #else  !NOGETPEER
                    360:                        fromlen = sizeof(from);
                    361:                        if (getpeername(Ifn, &from, &fromlen) < 0) {
                    362:                                logent(Rmtname, "NOT A TCP CONNECTION");
                    363:                                omsg('R', "NOT TCP", Ofn);
                    364:                                cleanup(0);
                    365:                        }
                    366: #endif !NOGETPEER
                    367:                        hp = gethostbyaddr(&from.sin_addr,
                    368:                                sizeof (struct in_addr), from.sin_family);
                    369:                        if (hp == NULL) {
                    370:                                /* security break or just old host table? */
                    371:                                logent(Rmtname, "UNKNOWN IP-HOST Name =");
                    372:                                cpnt = inet_ntoa(from.sin_addr),
                    373:                                logent(cpnt, "UNKNOWN IP-HOST Number =");
                    374:                                sprintf(wkpre, "%s/%s isn't in my host table",
                    375:                                        Rmtname, cpnt);
                    376:                                omsg('R' ,wkpre ,Ofn);
                    377:                                cleanup(0);
                    378:                        }
                    379:                        if (Debug > 99)
                    380:                                logent(Rmtname,"Request from IP-Host name =");
                    381:                        /*
                    382:                         * The following is to determine if the name given us by
                    383:                         * the Remote uucico matches any of the names
                    384:                         * given its network number (remote machine) in our
                    385:                         * host table.
                    386:                         * We could check the aliases, but that won't work in
                    387:                         * all cases (like if you are running the domain
                    388:                         * server, where you don't get any aliases). The only
                    389:                         * reliable way I can think of that works in ALL cases
                    390:                         * is too look up the site in L.sys and see if the
                    391:                         * sitename matches what we would call him if we
                    392:                         * originated the call.
                    393:                         */
                    394:                        /* PhoneNumber contains the official network name of the                           host we are checking. (set in versys.c) */
                    395:                        if (sncncmp(PhoneNumber, hp->h_name, SYSNSIZE) == 0) {
                    396:                                if (Debug > 99)
                    397:                                        logent(q,"Found in host Tables");
                    398:                        } else {
                    399:                                logent(hp->h_name, "FORGED HOSTNAME");
                    400:                                logent(inet_ntoa(from.sin_addr), "ORIGINATED AT");
                    401:                                logent(PhoneNumber, "SHOULD BE");
                    402:                                sprintf(wkpre, "You're not who you claim to be: %s !=  %s", hp->h_name, PhoneNumber);
                    403:                                omsg('R', wkpre, Ofn);
                    404:                                cleanup(0);
                    405:                        }
                    406:                }
                    407: #endif BSDTCP
                    408: 
                    409:                if (mlock(Rmtname)) {
                    410:                        omsg('R', "LCK", Ofn);
                    411:                        cleanup(0);
                    412:                }
                    413:                else if (callback(Loginuser)) {
                    414:                        signal(SIGINT, SIG_IGN);
                    415:                        signal(SIGHUP, SIG_IGN);
                    416:                        omsg('R', "CB", Ofn);
                    417:                        logent("CALLBACK", "REQUIRED");
                    418:                        /*  set up for call back  */
                    419:                        systat(Rmtname, SS_CALLBACK, "CALLING BACK");
                    420:                        gename(CMDPRE, Rmtname, 'C', file);
                    421:                        close(creat(subfile(file), 0666));
                    422:                        xuucico(Rmtname);
                    423:                        cleanup(0);
                    424:                }
                    425:                seq = 0;
                    426:                while (*p == '-') {
                    427:                        q = pskip(p);
                    428:                        switch(*(++p)) {
                    429:                        case 'x':
                    430:                                if (Debug == 0) {
                    431:                                        Debug = atoi(++p);
                    432:                                        if (Debug <= 0)
                    433:                                                Debug = 1;
                    434:                                        setdebug(DBG_PERM);
                    435:                                        if (Debug > 0)
                    436:                                                logent("Remote Enabled", "DEBUG");
                    437:                                } else {
                    438:                                        DEBUG(1, "Remote debug request ignored\n",
                    439:                                           CNULL);
                    440:                                }
                    441:                                break;
                    442:                        case 'Q':
                    443:                                seq = atoi(++p);
                    444:                                break;
                    445:                        case 'p':
                    446:                                MaxGrade = DefMaxGrade = *++p;
                    447:                                DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
                    448:                                break;
                    449:                        case 'v':
                    450:                                if (strncmp(p, "grade", 5) == 0) {
                    451:                                        p += 6;
                    452:                                        MaxGrade = DefMaxGrade = *p++;
                    453:                                        DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
                    454:                                }
                    455:                                break;
                    456:                        default:
                    457:                                break;
                    458:                        }
                    459:                        p = q;
                    460:                }
                    461:                setproctitle("%s: startup", Rmtname);
                    462:                if (callok(Rmtname) == SS_BADSEQ) {
                    463:                        logent("BADSEQ", "PREVIOUS");
                    464:                        omsg('R', "BADSEQ", Ofn);
                    465:                        cleanup(0);
                    466:                }
                    467: #ifdef GNXSEQ
                    468:                if ((ret = gnxseq(Rmtname)) == seq) {
                    469:                        omsg('R', "OK", Ofn);
                    470:                        cmtseq();
                    471:                } else {
                    472: #else !GNXSEQ
                    473:                if (seq == 0)
                    474:                        omsg('R', "OK", Ofn);
                    475:                else {
                    476: #endif !GNXSEQ
                    477:                        systat(Rmtname, Stattype[7], Stattext[7]);
                    478:                        logent("BAD SEQ", "FAILED HANDSHAKE");
                    479: #ifdef GNXSEQ
                    480:                        ulkseq();
                    481: #endif GNXSEQ
                    482:                        omsg('R', "BADSEQ", Ofn);
                    483:                        cleanup(0);
                    484:                }
                    485:                if (ttyn != NULL)
                    486:                        chmod(ttyn, 0600);
                    487:        }
                    488: 
                    489: loop:
                    490:        if(setjmp(Pipebuf)) {   /* come here on SIGPIPE */
                    491:                clsacu();
                    492:                logcls();
                    493:                close(Ofn);
                    494:                close(Ifn);
                    495:                Ifn = Ofn = -1;
                    496:                rmlock(CNULL);
                    497:                sleep(3);
                    498:        }
                    499:        if (!onesys) {
                    500:                do_connect_accounting();
                    501: #ifdef DIALINOUT
                    502:                /* reenable logins on dialout */
                    503:                reenable();
                    504: #endif DIALINOUT
                    505:                StartTime = 0;
                    506:                setproctitle("looking for work");
                    507:                ret = gnsys(Rmtname, Spool, CMDPRE);
                    508:                setproctitle("%s: startup", Rmtname);
                    509:                setdebug(DBG_PERM);
                    510:                if (ret == FAIL)
                    511:                        cleanup(100);
                    512:                else if (ret == SUCCESS)
                    513:                        cleanup(0);
                    514:                logcls();
                    515:        } else if (Role == MASTER && callok(Rmtname) != 0) {
                    516:                logent("SYSTEM STATUS", "CAN NOT CALL");
                    517:                cleanup(0);
                    518:        }
                    519: 
                    520:        sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname);
                    521:        StartTime = 0;
                    522:        Bytes_Sent = Bytes_Received = 0L;
                    523: 
                    524:        signal(SIGINT, SIG_IGN);
                    525:        signal(SIGQUIT, SIG_IGN);
                    526:        if (Role == MASTER) {
                    527:                extern char LineType[];
                    528:                /* check for /etc/nologin */
                    529:                if (access(NOLOGIN, 0) == 0) {
                    530:                        logent(NOLOGIN, "UUCICO SHUTDOWN");
                    531:                        if (Debug > 4)
                    532:                                logent("DEBUGGING", "continuing anyway");
                    533:                        else
                    534:                                cleanup(1);
                    535:                }
                    536:                /*  master part */
                    537:                signal(SIGHUP, SIG_IGN);
                    538:                if (Ifn != -1 && Role == MASTER) {
                    539:                        write(Ofn, EOTMSG, strlen(EOTMSG));
                    540:                        clsacu();
                    541:                        close(Ofn);
                    542:                        close(Ifn);
                    543:                        Ifn = Ofn = -1;
                    544:                        rmlock(CNULL);
                    545:                        sleep(3);
                    546:                }
                    547:                if (mlock(Rmtname) != SUCCESS) {
                    548:                        DEBUG(1, "LOCKED: call to %s\n", Rmtname); 
                    549:                        US_SST(us_s_lock);
                    550:                        goto next;
                    551:                }
                    552:                setproctitle("%s: starting call", Rmtname);
                    553:                Ofn = Ifn = conn(Rmtname);
                    554:                sprintf(msg, "(call to %s via %s)", Rmtname, LineType);
                    555:                if (Ofn < 0) {
                    556:                        if (Ofn != CF_TIME)
                    557:                                logent(msg, _FAILED);
                    558:                        /* avoid excessive 'wrong time' info */
                    559:                        if (Stattype[-Ofn] != SS_WRONGTIME){
                    560:                                systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]);
                    561:                                US_SST(-Ofn);
                    562:                                UB_SST(-Ofn);
                    563:                        }
                    564:                        goto next;
                    565:                } else {
                    566:                        logent(msg, "SUCCEEDED");
                    567:                        US_SST(us_s_cok);
                    568:                        UB_SST(ub_ok);
                    569:                }
                    570:                InitialRole = MASTER;
                    571: #ifdef TCPIP
                    572:                /*
                    573:                 * Determine if we are on TCPIP
                    574:                 */
                    575:                if (isatty(Ifn) == 0) {
                    576:                        IsTcpIp = 1;
                    577:                        DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
                    578:                } else
                    579:                        IsTcpIp = 0;
                    580: #endif
                    581: 
                    582:                if (setjmp(Sjbuf))
                    583:                        goto next;
                    584:                signal(SIGALRM, timeout);
                    585:                alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME*2);
                    586:                for (;;) {
                    587:                        ret = imsg(msg, Ifn);
                    588:                        if (ret != SUCCESS) {
                    589:                                alarm(0);
                    590:                                DEBUG(4,"\nimsg failed: errno %d\n", errno);
                    591:                                logent("imsg 1", _FAILED);
                    592:                                goto Failure;
                    593:                        }
                    594:                        if (msg[0] == 'S')
                    595:                                break;
                    596:                }
                    597:                alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
                    598: #ifdef GNXSEQ
                    599:                seq = gnxseq(Rmtname);
                    600: #else !GNXSEQ
                    601:                seq = 0;
                    602: #endif !GNXSEQ
                    603:                if (MaxGrade != '\177') {
                    604:                        DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade);
                    605:                        sprintf(msg, "%s -Q%d -p%c -vgrade=%c %s",
                    606:                                Myname, seq, MaxGrade, MaxGrade, rflags);
                    607:                } else
                    608:                        sprintf(msg, "%s -Q%d %s", Myname, seq, rflags);
                    609:                omsg('S', msg, Ofn);
                    610:                for (;;) {
                    611:                        ret = imsg(msg, Ifn);
                    612:                        DEBUG(4, "msg-%s\n", msg);
                    613:                        if (ret != SUCCESS) {
                    614:                                alarm(0);
                    615: #ifdef GNXSEQ
                    616:                                ulkseq();
                    617: #endif GNXSEQ
                    618:                                logent("imsg 2", _FAILED);
                    619:                                goto Failure;
                    620:                        }
                    621:                        if (msg[0] == 'R')
                    622:                                break;
                    623:                }
                    624:                alarm(0);
                    625:                if (msg[1] == 'B') {
                    626:                        /* bad sequence */
                    627:                        logent("BAD SEQ", "FAILED HANDSHAKE");
                    628:                        US_SST(us_s_hand);
                    629:                        systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]);
                    630: #ifdef GNXSEQ
                    631:                        ulkseq();
                    632: #endif GNXSEQ
                    633:                        goto next;
                    634:                }
                    635:                if (strcmp(&msg[1], "OK") != SAME)  {
                    636:                        logent(&msg[1], "FAILED HANDSHAKE");
                    637:                        US_SST(us_s_hand);
                    638: #ifdef GNXSEQ
                    639:                        ulkseq();
                    640: #endif GNXSEQ
                    641:                        systat(Rmtname, SS_INPROGRESS,
                    642:                                strcmp(&msg[1], "CB") == SAME?
                    643:                                "AWAITING CALLBACK": "FAILED HANDSHAKE");
                    644:                        goto next;
                    645:                }
                    646: #ifdef GNXSEQ
                    647:                cmtseq();
                    648: #endif GNXSEQ
                    649:        }
                    650:        DEBUG(1, "Rmtname %s, ", Rmtname);
                    651:        DEBUG(1, "Role %s,  ", Role ? "MASTER" : "SLAVE");
                    652:        DEBUG(1, "Ifn - %d, ", Ifn);
                    653:        DEBUG(1, "Loginuser - %s\n", Loginuser);
                    654:        setproctitle("%s: %s", Rmtname, Role ? "MASTER" : "SLAVE");
                    655: 
                    656:        ttyn = ttyname(Ifn);
                    657: 
                    658:        alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
                    659:        if (ret=setjmp(Sjbuf))
                    660:                goto Failure;
                    661:        ret = startup(Role);
                    662:        alarm(0);
                    663:        if (ret != SUCCESS) {
                    664:                logent("(startup)", _FAILED);
                    665: Failure:
                    666:                US_SST(us_s_start);
                    667:                systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" :
                    668:                        "STARTUP FAILED");
                    669:                goto next;
                    670:        } else {
                    671:                char smsg[BUFSIZ], gmsg[10], pmsg[20], bpsmsg[20];
                    672:                extern char UsingProtocol;
                    673:                extern int linebaudrate;
                    674:                if (ttyn != NULL) 
                    675:                        sprintf(bpsmsg, " %s %d bps", &ttyn[5], linebaudrate);
                    676:                else
                    677:                        bpsmsg[0] = '\0';
                    678:                if (UsingProtocol != 'g')
                    679:                        sprintf(pmsg, " %c protocol", UsingProtocol);
                    680:                else
                    681:                        pmsg[0] = '\0';
                    682:                if (MaxGrade != '\177')
                    683:                        sprintf(gmsg, " grade %c", MaxGrade);
                    684:                else
                    685:                        gmsg[0] = '\0';
                    686:                sprintf(smsg, "(startup%s%s%s)", bpsmsg, pmsg, gmsg);
                    687:                logent(smsg, "OK");
                    688:                US_SST(us_s_gress);
                    689:                StartTime = Now.time;
                    690:                systat(Rmtname, SS_INPROGRESS, "TALKING");
                    691:                ret = cntrl(Role, wkpre);
                    692:                DEBUG(1, "cntrl - %d\n", ret);
                    693:                signal(SIGINT, SIG_IGN);
                    694:                signal(SIGHUP, SIG_IGN);
                    695:                signal(SIGALRM, timeout);
                    696:                sprintf(smsg, "(conversation complete %ld sent %ld received)",
                    697:                        Bytes_Sent, Bytes_Received);
                    698:                if (ret == SUCCESS) {
                    699:                        logent(smsg, "OK");
                    700:                        US_SST(us_s_ok);
                    701:                        rmstat(Rmtname);
                    702: 
                    703:                } else {
                    704:                        logent(smsg, _FAILED);
                    705:                        US_SST(us_s_cf);
                    706:                        systat(Rmtname, SS_FAIL, "CONVERSATION FAILED");
                    707:                }
                    708:                alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
                    709:                DEBUG(4, "send OO %d,", ret);
                    710:                if (!setjmp(Sjbuf)) {
                    711:                        for (;;) {
                    712:                                omsg('O', "OOOOO", Ofn);
                    713:                                ret = imsg(msg, Ifn);
                    714:                                if (ret != 0)
                    715:                                        break;
                    716:                                if (msg[0] == 'O')
                    717:                                        break;
                    718:                        }
                    719:                }
                    720:                alarm(0);
                    721:                clsacu();
                    722:                rmlock(CNULL);
                    723:        
                    724:        }
                    725: next:
                    726:        if (!onesys) {
                    727:                goto loop;
                    728:        }
                    729:        cleanup(0);
                    730: }
                    731: 
                    732: #ifndef        USG
                    733: struct sgttyb Hupvec;
                    734: #endif
                    735: 
                    736: /*
                    737:  *     cleanup and exit with "code" status
                    738:  */
                    739: cleanup(code)
                    740: register int code;
                    741: {
                    742:        signal(SIGINT, SIG_IGN);
                    743:        signal(SIGHUP, SIG_IGN);
                    744:        rmlock(CNULL);
                    745:        sleep(5);                       /* Wait for any pending output    */
                    746:        clsacu();
                    747:        logcls();
                    748:        if (Role == SLAVE) {
                    749:                if (!IsTcpIp) {
                    750: #ifdef USG
                    751:                        Savettyb.c_cflag |= HUPCL;
                    752:                        (void) ioctl(0, TCSETA, &Savettyb);
                    753: #else !USG
                    754:                        (void) ioctl(0, TIOCHPCL, STBNULL);
                    755: #ifdef TIOCSDTR
                    756:                        (void) ioctl(0, TIOCCDTR, STBNULL);
                    757:                        sleep(2);
                    758:                        (void) ioctl(0, TIOCSDTR, STBNULL);
                    759: #else !TIOCSDTR
                    760:                        (void) ioctl(0, TIOCGETP, &Hupvec);
                    761:                        Hupvec.sg_ispeed = B0;
                    762:                        Hupvec.sg_ospeed = B0;
                    763:                        (void) ioctl(0, TIOCSETP, &Hupvec);
                    764: #endif !TIOCSDTR
                    765:                        sleep(2);
                    766:                        (void) ioctl(0, TIOCSETP, &Savettyb);
                    767:                        /* make *sure* exclusive access is off */
                    768:                        (void) ioctl(0, TIOCNXCL, STBNULL);
                    769: #endif !USG
                    770:                }
                    771:                if (ttyn != NULL)
                    772:                        chmod(ttyn, 0600);
                    773:        }
                    774:        if (Ofn != -1) {
                    775:                if (Role == MASTER)
                    776:                        write(Ofn, EOTMSG, strlen(EOTMSG));
                    777:                close(Ifn);
                    778:                close(Ofn);
                    779:        }
                    780: #ifdef DIALINOUT
                    781:        /* reenable logins on dialout */
                    782:        reenable();
                    783: #endif DIALINOUT
                    784:        if (code == 0)
                    785:                xuuxqt();
                    786:        else
                    787:                DEBUG(1, "exit code %d\n", code);
                    788:        setdebug (DBG_CLEAN);
                    789:        do_connect_accounting();
                    790:        exit(code);
                    791: }
                    792: 
                    793: do_connect_accounting()
                    794: {
                    795: #ifdef DO_CONNECT_ACCOUNTING
                    796:        register FILE *fp;
                    797:        struct tm *localtime();
                    798:        register struct tm *tm;
                    799:        int flags;
                    800: 
                    801:        if (StartTime == 0)
                    802:                return;
                    803: 
                    804:        fp = fopen(DO_CONNECT_ACCOUNTING, "a");
                    805:        if (fp == NULL) {
                    806:                syslog(LOG_ALERT, "fopen(%s) failed: %m",DO_CONNECT_ACCOUNTING);
                    807:                cleanup(FAIL);
                    808:        }
                    809: 
                    810:        tm = localtime(&StartTime);
                    811: #ifdef F_SETFL
                    812:        flags = fcntl(fileno(fp), F_GETFL, 0);
                    813:        fcntl(fileno(fp), F_SETFL, flags|O_APPEND);
                    814: #endif
                    815: #ifdef USG
                    816:        fprintf(fp,"%s %d %d%.2d%.2d %.2d%.2d %d %ld %s %ld %ld\n",
                    817: #else /* V7 */
                    818:        fprintf(fp,"%s %d %d%02d%02d %02d%02d %d %ld %s %ld %ld\n",
                    819: #endif /* V7 */
                    820:                Rmtname, InitialRole, tm->tm_year, tm->tm_mon + 1,
                    821:                tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_wday,
                    822:                (Now.time - StartTime + 59) / 60, 
                    823:                ttyn == NULL ? "ttyp0" : &ttyn[5],
                    824:                        Bytes_Sent, Bytes_Received);
                    825:        fclose(fp);
                    826: #endif /* DO_CONNECT_ACCOUNTING */
                    827: }
                    828: 
                    829: /*
                    830:  *     on interrupt - remove locks and exit
                    831:  */
                    832: 
                    833: onintr(inter)
                    834: register int inter;
                    835: {
                    836:        char str[BUFSIZ];
                    837:        signal(inter, SIG_IGN);
                    838:        sprintf(str, "(SIGNAL %d)", inter);
                    839:        logent(str, "CAUGHT");
                    840:        US_SST(us_s_intr);
                    841:        if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME))
                    842:                systat(Rmtname, SS_FAIL, str);
                    843:        sprintf(str, "(conversation complete %ld sent %ld received)",
                    844:                Bytes_Sent, Bytes_Received);
                    845:        logent(str, _FAILED);
                    846:        if (inter == SIGPIPE && !onesys)
                    847:                longjmp(Pipebuf, 1);
                    848:        cleanup(inter);
                    849: }
                    850: 
                    851: /*
                    852:  * Catch a special signal
                    853:  * (SIGUSR1), and toggle debugging between 0 and 30.
                    854:  * Handy for looking in on long running uucicos.
                    855:  */
                    856: dbg_signal()
                    857: {
                    858:        Debug = (Debug == 0) ? 30 : 0;
                    859:        setdebug(DBG_PERM);
                    860:        if (Debug > 0)
                    861:                logent("Signal Enabled", "DEBUG");
                    862: }
                    863: 
                    864: 
                    865: /*
                    866:  * Check debugging requests, and open RMTDEBUG audit file if necessary. If an
                    867:  * audit file is needed, the parm argument indicates how to create the file:
                    868:  *
                    869:  *     DBG_TEMP  - Open a temporary file, with filename = RMTDEBUG/pid.
                    870:  *     DBG_PERM  - Open a permanent audit file, filename = RMTDEBUG/Rmtname.
                    871:  *                 If a temp file already exists, it is mv'ed to be permanent.
                    872:  *     DBG_CLEAN - Cleanup; unlink temp files.
                    873:  *
                    874:  * Restrictions - this code can only cope with one open debug file at a time.
                    875:  * Each call creates a new file; if an old one of the same name exists it will
                    876:  * be overwritten.
                    877:  */
                    878: setdebug(parm)
                    879: int parm;
                    880: {
                    881:        char buf[BUFSIZ];               /* Buffer for building filenames     */
                    882:        static char *temp = NULL;       /* Ptr to temporary file name        */
                    883:        static int auditopen = 0;       /* Set to 1 when we open a file      */
                    884:        struct stat stbuf;              /* File status buffer                */
                    885: 
                    886:        /*
                    887:         * If movement or cleanup of a temp file is indicated, we do it no
                    888:         * matter what.
                    889:         */
                    890:        if (temp != CNULL && parm == DBG_PERM) {
                    891:                sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
                    892:                unlink(buf);
                    893:                if (link(temp, buf) != 0) {
                    894:                        Debug = 0;
                    895:                        syslog(LOG_ERR, "RMTDEBUG link(%s,%s) failed: %m",
                    896:                                temp, buf);
                    897:                        cleanup(FAIL);
                    898:                }
                    899:                parm = DBG_CLEAN;
                    900:        }
                    901:        if (parm == DBG_CLEAN) {
                    902:                if (temp != CNULL) {
                    903:                        unlink(temp);
                    904:                        free(temp);
                    905:                        temp = CNULL;
                    906:                }
                    907:                return;
                    908:        }
                    909: 
                    910:        if (Debug == 0)
                    911:                return;         /* Gotta be in debug to come here.   */
                    912: 
                    913:        /*
                    914:         * If we haven't opened a file already, we can just return if it's
                    915:         * alright to use the stderr we came in with. We can if:
                    916:         *
                    917:         *      Role == MASTER, and Stderr is a regular file, a TTY or a pipe.
                    918:         *
                    919:         * Caution: Detecting when stderr is a pipe is tricky, because the 4.2
                    920:         * man page for fstat(2) disagrees with reality, and System V leaves it
                    921:         * undefined, which means different implementations act differently.
                    922:         */
                    923:        if (!auditopen && Role == MASTER) {
                    924:                if (isatty(fileno(stderr)))
                    925:                        return;
                    926:                else if (fstat(fileno(stderr), &stbuf) == 0) {
                    927: #ifdef USG
                    928:                        /* Is Regular File or Fifo   */
                    929:                        if ((stbuf.st_mode & 0060000) == 0)
                    930:                                return;
                    931: #else !USG
                    932: #ifdef BSD4_2
                    933:                                        /* Is Regular File */
                    934:                        if ((stbuf.st_mode & S_IFMT) == S_IFREG ||
                    935:                            stbuf.st_mode == 0)         /* Is a pipe */
                    936:                                return;
                    937: #else !BSD4_2
                    938:                                         /* Is Regular File or Pipe  */
                    939:                        if ((stbuf.st_mode & S_IFMT) == S_IFREG)
                    940:                                return;
                    941: #endif BSD4_2
                    942: #endif USG
                    943:                }
                    944:        }
                    945: 
                    946:        /*
                    947:         * We need RMTDEBUG directory to do auditing. If the file doesn't exist,
                    948:         * then we forget about debugging; if it exists but has improper owner-
                    949:         * ship or modes, we gripe about it in ERRLOG. 
                    950:         */
                    951:        if (stat(RMTDEBUG, &stbuf) != SUCCESS) {
                    952:                Debug = 0;
                    953:                return;
                    954:        }
                    955:        if ((geteuid() != stbuf.st_uid) ||              /* We must own it    */
                    956:            ((stbuf.st_mode & 0170700) != 040700)) {    /* Directory, rwx    */
                    957:                Debug = 0;
                    958:                syslog(LOG_ERR, "%s: invalid directory mode: %o", RMTDEBUG,
                    959:                        stbuf.st_mode);
                    960:                return;
                    961:        }
                    962: 
                    963:        if (parm == DBG_TEMP) {
                    964:                sprintf(buf, "%s/%d", RMTDEBUG, getpid());
                    965:                temp = malloc(strlen (buf) + 1);
                    966:                if (temp == CNULL) {
                    967:                        Debug = 0;
                    968:                        syslog(LOG_ERR, "RMTDEBUG malloc failed: %m");
                    969:                        cleanup(FAIL);
                    970:                }
                    971:                strcpy(temp, buf);
                    972:        } else
                    973:                sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
                    974: 
                    975:        unlink(buf);
                    976:        if (freopen(buf, "w", stderr) != stderr) {
                    977:                Debug = 0;
                    978:                syslog(LOG_ERR, "RMTDEBUG freopen(%s) failed: %m", buf);
                    979:                cleanup(FAIL);
                    980:        }
                    981:        setbuf(stderr, CNULL);
                    982:        auditopen = 1;
                    983: }
                    984: 
                    985: /*
                    986:  *     catch SIGALRM routine
                    987:  */
                    988: timeout()
                    989: {
                    990:        extern int HaveSentHup;
                    991:        if (!HaveSentHup) {
                    992:                logent(Rmtname, "TIMEOUT");
                    993:                if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) {
                    994:                        US_SST(us_s_tmot);
                    995:                        systat(Rmtname, SS_FAIL, "TIMEOUT");
                    996:                }
                    997:        }
                    998:        longjmp(Sjbuf, 1);
                    999: }
                   1000: 
                   1001: static char *
                   1002: pskip(p)
                   1003: register char *p;
                   1004: {
                   1005:        while(*p && *p != ' ')
                   1006:                ++p;
                   1007:        while(*p && *p == ' ')
                   1008:                *p++ = 0;
                   1009:        return p;
                   1010: }
                   1011: 
                   1012: /*
                   1013:  * clobber argv so ps will show what we're doing.
                   1014:  * stolen from sendmail
                   1015:  */
                   1016: /*VARARGS1*/
                   1017: setproctitle(fmt, a, b, c)
                   1018: char *fmt;
                   1019: {
                   1020: #ifdef SETPROCTITLE
                   1021:        register char *p;
                   1022:        register int i;
                   1023:        extern char **Argv;
                   1024:        extern char *LastArgv;
                   1025:        char buf[BUFSIZ];
                   1026: 
                   1027:        (void) sprintf(buf, fmt, a, b, c);
                   1028: 
                   1029:        /* make ps print "(sendmail)" */
                   1030:        p = Argv[0];
                   1031:        *p++ = '-';
                   1032: 
                   1033:        i = strlen(buf);
                   1034:        if (i > LastArgv - p - 2) {
                   1035:                i = LastArgv - p - 2;
                   1036:                buf[i] = '\0';
                   1037:        }
                   1038:        (void) strcpy(p, buf);
                   1039:        p += i;
                   1040:        while (p < LastArgv)
                   1041:                *p++ = ' ';
                   1042: #endif SETPROCTITLE
                   1043: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.