# 2.11BSD#431 - /usr/src/usr.bin/uucp/cico.c

##### Functions

    cleanup           X
    dbg_signal        X
    main              X
    onintr            X
    setdebug          X
    timeout           X

##### Variables

    Hupvec            X
    Pipebuf           X
    ReverseRole       X
    Role              X
    Savettyb          X
    Sjbuf             X
    Stattext          X
    Stattype          X
    onesys            X
    ttyn              X
    turntime          X

##### Macros

    DBG_CLEAN         X
    DBG_PERM          X
    DBG_TEMP          X
    NOGETPEER         X

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

#### Defined functions

cleanup defined in line 667; used 22 times

- in line 216, 264, 277, 300, 323, 336, 363, 370, 382, 423, 441, 460-465(3), 479, 657, 736, 784, 855, 865
- in /usr/src/usr.bin/uucp/chkpth.c line 246
- in /usr/src/usr.bin/uucp/uucp.h line 263

dbg_signal defined in line 744; used 2 times

- in line 94, 111

main defined in line 85; used 1 times

- in /usr/src/usr.bin/uucp/uucp.h line 411

onintr defined in line 724; used 6 times

- in line 94, 106-110(5)

pskip defined in line 887; used 3 times

- in line 95, 284, 386

setdebug defined in line 766; used 6 times

- in line 201, 292, 393, 458, 716, 747

timeout defined in line 874; used 4 times

- in line 94, 252, 527, 626

#### Defined variables

Hupvec defined in line 661; used 4 times

- in line 688-691(4)

Pipebuf defined in line 33; used 2 times

- in line 448, 735

ReverseRole defined in line 64; used 1 times

- in line 136

Role defined in line 65; used 15 times

- in line 133-137(2), 174, 185, 201, 209, 463, 472, 483, 593, 602, 622, 676, 703, 810

Savettyb defined in line 78; used 15 times

- in line 234-241(8), 258-261(2), 272-274(2), 679-680(2), 694

Sjbuf defined in line 32; used 11 times

- in line 254, 525, 600, 639, 884
- in /usr/src/usr.bin/uucp/conn.c line 50, 275, 610
- in /usr/src/usr.bin/uucp/pk1.c line 296, 313, 423

Stattext defined in line 36; used 3 times

- in line 435, 504, 571

Stattype defined in line 48; used 3 times

- in line 435, 503-504(2)

onesys defined in line 66; used 6 times

- in line 143, 231, 456, 654, 734
- in /usr/src/usr.bin/uucp/conn.c line 128

sccsid defined in line 2; never used
ttyn defined in line 68; used 8 times

- in line 243, 443-444(2), 597, 612-615(2), 699-700(2)

turntime defined in line 67; used 4 times

- in line 152
- in /usr/src/usr.bin/uucp/cntrl.c line 144, 509, 573

#### Defined macros

DBG_CLEAN defined in line 62; used 3 times

- in line 716, 786-788(2)

DBG_PERM defined in line 61; used 6 times

- in line 201, 292, 393, 458, 747, 778

DBG_TEMP defined in line 60; used 2 times

- in line 201, 849

NOGETPEER defined in line 29; used 4 times

- in line 97, 157, 315-318(2)

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2656 |