113639Ssam #ifndef lint 2*18616Sralph static char sccsid[] = "@(#)cico.c 5.6 (Berkeley) 04/10/85"; 313639Ssam #endif 413639Ssam 513639Ssam #include "uucp.h" 613639Ssam #include <signal.h> 713639Ssam #include <setjmp.h> 817767Sralph #ifdef USG 913639Ssam #include <termio.h> 1013639Ssam #endif 1117767Sralph #ifndef USG 1213639Ssam #include <sgtty.h> 1313639Ssam #endif 1417767Sralph #ifdef BSDTCP 1517767Sralph #include <netdb.h> 1617767Sralph #include <netinet/in.h> 1717767Sralph #include <sys/socket.h> 1817767Sralph #endif BSDTCP 1917767Sralph #include <sys/stat.h> 2017767Sralph #include "uust.h" 2117767Sralph #include "uusub.h" 2213639Ssam 2317767Sralph jmp_buf Sjbuf; 2417767Sralph jmp_buf Pipebuf; 2513639Ssam 2617767Sralph /* call fail text */ 2713639Ssam char *Stattext[] = { 2813639Ssam "", 2913639Ssam "BAD SYSTEM", 3017767Sralph "WRONG TIME TO CALL", 3113639Ssam "SYSTEM LOCKED", 3213639Ssam "NO DEVICE", 3313639Ssam "DIAL FAILED", 3413639Ssam "LOGIN FAILED", 3513639Ssam "BAD SEQUENCE" 3617767Sralph }; 3713639Ssam 3817767Sralph /* call fail codes */ 3917767Sralph int Stattype[] = { 4017767Sralph 0, 4117767Sralph 0, 4217767Sralph SS_WRONGTIME, 4317767Sralph 0, 4417767Sralph SS_NODEVICE, 4517767Sralph SS_FAIL, 4617767Sralph SS_FAIL, 4717767Sralph SS_BADSEQ 4817767Sralph }; 4913639Ssam 5013639Ssam 5113639Ssam int Errorrate = 0; 5217767Sralph int ReverseRole = 0; 5317767Sralph int StdErrIsTty = 0; 5417767Sralph int Role = SLAVE; 5517767Sralph int onesys = 0; 56*18616Sralph int turntime = 30 * 60; /* 30 minutes expressed in seconds */ 5717767Sralph extern int LocalOnly; 58*18616Sralph extern char MaxGrade, DefMaxGrade; 59*18616Sralph extern char Myfullname[]; 6017767Sralph 6117767Sralph #ifdef USG 6213639Ssam struct termio Savettyb; 6313639Ssam #endif 6417767Sralph #ifndef USG 6513639Ssam struct sgttyb Savettyb; 6613639Ssam #endif 6713639Ssam 6813639Ssam /******* 6913639Ssam * cico - this program is used to place a call to a 7013639Ssam * remote machine, login, and copy files between the two machines. 7113639Ssam */ 7213639Ssam 7313639Ssam main(argc, argv) 7413639Ssam register char *argv[]; 7513639Ssam { 7613639Ssam register int ret; 7713639Ssam int seq; 7813639Ssam char wkpre[NAMESIZE], file[NAMESIZE]; 7917767Sralph char msg[MAXFULLNAME], *q, **alias; 8013639Ssam register char *p; 8113639Ssam extern onintr(), timeout(), setdebug(); 8213639Ssam extern char *pskip(); 8313639Ssam char rflags[30]; 8413639Ssam char *ttyn; 8517767Sralph #if defined(VMS) && defined(BSDTCP) 8617767Sralph u_long Hostnumber = 0; 8717767Sralph #endif VMS && BSDTCP 8813639Ssam 8913639Ssam strcpy(Progname, "uucico"); 9013639Ssam uucpname(Myname); 9113639Ssam 9213639Ssam signal(SIGINT, onintr); 9313639Ssam signal(SIGHUP, onintr); 9413639Ssam signal(SIGQUIT, onintr); 9513639Ssam signal(SIGTERM, onintr); 9613639Ssam signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */ 9713639Ssam signal(SIGFPE, setdebug); 9813639Ssam ret = guinfo(getuid(), User, msg); 9913639Ssam strcpy(Loginuser, User); 10017767Sralph ASSERT(ret == 0, "BAD UID", CNULL, ret); 10113639Ssam 10217767Sralph #ifdef BSD4_2 10317767Sralph setlinebuf(stderr); 10417767Sralph #endif 10513639Ssam rflags[0] = '\0'; 10613639Ssam umask(WFMASK); 10713639Ssam strcpy(Rmtname, Myname); 10813639Ssam Ifn = Ofn = -1; 10913639Ssam while(argc>1 && argv[1][0] == '-'){ 11013639Ssam switch(argv[1][1]){ 11113639Ssam case 'd': 11213639Ssam Spool = &argv[1][2]; 11313639Ssam break; 11413639Ssam case 'g': 115*18616Sralph case 'p': 116*18616Sralph MaxGrade = DefMaxGrade = argv[1][2]; 11713639Ssam break; 11813639Ssam case 'r': 11913639Ssam Role = atoi(&argv[1][2]); 12013639Ssam break; 12117767Sralph case 'R': 12217767Sralph ReverseRole++; 12317767Sralph Role = MASTER; 12417767Sralph break; 12513639Ssam case 's': 12613639Ssam sprintf(Rmtname, "%.7s", &argv[1][2]); 12713639Ssam if (Rmtname[0] != '\0') 12813639Ssam onesys = 1; 12913639Ssam break; 13013639Ssam case 'x': 13117767Sralph chkdebug(); 13213639Ssam Debug = atoi(&argv[1][2]); 13313639Ssam if (Debug <= 0) 13413639Ssam Debug = 1; 13513639Ssam strcat(rflags, argv[1]); 13613639Ssam logent("ENABLED", "DEBUG"); 13713639Ssam break; 138*18616Sralph case 't': 139*18616Sralph turntime = atoi(&argv[1][2])*60;/* minutes to seconds */ 140*18616Sralph break; 14117767Sralph case 'L': /* local calls only */ 14217767Sralph LocalOnly++; 14317767Sralph break; 14417767Sralph #if defined(VMS) && defined(BSDTCP) 14517767Sralph case 'h': 14617767Sralph Hostnumber = inet_addr(&argv[1][2]); 14717767Sralph break; 14817767Sralph #endif VMS && BSDTCP 14913639Ssam default: 15017767Sralph printf("unknown flag %s (ignored)\n", argv[1]); 15113639Ssam break; 15213639Ssam } 15313639Ssam --argc; argv++; 15413639Ssam } 15513639Ssam 15617767Sralph while (argc > 1) { 15717767Sralph printf("unknown argument %s (ignored)\n", argv[1]); 15817767Sralph --argc; argv++; 15917767Sralph } 16017767Sralph 16117767Sralph /* Try to run as uucp -- rti!trt */ 16217767Sralph setgid(getegid()); 16317767Sralph setuid(geteuid()); 16417767Sralph #ifdef TIOCNOTTY 16517767Sralph /* 16617767Sralph * detach uucico from controlling terminal 16717767Sralph * to defend against rlogind sending us a SIGKILL (!!!) 16817767Sralph */ 16917767Sralph if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) { 17017767Sralph ioctl(ret, TIOCNOTTY, STBNULL); 17117767Sralph close(ret); 17217767Sralph } 17317767Sralph #endif TIOCNOTTY 17417767Sralph #ifdef BSD4_2 17517767Sralph if (getpgrp(0) == 0) { /*We have no controlling terminal */ 17617767Sralph setpgrp(0, getpid()); 17717767Sralph } 17817767Sralph #endif BSD4_2 17917767Sralph 18017767Sralph ret = subchdir(Spool); 18117767Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 18213639Ssam strcpy(Wrkdir, Spool); 18313639Ssam 18413639Ssam if (Role == SLAVE) { 18517767Sralph /* check for /etc/nologin */ 18617767Sralph ultouch(); /* sets nologinflag as a side effect */ 18717767Sralph if (nologinflag) { 18817767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 18917767Sralph if (Debug) 19017767Sralph logent("DEBUGGING", "continuing anyway"); 19117767Sralph else 19217767Sralph cleanup(1); 19317767Sralph } 19417767Sralph #ifdef TCPIP 19517767Sralph /* 19617767Sralph * Determine if we are on TCPIP 19717767Sralph */ 19817767Sralph if (isatty(0) == 0) { 19917767Sralph IsTcpIp = 1; 20017767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 20117767Sralph } 20217767Sralph #endif TCPIP 20313639Ssam /* initial handshake */ 20413639Ssam onesys = 1; 20517767Sralph if (!IsTcpIp) { 20617767Sralph #ifdef USG 20713639Ssam ret = ioctl(0, TCGETA, &Savettyb); 20813639Ssam Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; 20913639Ssam Savettyb.c_oflag |= OPOST; 21013639Ssam Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 21117767Sralph #else !USG 21213639Ssam ret = ioctl(0, TIOCGETP, &Savettyb); 21313639Ssam Savettyb.sg_flags |= ECHO; 21413639Ssam Savettyb.sg_flags &= ~RAW; 21517767Sralph #endif !USG 21613639Ssam } 21713639Ssam Ifn = 0; 21813639Ssam Ofn = 1; 21913639Ssam fixmode(Ifn); 22017767Sralph sprintf(file,"%s/%d", RMTDEBUG, getpid()); 22117767Sralph #ifdef VMS 22217767Sralph /* hold the version number down */ 22317767Sralph unlink(file); 22417767Sralph #endif 22517767Sralph freopen(file, "w", stderr); 22617767Sralph #ifdef BSD4_2 22717767Sralph setlinebuf(stderr); 22817767Sralph #else !BSD4_2 22917767Sralph setbuf(stderr, NULL); 23017767Sralph #endif !BSD4_2 231*18616Sralph sprintf(msg, "here=%s", Myfullname); 23217767Sralph omsg('S', msg, Ofn); 23313639Ssam signal(SIGALRM, timeout); 23413639Ssam alarm(MAXMSGTIME); 23513639Ssam if (setjmp(Sjbuf)) { 23613639Ssam /* timed out */ 23717767Sralph if (!IsTcpIp) { 23817767Sralph #ifdef USG 23913639Ssam ret = ioctl(0, TCSETA, &Savettyb); 24013639Ssam #endif 24117767Sralph #ifndef USG 24213639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 24313639Ssam #endif 24413639Ssam } 24517767Sralph cleanup(0); 24613639Ssam } 24713639Ssam for (;;) { 24813639Ssam ret = imsg(msg, Ifn); 24913639Ssam if (ret != 0) { 25013639Ssam alarm(0); 25117767Sralph if (!IsTcpIp) { 25217767Sralph #ifdef USG 25313639Ssam ret = ioctl(0, TCSETA, &Savettyb); 25413639Ssam #endif 25517767Sralph #ifndef USG 25613639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 25713639Ssam #endif 25813639Ssam } 25917767Sralph cleanup(0); 26013639Ssam } 26113639Ssam if (msg[0] == 'S') 26213639Ssam break; 26313639Ssam } 26413639Ssam alarm(0); 26513639Ssam q = &msg[1]; 26613639Ssam p = pskip(q); 26713639Ssam sprintf(Rmtname, "%.7s", q); 26817767Sralph sprintf(wkpre,"%s/%s", RMTDEBUG, Rmtname); 26917767Sralph unlink(wkpre); 27017767Sralph if (link(file, wkpre) == 0) 27117767Sralph unlink(file); 27213639Ssam DEBUG(4, "sys-%s\n", Rmtname); 27317767Sralph #ifdef BSDTCP 27417767Sralph /* we must make sure they are really who they say they 27517767Sralph * are. We compare the hostnumber with the number in the hosts 27617767Sralph * table for the site they claim to be. 27717767Sralph */ 27817767Sralph if (IsTcpIp) { 27917767Sralph struct hostent *hp; 28017767Sralph char *cpnt, *inet_ntoa(); 28117767Sralph int fromlen; 28217767Sralph struct sockaddr_in from; 28317767Sralph 28417767Sralph #ifndef VMS 28517767Sralph fromlen = sizeof(from); 28617767Sralph if (getpeername(0, &from, &fromlen) < 0) { 28717767Sralph logent(Rmtname, "NOT A TCP CONNECTION"); 28817767Sralph omsg('R', "NOT TCP", Ofn); 28917767Sralph cleanup(0); 29017767Sralph } 29117767Sralph #else VMS 29217767Sralph from.sin_addr.s_addr = Hostnumber; 29317767Sralph from.sin_family = AF_INET; 29417767Sralph #endif VMS 29517767Sralph hp = gethostbyaddr(&from.sin_addr, 29617767Sralph sizeof (struct in_addr), from.sin_family); 29717767Sralph if (hp == 0) { 29817767Sralph /* security break or just old host table? */ 29917767Sralph logent(Rmtname, "UNKNOWN IP-HOST Name ="); 30017767Sralph cpnt = inet_ntoa(from.sin_addr), 30117767Sralph logent(cpnt, "UNKNOWN IP-HOST Number ="); 30217767Sralph sprintf(wkpre, "%s/%s isn't in my host table", 30317767Sralph Rmtname, cpnt); 30417767Sralph omsg('R' ,wkpre ,Ofn); 30517767Sralph cleanup(0); 30617767Sralph } 30717767Sralph if (Debug>99) 30817767Sralph logent(Rmtname,"Request from IP-Host name ="); 30917767Sralph /* The following is to determine if the name given us by 31017767Sralph * the Remote uucico matches any of the names(aliases) 31117767Sralph * given its network number (remote machine) in our 31217767Sralph * host table. 31317767Sralph */ 31417767Sralph if (strncmp(q, hp->h_name, 7) == 0) { 31517767Sralph if (Debug > 99) 31617767Sralph logent(q,"Found in host Tables"); 31717767Sralph } else { /* Scan The host aliases */ 31817767Sralph for(alias=hp->h_aliases; *alias!=0 && 31917767Sralph strncmp(q, *alias, 7) != 0; ++alias) 32017767Sralph ; 32117767Sralph if (strncmp(q, *alias, 7) != 0) { 32217767Sralph logent(q, "FORGED HOSTNAME"); 32317767Sralph logent(inet_ntoa(from.sin_addr), "ORIGINATED AT"); 32417767Sralph omsg('R',"You're not who you claim to be"); 32517767Sralph cleanup(0); 32617767Sralph } 32717767Sralph #ifdef DEBUG 32817767Sralph if (Debug> 99) 32917767Sralph logent(q,"Found in host Tables"); 33017767Sralph #endif 33117767Sralph } 33217767Sralph } 33317767Sralph #endif BSDTCP 33417767Sralph 33517767Sralph #ifdef NOSTRANGERS 33617767Sralph /* If we don't know them, we won't talk to them... */ 337*18616Sralph if (versys(&Rmtname)) { 33817767Sralph logent(Rmtname, "UNKNOWN HOST"); 33917767Sralph omsg('R', "You are unknown to me", Ofn); 34017767Sralph cleanup(0); 34117767Sralph } 34217767Sralph #endif NOSTRANGERS 34313639Ssam if (mlock(Rmtname)) { 34413639Ssam omsg('R', "LCK", Ofn); 34513639Ssam cleanup(0); 34613639Ssam } 34713639Ssam else if (callback(Loginuser)) { 34813639Ssam signal(SIGINT, SIG_IGN); 34913639Ssam signal(SIGHUP, SIG_IGN); 35013639Ssam omsg('R', "CB", Ofn); 35113639Ssam logent("CALLBACK", "REQUIRED"); 35213639Ssam /* set up for call back */ 35317767Sralph systat(Rmtname, SS_CALLBACK, "CALLING BACK"); 35413639Ssam gename(CMDPRE, Rmtname, 'C', file); 35513639Ssam close(creat(subfile(file), 0666)); 35613639Ssam xuucico(Rmtname); 35713639Ssam cleanup(0); 35813639Ssam } 35913639Ssam seq = 0; 36013639Ssam while (*p == '-') { 36113639Ssam q = pskip(p); 36213639Ssam switch(*(++p)) { 36313639Ssam case 'x': 36413639Ssam Debug = atoi(++p); 36513639Ssam if (Debug <= 0) 36613639Ssam Debug = 1; 36713639Ssam break; 36813639Ssam case 'Q': 36913639Ssam seq = atoi(++p); 37013639Ssam break; 371*18616Sralph case 'p': 372*18616Sralph MaxGrade = DefMaxGrade = *++p; 373*18616Sralph DEBUG(4, "MaxGrade set to %c\n", MaxGrade); 374*18616Sralph break; 37513639Ssam default: 37613639Ssam break; 37713639Ssam } 37813639Ssam p = q; 37913639Ssam } 38013639Ssam if (callok(Rmtname) == SS_BADSEQ) { 38113639Ssam logent("BADSEQ", "PREVIOUS"); 38213639Ssam omsg('R', "BADSEQ", Ofn); 38313639Ssam cleanup(0); 38413639Ssam } 38517767Sralph #ifdef GNXSEQ 38613639Ssam if ((ret = gnxseq(Rmtname)) == seq) { 38713639Ssam omsg('R', "OK", Ofn); 38813639Ssam cmtseq(); 38917767Sralph } else { 39017767Sralph #else !GNXSEQ 39117767Sralph if (seq == 0) 39217767Sralph omsg('R', "OK", Ofn); 39313639Ssam else { 39417767Sralph #endif !GNXSEQ 39513639Ssam systat(Rmtname, Stattype[7], Stattext[7]); 39617767Sralph logent("BAD SEQ", "HANDSHAKE FAIL"); 39717767Sralph #ifdef GNXSEQ 39813639Ssam ulkseq(); 39917767Sralph #endif GNXSEQ 40013639Ssam omsg('R', "BADSEQ", Ofn); 40113639Ssam cleanup(0); 40213639Ssam } 40313639Ssam ttyn = ttyname(Ifn); 40413639Ssam if (ttyn != NULL) 40513639Ssam chmod(ttyn, 0600); 40617767Sralph } else { /* Role == MASTER */ 40717767Sralph struct stat stbuf; 40817767Sralph if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0 40917767Sralph && stbuf.st_mode&S_IFREG) ) 41017767Sralph StdErrIsTty = 1; 41117767Sralph setdebug(0); 41213639Ssam } 41317767Sralph 41413639Ssam loop: 41517767Sralph if(setjmp(Pipebuf)) { /* come here on SIGPIPE */ 41617767Sralph clsacu(); 41717767Sralph close(Ofn); 41817767Sralph close(Ifn); 41917767Sralph Ifn = Ofn = -1; 42017767Sralph rmlock(CNULL); 42117767Sralph sleep(3); 42217767Sralph } 42313639Ssam if (!onesys) { 42417767Sralph struct stat sbuf; 42517767Sralph 42617767Sralph if (!StdErrIsTty) { 42717767Sralph sprintf(file, "%s/%s", RMTDEBUG, Rmtname); 42817767Sralph if (stat(file, &sbuf) == 0 && sbuf.st_size == 0) 42917767Sralph unlink(file); 43017767Sralph } 43113639Ssam ret = gnsys(Rmtname, Spool, CMDPRE); 43217767Sralph setdebug(0); 43313639Ssam if (ret == FAIL) 43413639Ssam cleanup(100); 43513639Ssam if (ret == 0) 43613639Ssam cleanup(0); 43717767Sralph } else if (Role == MASTER && callok(Rmtname) != 0) { 43813639Ssam logent("SYSTEM STATUS", "CAN NOT CALL"); 43913639Ssam cleanup(0); 44013639Ssam } 44113639Ssam 44213639Ssam sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname); 44313639Ssam 44417767Sralph signal(SIGINT, SIG_IGN); 44517767Sralph signal(SIGQUIT, SIG_IGN); 44613639Ssam if (Role == MASTER) { 44717767Sralph /* check for /etc/nologin */ 44817767Sralph ultouch(); /* sets nologinflag as a side effect */ 44917767Sralph if (nologinflag) { 45017767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 45117767Sralph if (Debug) 45217767Sralph logent("DEBUGGING", "continuing anyway"); 45317767Sralph else 45417767Sralph cleanup(1); 45517767Sralph } 45613639Ssam /* master part */ 45713639Ssam signal(SIGHUP, SIG_IGN); 458*18616Sralph MaxGrade = DefMaxGrade; 45913639Ssam if (!iswrk(file, "chk", Spool, wkpre) && !onesys) { 46013639Ssam logent(Rmtname, "NO WORK"); 46113639Ssam goto next; 46213639Ssam } 46313639Ssam if (Ifn != -1 && Role == MASTER) { 46413639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 46513639Ssam clsacu(); 46613639Ssam close(Ofn); 46713639Ssam close(Ifn); 46813639Ssam Ifn = Ofn = -1; 46913639Ssam rmlock(CNULL); 47013639Ssam sleep(3); 47113639Ssam } 47213639Ssam sprintf(msg, "call to %s ", Rmtname); 47313639Ssam if (mlock(Rmtname) != 0) { 47413639Ssam logent(msg, "LOCKED"); 47517767Sralph US_SST(us_s_lock); 47613639Ssam goto next; 47713639Ssam } 47813639Ssam Ofn = Ifn = conn(Rmtname); 47913639Ssam if (Ofn < 0) { 48017767Sralph if (Ofn != CF_TIME) 48117767Sralph logent(msg, _FAILED); 48217767Sralph /* avoid excessive 'wrong time' info */ 48317767Sralph if (Stattype[-Ofn] != SS_WRONGTIME || argv[0][0] != 'U'){ 48417767Sralph systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]); 48517767Sralph US_SST(-Ofn); 48617767Sralph UB_SST(-Ofn); 48717767Sralph } 48813639Ssam goto next; 48917767Sralph } else { 49013639Ssam logent(msg, "SUCCEEDED"); 49117767Sralph US_SST(us_s_cok); 49217767Sralph UB_SST(ub_ok); 49313639Ssam } 49417767Sralph #ifdef TCPIP 49517767Sralph /* 49617767Sralph * Determine if we are on TCPIP 49717767Sralph */ 49817767Sralph if (isatty(Ifn) == 0) { 49917767Sralph IsTcpIp = 1; 50017767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 50117767Sralph } 50217767Sralph #endif 50317767Sralph 50413639Ssam if (setjmp(Sjbuf)) 50513639Ssam goto next; 50613639Ssam signal(SIGALRM, timeout); 50713639Ssam alarm(2 * MAXMSGTIME); 50813639Ssam for (;;) { 50913639Ssam ret = imsg(msg, Ifn); 51013639Ssam if (ret != 0) { 51113639Ssam alarm(0); 51217767Sralph logent("imsg 1", _FAILED); 51317767Sralph goto Failure; 51413639Ssam } 51513639Ssam if (msg[0] == 'S') 51613639Ssam break; 51713639Ssam } 51813639Ssam alarm(MAXMSGTIME); 51917767Sralph #ifdef GNXSEQ 52013639Ssam seq = gnxseq(Rmtname); 52117767Sralph #else !GNXSEQ 52217767Sralph seq = 0; 52317767Sralph #endif !GNXSEQ 524*18616Sralph if (MaxGrade != '\177') { 525*18616Sralph char buf[10]; 526*18616Sralph sprintf(buf, " -p%c", MaxGrade); 527*18616Sralph strcat(rflags, buf); 528*18616Sralph } 529*18616Sralph 53013639Ssam sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags); 53113639Ssam omsg('S', msg, Ofn); 53213639Ssam for (;;) { 53313639Ssam ret = imsg(msg, Ifn); 53413639Ssam DEBUG(4, "msg-%s\n", msg); 53517767Sralph if (ret != SUCCESS) { 53613639Ssam alarm(0); 53717767Sralph #ifdef GNXSEQ 53813639Ssam ulkseq(); 53917767Sralph #endif GNXSEQ 54017767Sralph logent("imsg 2", _FAILED); 54117767Sralph goto Failure; 54213639Ssam } 54313639Ssam if (msg[0] == 'R') 54413639Ssam break; 54513639Ssam } 54613639Ssam alarm(0); 54713639Ssam if (msg[1] == 'B') { 54813639Ssam /* bad sequence */ 54917767Sralph logent("BAD SEQ", "HANDSHAKE FAIL"); 55017767Sralph US_SST(us_s_hand); 55117767Sralph systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]); 55217767Sralph #ifdef GNXSEQ 55313639Ssam ulkseq(); 55417767Sralph #endif GNXSEQ 55513639Ssam goto next; 55613639Ssam } 55713639Ssam if (strcmp(&msg[1], "OK") != SAME) { 55817767Sralph logent(&msg[1], "HANDSHAKE FAIL"); 55917767Sralph US_SST(us_s_hand); 56017767Sralph #ifdef GNXSEQ 56113639Ssam ulkseq(); 56217767Sralph #endif GNXSEQ 56317767Sralph systat(Rmtname, SS_INPROGRESS, 56417767Sralph strcmp(&msg[1], "CB") == SAME? 56517767Sralph "AWAITING CALLBACK": "HANDSHAKE FAIL"); 56613639Ssam goto next; 56713639Ssam } 56817767Sralph #ifdef GNXSEQ 56913639Ssam cmtseq(); 57017767Sralph #endif GNXSEQ 57113639Ssam } 57217767Sralph DEBUG(1, "Rmtname %s, ", Rmtname); 57313639Ssam DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); 57413639Ssam DEBUG(1, "Ifn - %d, ", Ifn); 57513639Ssam DEBUG(1, "Loginuser - %s\n", Loginuser); 57613639Ssam 57713639Ssam alarm(MAXMSGTIME); 578*18616Sralph if (ret=setjmp(Sjbuf)) 57913639Ssam goto Failure; 58013639Ssam ret = startup(Role); 58113639Ssam alarm(0); 58213639Ssam if (ret != SUCCESS) { 58317767Sralph logent("startup", _FAILED); 58413639Ssam Failure: 58517767Sralph US_SST(us_s_start); 586*18616Sralph systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" : 587*18616Sralph "STARTUP FAILED"); 58813639Ssam goto next; 58917767Sralph } else { 59013639Ssam logent("startup", "OK"); 59117767Sralph US_SST(us_s_gress); 59213639Ssam systat(Rmtname, SS_INPROGRESS, "TALKING"); 59313639Ssam ret = cntrl(Role, wkpre); 59413639Ssam DEBUG(1, "cntrl - %d\n", ret); 59513639Ssam signal(SIGINT, SIG_IGN); 59613639Ssam signal(SIGHUP, SIG_IGN); 59713639Ssam signal(SIGALRM, timeout); 59817767Sralph if (ret == SUCCESS) { 59913639Ssam logent("conversation complete", "OK"); 60017767Sralph US_SST(us_s_ok); 60113639Ssam rmstat(Rmtname); 60213639Ssam 60317767Sralph } else { 60417767Sralph logent("conversation complete", _FAILED); 60517767Sralph US_SST(us_s_cf); 60617767Sralph systat(Rmtname, SS_FAIL, "CONVERSATION FAILED"); 60713639Ssam } 60813639Ssam alarm(MAXMSGTIME); 60913639Ssam DEBUG(4, "send OO %d,", ret); 61013639Ssam if (!setjmp(Sjbuf)) { 61113639Ssam for (;;) { 61213639Ssam omsg('O', "OOOOO", Ofn); 61313639Ssam ret = imsg(msg, Ifn); 61413639Ssam if (ret != 0) 61513639Ssam break; 61613639Ssam if (msg[0] == 'O') 61713639Ssam break; 61813639Ssam } 61913639Ssam } 62013639Ssam alarm(0); 62117767Sralph clsacu(); 62217767Sralph rmlock(CNULL); 62313639Ssam } 62413639Ssam next: 62513639Ssam if (!onesys) { 62613639Ssam goto loop; 62713639Ssam } 62813639Ssam cleanup(0); 62913639Ssam } 63013639Ssam 63117767Sralph #ifndef USG 63213639Ssam struct sgttyb Hupvec; 63313639Ssam #endif 63413639Ssam 63513639Ssam /*** 63613639Ssam * cleanup(code) cleanup and exit with "code" status 63713639Ssam * int code; 63813639Ssam */ 63913639Ssam 64013639Ssam cleanup(code) 64113639Ssam register int code; 64213639Ssam { 64313639Ssam register int ret; 64413639Ssam register char *ttyn; 64517767Sralph char bfr[BUFSIZ]; 64617767Sralph struct stat sbuf; 64713639Ssam 64813639Ssam signal(SIGINT, SIG_IGN); 64913639Ssam signal(SIGHUP, SIG_IGN); 65013639Ssam rmlock(CNULL); 65113639Ssam clsacu(); 65213639Ssam logcls(); 65313639Ssam if (Role == SLAVE) { 65417767Sralph if (!IsTcpIp) { 65517767Sralph #ifdef USG 65613639Ssam Savettyb.c_cflag |= HUPCL; 65713639Ssam ret = ioctl(0, TCSETA, &Savettyb); 65817767Sralph #else !USG 65913639Ssam ret = ioctl(0, TIOCHPCL, STBNULL); 660*18616Sralph #ifdef TIOCSDTR 661*18616Sralph ret = ioctl(0, TIOCCDTR, STBNULL); 662*18616Sralph sleep(2); 663*18616Sralph ret = ioctl(0, TIOCSDTR, STBNULL); 664*18616Sralph #else !TIOCSDTR 66513639Ssam ret = ioctl(0, TIOCGETP, &Hupvec); 666*18616Sralph #endif !TIOCSDTR 66713639Ssam Hupvec.sg_ispeed = B0; 66813639Ssam Hupvec.sg_ospeed = B0; 66913639Ssam ret = ioctl(0, TIOCSETP, &Hupvec); 67013639Ssam sleep(2); 67113639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 67217767Sralph /* make *sure* exclusive access is off */ 67317767Sralph ret = ioctl(0, TIOCNXCL, STBNULL); 67417767Sralph #endif !USG 67513639Ssam DEBUG(4, "ret ioctl - %d\n", ret); 67613639Ssam } 67713639Ssam ttyn = ttyname(Ifn); 67813639Ssam if (ttyn != NULL) 67913639Ssam chmod(ttyn, 0600); 68013639Ssam } 68113639Ssam if (Ofn != -1) { 68213639Ssam if (Role == MASTER) 68313639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 68413639Ssam close(Ifn); 68513639Ssam close(Ofn); 68613639Ssam } 687*18616Sralph #ifdef DIALINOUT 688*18616Sralph /* reenable logins on dialout */ 689*18616Sralph reenable(); 690*18616Sralph #endif DIALINOUT 69113639Ssam if (code == 0) 69213639Ssam xuuxqt(); 69317767Sralph else 69417767Sralph DEBUG(1, "exit code %d\n", code); 69517767Sralph sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname); 69617767Sralph if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0) 69717767Sralph unlink(bfr); 69817767Sralph sprintf(bfr, "%s/%d", RMTDEBUG, getpid()); 69917767Sralph unlink(bfr); 70013639Ssam exit(code); 70113639Ssam } 70213639Ssam 70313639Ssam /*** 70413639Ssam * onintr(inter) interrupt - remove locks and exit 70513639Ssam */ 70613639Ssam 70713639Ssam onintr(inter) 70813639Ssam register int inter; 70913639Ssam { 71013639Ssam char str[30]; 71113639Ssam signal(inter, SIG_IGN); 71213639Ssam sprintf(str, "SIGNAL %d", inter); 71313639Ssam logent(str, "CAUGHT"); 71417767Sralph US_SST(us_s_intr); 715*18616Sralph if (*Rmtname && strncmp(Rmtname, Myname, 7)) 71617767Sralph systat(Rmtname, SS_FAIL, str); 71717767Sralph if (inter == SIGPIPE && !onesys) 71817767Sralph longjmp(Pipebuf, 1); 71913639Ssam cleanup(inter); 72013639Ssam } 72113639Ssam 72213639Ssam /* 72313639Ssam * Catch a special signal 72413639Ssam * (SIGFPE, ugh), and toggle debugging between 0 and 30. 72513639Ssam * Handy for looking in on long running uucicos. 72613639Ssam */ 72717767Sralph setdebug(code) 72817767Sralph int code; 72913639Ssam { 73017767Sralph char buf[BUFSIZ]; 73117767Sralph 73217767Sralph if (!StdErrIsTty) { 73317767Sralph sprintf(buf,"%s/%s", RMTDEBUG, Rmtname); 73417767Sralph unlink(buf); 73517767Sralph freopen(buf, "w", stderr); 73617767Sralph #ifdef BSD4_2 73717767Sralph setlinebuf(stderr); 73817767Sralph #else !BSD4_2 73917767Sralph setbuf(stderr, NULL); 74017767Sralph #endif !BSD4_2 74117767Sralph } 74217767Sralph if (code) { 74317767Sralph if (Debug == 0) 74417767Sralph Debug = 30; 74517767Sralph else 74617767Sralph Debug = 0; 74717767Sralph } 74813639Ssam } 74913639Ssam 75013639Ssam 75113639Ssam /*** 75213639Ssam * fixmode(tty) fix kill/echo/raw on line 75313639Ssam * 75413639Ssam * return codes: none 75513639Ssam */ 75613639Ssam 75713639Ssam fixmode(tty) 75813639Ssam register int tty; 75913639Ssam { 76017767Sralph #ifdef USG 76113639Ssam struct termio ttbuf; 76213639Ssam #endif 76317767Sralph #ifndef USG 76413639Ssam struct sgttyb ttbuf; 76513639Ssam #endif 76613639Ssam register int ret; 76713639Ssam 76817767Sralph if (IsTcpIp) 76913639Ssam return; 77017767Sralph #ifdef USG 77117767Sralph ret = ioctl(tty, TCGETA, &ttbuf); 77213639Ssam ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 77313639Ssam ttbuf.c_cflag &= (CBAUD); 77413639Ssam ttbuf.c_cflag |= (CS8|CREAD); 77513639Ssam ttbuf.c_cc[VMIN] = 6; 77613639Ssam ttbuf.c_cc[VTIME] = 1; 77713639Ssam ret = ioctl(tty, TCSETA, &ttbuf); 77813639Ssam #endif 77917767Sralph #ifndef USG 78013639Ssam ioctl(tty, TIOCGETP, &ttbuf); 78113639Ssam ttbuf.sg_flags = (ANYP | RAW); 78213639Ssam ret = ioctl(tty, TIOCSETP, &ttbuf); 78313639Ssam #endif 78417767Sralph /* ASSERT(ret >= 0, "STTY FAILED", CNULL, ret); */ 78517767Sralph #ifndef USG 78617767Sralph ret = ioctl(tty, TIOCEXCL, STBNULL); 78713639Ssam #endif 78813639Ssam } 78913639Ssam 79013639Ssam 79113639Ssam /*** 79213639Ssam * timeout() catch SIGALRM routine 79313639Ssam */ 79413639Ssam 79513639Ssam timeout() 79613639Ssam { 79713639Ssam logent(Rmtname, "TIMEOUT"); 798*18616Sralph if (*Rmtname && strncmp(Rmtname, Myname, 7)) { 79917767Sralph US_SST(us_s_tmot); 80017767Sralph systat(Rmtname, SS_FAIL, "TIMEOUT"); 80117767Sralph } 80213639Ssam longjmp(Sjbuf, 1); 80313639Ssam } 80413639Ssam 80513639Ssam static char * 80613639Ssam pskip(p) 80713639Ssam register char *p; 80813639Ssam { 80917767Sralph while(*p && *p != ' ') 81013639Ssam ++p; 81117767Sralph if(*p) 81217767Sralph *p++ = 0; 81317767Sralph return p; 81413639Ssam } 815