113639Ssam #ifndef lint 2*17767Sralph static char sccsid[] = "@(#)cico.c 5.5 (Berkeley) 01/22/85"; 313639Ssam #endif 413639Ssam 513639Ssam #include "uucp.h" 613639Ssam #include <signal.h> 713639Ssam #include <setjmp.h> 813639Ssam #include <sys/types.h> 9*17767Sralph #ifdef USG 1013639Ssam #include <termio.h> 1113639Ssam #endif 12*17767Sralph #ifndef USG 1313639Ssam #include <sgtty.h> 1413639Ssam #endif 15*17767Sralph #ifdef BSDTCP 16*17767Sralph #include <netdb.h> 17*17767Sralph #include <netinet/in.h> 18*17767Sralph #include <sys/socket.h> 19*17767Sralph #endif BSDTCP 20*17767Sralph #include <sys/stat.h> 21*17767Sralph #include "uust.h" 22*17767Sralph #include "uusub.h" 2313639Ssam 24*17767Sralph jmp_buf Sjbuf; 25*17767Sralph jmp_buf Pipebuf; 2613639Ssam 27*17767Sralph /* call fail text */ 2813639Ssam char *Stattext[] = { 2913639Ssam "", 3013639Ssam "BAD SYSTEM", 31*17767Sralph "WRONG TIME TO CALL", 3213639Ssam "SYSTEM LOCKED", 3313639Ssam "NO DEVICE", 3413639Ssam "DIAL FAILED", 3513639Ssam "LOGIN FAILED", 3613639Ssam "BAD SEQUENCE" 37*17767Sralph }; 3813639Ssam 39*17767Sralph /* call fail codes */ 40*17767Sralph int Stattype[] = { 41*17767Sralph 0, 42*17767Sralph 0, 43*17767Sralph SS_WRONGTIME, 44*17767Sralph 0, 45*17767Sralph SS_NODEVICE, 46*17767Sralph SS_FAIL, 47*17767Sralph SS_FAIL, 48*17767Sralph SS_BADSEQ 49*17767Sralph }; 5013639Ssam 5113639Ssam 5213639Ssam int Errorrate = 0; 53*17767Sralph int ReverseRole = 0; 54*17767Sralph int StdErrIsTty = 0; 55*17767Sralph int Role = SLAVE; 56*17767Sralph int onesys = 0; 57*17767Sralph extern int LocalOnly; 58*17767Sralph extern char MaxGrade; 59*17767Sralph 60*17767Sralph #ifdef USG 6113639Ssam struct termio Savettyb; 6213639Ssam #endif 63*17767Sralph #ifndef USG 6413639Ssam struct sgttyb Savettyb; 6513639Ssam #endif 6613639Ssam 6713639Ssam /******* 6813639Ssam * cico - this program is used to place a call to a 6913639Ssam * remote machine, login, and copy files between the two machines. 7013639Ssam */ 7113639Ssam 7213639Ssam main(argc, argv) 7313639Ssam register char *argv[]; 7413639Ssam { 7513639Ssam register int ret; 7613639Ssam int seq; 7713639Ssam char wkpre[NAMESIZE], file[NAMESIZE]; 78*17767Sralph char msg[MAXFULLNAME], *q, **alias; 7913639Ssam register char *p; 8013639Ssam extern onintr(), timeout(), setdebug(); 8113639Ssam extern char *pskip(); 8213639Ssam char rflags[30]; 8313639Ssam char *ttyn; 84*17767Sralph #if defined(VMS) && defined(BSDTCP) 85*17767Sralph u_long Hostnumber = 0; 86*17767Sralph #endif VMS && BSDTCP 8713639Ssam 8813639Ssam strcpy(Progname, "uucico"); 8913639Ssam uucpname(Myname); 9013639Ssam 9113639Ssam signal(SIGINT, onintr); 9213639Ssam signal(SIGHUP, onintr); 9313639Ssam signal(SIGQUIT, onintr); 9413639Ssam signal(SIGTERM, onintr); 9513639Ssam signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */ 9613639Ssam signal(SIGFPE, setdebug); 9713639Ssam ret = guinfo(getuid(), User, msg); 9813639Ssam strcpy(Loginuser, User); 99*17767Sralph ASSERT(ret == 0, "BAD UID", CNULL, ret); 10013639Ssam 101*17767Sralph #ifdef BSD4_2 102*17767Sralph setlinebuf(stderr); 103*17767Sralph #endif 10413639Ssam rflags[0] = '\0'; 10513639Ssam umask(WFMASK); 10613639Ssam strcpy(Rmtname, Myname); 10713639Ssam Ifn = Ofn = -1; 10813639Ssam while(argc>1 && argv[1][0] == '-'){ 10913639Ssam switch(argv[1][1]){ 11013639Ssam case 'd': 11113639Ssam Spool = &argv[1][2]; 11213639Ssam break; 11313639Ssam case 'g': 114*17767Sralph MaxGrade = argv[1][2]; 11513639Ssam break; 11613639Ssam case 'r': 11713639Ssam Role = atoi(&argv[1][2]); 11813639Ssam break; 119*17767Sralph case 'R': 120*17767Sralph ReverseRole++; 121*17767Sralph Role = MASTER; 122*17767Sralph break; 12313639Ssam case 's': 12413639Ssam sprintf(Rmtname, "%.7s", &argv[1][2]); 12513639Ssam if (Rmtname[0] != '\0') 12613639Ssam onesys = 1; 12713639Ssam break; 12813639Ssam case 'x': 129*17767Sralph chkdebug(); 13013639Ssam Debug = atoi(&argv[1][2]); 13113639Ssam if (Debug <= 0) 13213639Ssam Debug = 1; 13313639Ssam strcat(rflags, argv[1]); 13413639Ssam logent("ENABLED", "DEBUG"); 13513639Ssam break; 136*17767Sralph case 'L': /* local calls only */ 137*17767Sralph LocalOnly++; 138*17767Sralph break; 139*17767Sralph #if defined(VMS) && defined(BSDTCP) 140*17767Sralph case 'h': 141*17767Sralph Hostnumber = inet_addr(&argv[1][2]); 142*17767Sralph break; 143*17767Sralph #endif VMS && BSDTCP 14413639Ssam default: 145*17767Sralph printf("unknown flag %s (ignored)\n", argv[1]); 14613639Ssam break; 14713639Ssam } 14813639Ssam --argc; argv++; 14913639Ssam } 15013639Ssam 151*17767Sralph while (argc > 1) { 152*17767Sralph printf("unknown argument %s (ignored)\n", argv[1]); 153*17767Sralph --argc; argv++; 154*17767Sralph } 155*17767Sralph 156*17767Sralph /* Try to run as uucp -- rti!trt */ 157*17767Sralph setgid(getegid()); 158*17767Sralph setuid(geteuid()); 159*17767Sralph #ifdef TIOCNOTTY 160*17767Sralph /* 161*17767Sralph * detach uucico from controlling terminal 162*17767Sralph * to defend against rlogind sending us a SIGKILL (!!!) 163*17767Sralph */ 164*17767Sralph if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) { 165*17767Sralph ioctl(ret, TIOCNOTTY, STBNULL); 166*17767Sralph close(ret); 167*17767Sralph } 168*17767Sralph #endif TIOCNOTTY 169*17767Sralph #ifdef BSD4_2 170*17767Sralph if (getpgrp(0) == 0) { /*We have no controlling terminal */ 171*17767Sralph setpgrp(0, getpid()); 172*17767Sralph } 173*17767Sralph #endif BSD4_2 174*17767Sralph 175*17767Sralph ret = subchdir(Spool); 176*17767Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 17713639Ssam strcpy(Wrkdir, Spool); 17813639Ssam 17913639Ssam if (Role == SLAVE) { 180*17767Sralph /* check for /etc/nologin */ 181*17767Sralph ultouch(); /* sets nologinflag as a side effect */ 182*17767Sralph if (nologinflag) { 183*17767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 184*17767Sralph if (Debug) 185*17767Sralph logent("DEBUGGING", "continuing anyway"); 186*17767Sralph else 187*17767Sralph cleanup(1); 188*17767Sralph } 189*17767Sralph #ifdef TCPIP 190*17767Sralph /* 191*17767Sralph * Determine if we are on TCPIP 192*17767Sralph */ 193*17767Sralph if (isatty(0) == 0) { 194*17767Sralph IsTcpIp = 1; 195*17767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 196*17767Sralph } 197*17767Sralph #endif TCPIP 19813639Ssam /* initial handshake */ 19913639Ssam onesys = 1; 200*17767Sralph if (!IsTcpIp) { 201*17767Sralph #ifdef USG 20213639Ssam ret = ioctl(0, TCGETA, &Savettyb); 20313639Ssam Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; 20413639Ssam Savettyb.c_oflag |= OPOST; 20513639Ssam Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 206*17767Sralph #else !USG 20713639Ssam ret = ioctl(0, TIOCGETP, &Savettyb); 20813639Ssam Savettyb.sg_flags |= ECHO; 20913639Ssam Savettyb.sg_flags &= ~RAW; 210*17767Sralph #endif !USG 21113639Ssam } 21213639Ssam Ifn = 0; 21313639Ssam Ofn = 1; 21413639Ssam fixmode(Ifn); 215*17767Sralph sprintf(file,"%s/%d", RMTDEBUG, getpid()); 216*17767Sralph #ifdef VMS 217*17767Sralph /* hold the version number down */ 218*17767Sralph unlink(file); 219*17767Sralph #endif 220*17767Sralph freopen(file, "w", stderr); 221*17767Sralph #ifdef BSD4_2 222*17767Sralph setlinebuf(stderr); 223*17767Sralph #else !BSD4_2 224*17767Sralph setbuf(stderr, NULL); 225*17767Sralph #endif !BSD4_2 226*17767Sralph sprintf(msg, "here=%s", Myname); 227*17767Sralph omsg('S', msg, Ofn); 22813639Ssam signal(SIGALRM, timeout); 22913639Ssam alarm(MAXMSGTIME); 23013639Ssam if (setjmp(Sjbuf)) { 23113639Ssam /* timed out */ 232*17767Sralph if (!IsTcpIp) { 233*17767Sralph #ifdef USG 23413639Ssam ret = ioctl(0, TCSETA, &Savettyb); 23513639Ssam #endif 236*17767Sralph #ifndef USG 23713639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 23813639Ssam #endif 23913639Ssam } 240*17767Sralph cleanup(0); 24113639Ssam } 24213639Ssam for (;;) { 24313639Ssam ret = imsg(msg, Ifn); 24413639Ssam if (ret != 0) { 24513639Ssam alarm(0); 246*17767Sralph if (!IsTcpIp) { 247*17767Sralph #ifdef USG 24813639Ssam ret = ioctl(0, TCSETA, &Savettyb); 24913639Ssam #endif 250*17767Sralph #ifndef USG 25113639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 25213639Ssam #endif 25313639Ssam } 254*17767Sralph cleanup(0); 25513639Ssam } 25613639Ssam if (msg[0] == 'S') 25713639Ssam break; 25813639Ssam } 25913639Ssam alarm(0); 26013639Ssam q = &msg[1]; 26113639Ssam p = pskip(q); 26213639Ssam sprintf(Rmtname, "%.7s", q); 263*17767Sralph sprintf(wkpre,"%s/%s", RMTDEBUG, Rmtname); 264*17767Sralph unlink(wkpre); 265*17767Sralph if (link(file, wkpre) == 0) 266*17767Sralph unlink(file); 26713639Ssam DEBUG(4, "sys-%s\n", Rmtname); 268*17767Sralph #ifdef BSDTCP 269*17767Sralph /* we must make sure they are really who they say they 270*17767Sralph * are. We compare the hostnumber with the number in the hosts 271*17767Sralph * table for the site they claim to be. 272*17767Sralph */ 273*17767Sralph if (IsTcpIp) { 274*17767Sralph struct hostent *hp; 275*17767Sralph char *cpnt, *inet_ntoa(); 276*17767Sralph int fromlen; 277*17767Sralph struct sockaddr_in from; 278*17767Sralph 279*17767Sralph #ifndef VMS 280*17767Sralph fromlen = sizeof(from); 281*17767Sralph if (getpeername(0, &from, &fromlen) < 0) { 282*17767Sralph logent(Rmtname, "NOT A TCP CONNECTION"); 283*17767Sralph omsg('R', "NOT TCP", Ofn); 284*17767Sralph cleanup(0); 285*17767Sralph } 286*17767Sralph #else VMS 287*17767Sralph from.sin_addr.s_addr = Hostnumber; 288*17767Sralph from.sin_family = AF_INET; 289*17767Sralph #endif VMS 290*17767Sralph hp = gethostbyaddr(&from.sin_addr, 291*17767Sralph sizeof (struct in_addr), from.sin_family); 292*17767Sralph if (hp == 0) { 293*17767Sralph /* security break or just old host table? */ 294*17767Sralph logent(Rmtname, "UNKNOWN IP-HOST Name ="); 295*17767Sralph cpnt = inet_ntoa(from.sin_addr), 296*17767Sralph logent(cpnt, "UNKNOWN IP-HOST Number ="); 297*17767Sralph sprintf(wkpre, "%s/%s isn't in my host table", 298*17767Sralph Rmtname, cpnt); 299*17767Sralph omsg('R' ,wkpre ,Ofn); 300*17767Sralph cleanup(0); 301*17767Sralph } 302*17767Sralph if (Debug>99) 303*17767Sralph logent(Rmtname,"Request from IP-Host name ="); 304*17767Sralph /* The following is to determine if the name given us by 305*17767Sralph * the Remote uucico matches any of the names(aliases) 306*17767Sralph * given its network number (remote machine) in our 307*17767Sralph * host table. 308*17767Sralph */ 309*17767Sralph if (strncmp(q, hp->h_name, 7) == 0) { 310*17767Sralph if (Debug > 99) 311*17767Sralph logent(q,"Found in host Tables"); 312*17767Sralph } else { /* Scan The host aliases */ 313*17767Sralph for(alias=hp->h_aliases; *alias!=0 && 314*17767Sralph strncmp(q, *alias, 7) != 0; ++alias) 315*17767Sralph ; 316*17767Sralph if (strncmp(q, *alias, 7) != 0) { 317*17767Sralph logent(q, "FORGED HOSTNAME"); 318*17767Sralph logent(inet_ntoa(from.sin_addr), "ORIGINATED AT"); 319*17767Sralph omsg('R',"You're not who you claim to be"); 320*17767Sralph cleanup(0); 321*17767Sralph } 322*17767Sralph #ifdef DEBUG 323*17767Sralph if (Debug> 99) 324*17767Sralph logent(q,"Found in host Tables"); 325*17767Sralph #endif 326*17767Sralph } 327*17767Sralph } 328*17767Sralph #endif BSDTCP 329*17767Sralph 330*17767Sralph #ifdef NOSTRANGERS 331*17767Sralph /* If we don't know them, we won't talk to them... */ 332*17767Sralph if (versys(Rmtname)) { 333*17767Sralph logent(Rmtname, "UNKNOWN HOST"); 334*17767Sralph omsg('R', "You are unknown to me", Ofn); 335*17767Sralph cleanup(0); 336*17767Sralph } 337*17767Sralph #endif NOSTRANGERS 33813639Ssam if (mlock(Rmtname)) { 33913639Ssam omsg('R', "LCK", Ofn); 34013639Ssam cleanup(0); 34113639Ssam } 34213639Ssam else if (callback(Loginuser)) { 34313639Ssam signal(SIGINT, SIG_IGN); 34413639Ssam signal(SIGHUP, SIG_IGN); 34513639Ssam omsg('R', "CB", Ofn); 34613639Ssam logent("CALLBACK", "REQUIRED"); 34713639Ssam /* set up for call back */ 348*17767Sralph systat(Rmtname, SS_CALLBACK, "CALLING BACK"); 34913639Ssam gename(CMDPRE, Rmtname, 'C', file); 35013639Ssam close(creat(subfile(file), 0666)); 35113639Ssam xuucico(Rmtname); 35213639Ssam cleanup(0); 35313639Ssam } 35413639Ssam seq = 0; 35513639Ssam while (*p == '-') { 35613639Ssam q = pskip(p); 35713639Ssam switch(*(++p)) { 35813639Ssam case 'x': 35913639Ssam Debug = atoi(++p); 36013639Ssam if (Debug <= 0) 36113639Ssam Debug = 1; 36213639Ssam break; 36313639Ssam case 'Q': 36413639Ssam seq = atoi(++p); 36513639Ssam break; 36613639Ssam default: 36713639Ssam break; 36813639Ssam } 36913639Ssam p = q; 37013639Ssam } 37113639Ssam if (callok(Rmtname) == SS_BADSEQ) { 37213639Ssam logent("BADSEQ", "PREVIOUS"); 37313639Ssam omsg('R', "BADSEQ", Ofn); 37413639Ssam cleanup(0); 37513639Ssam } 376*17767Sralph #ifdef GNXSEQ 37713639Ssam if ((ret = gnxseq(Rmtname)) == seq) { 37813639Ssam omsg('R', "OK", Ofn); 37913639Ssam cmtseq(); 380*17767Sralph } else { 381*17767Sralph #else !GNXSEQ 382*17767Sralph if (seq == 0) 383*17767Sralph omsg('R', "OK", Ofn); 38413639Ssam else { 385*17767Sralph #endif !GNXSEQ 38613639Ssam systat(Rmtname, Stattype[7], Stattext[7]); 387*17767Sralph logent("BAD SEQ", "HANDSHAKE FAIL"); 388*17767Sralph #ifdef GNXSEQ 38913639Ssam ulkseq(); 390*17767Sralph #endif GNXSEQ 39113639Ssam omsg('R', "BADSEQ", Ofn); 39213639Ssam cleanup(0); 39313639Ssam } 39413639Ssam ttyn = ttyname(Ifn); 39513639Ssam if (ttyn != NULL) 39613639Ssam chmod(ttyn, 0600); 397*17767Sralph } else { /* Role == MASTER */ 398*17767Sralph struct stat stbuf; 399*17767Sralph if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0 400*17767Sralph && stbuf.st_mode&S_IFREG) ) 401*17767Sralph StdErrIsTty = 1; 402*17767Sralph setdebug(0); 40313639Ssam } 404*17767Sralph 40513639Ssam loop: 406*17767Sralph if(setjmp(Pipebuf)) { /* come here on SIGPIPE */ 407*17767Sralph clsacu(); 408*17767Sralph close(Ofn); 409*17767Sralph close(Ifn); 410*17767Sralph Ifn = Ofn = -1; 411*17767Sralph rmlock(CNULL); 412*17767Sralph sleep(3); 413*17767Sralph } 41413639Ssam if (!onesys) { 415*17767Sralph struct stat sbuf; 416*17767Sralph 417*17767Sralph if (!StdErrIsTty) { 418*17767Sralph sprintf(file, "%s/%s", RMTDEBUG, Rmtname); 419*17767Sralph if (stat(file, &sbuf) == 0 && sbuf.st_size == 0) 420*17767Sralph unlink(file); 421*17767Sralph } 42213639Ssam ret = gnsys(Rmtname, Spool, CMDPRE); 423*17767Sralph setdebug(0); 42413639Ssam if (ret == FAIL) 42513639Ssam cleanup(100); 42613639Ssam if (ret == 0) 42713639Ssam cleanup(0); 428*17767Sralph } else if (Role == MASTER && callok(Rmtname) != 0) { 42913639Ssam logent("SYSTEM STATUS", "CAN NOT CALL"); 43013639Ssam cleanup(0); 43113639Ssam } 43213639Ssam 43313639Ssam sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname); 43413639Ssam 435*17767Sralph signal(SIGINT, SIG_IGN); 436*17767Sralph signal(SIGQUIT, SIG_IGN); 43713639Ssam if (Role == MASTER) { 438*17767Sralph /* check for /etc/nologin */ 439*17767Sralph ultouch(); /* sets nologinflag as a side effect */ 440*17767Sralph if (nologinflag) { 441*17767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 442*17767Sralph if (Debug) 443*17767Sralph logent("DEBUGGING", "continuing anyway"); 444*17767Sralph else 445*17767Sralph cleanup(1); 446*17767Sralph } 44713639Ssam /* master part */ 44813639Ssam signal(SIGHUP, SIG_IGN); 44913639Ssam if (!iswrk(file, "chk", Spool, wkpre) && !onesys) { 45013639Ssam logent(Rmtname, "NO WORK"); 45113639Ssam goto next; 45213639Ssam } 45313639Ssam if (Ifn != -1 && Role == MASTER) { 45413639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 45513639Ssam clsacu(); 45613639Ssam close(Ofn); 45713639Ssam close(Ifn); 45813639Ssam Ifn = Ofn = -1; 45913639Ssam rmlock(CNULL); 46013639Ssam sleep(3); 46113639Ssam } 46213639Ssam sprintf(msg, "call to %s ", Rmtname); 46313639Ssam if (mlock(Rmtname) != 0) { 46413639Ssam logent(msg, "LOCKED"); 465*17767Sralph US_SST(us_s_lock); 46613639Ssam goto next; 46713639Ssam } 46813639Ssam Ofn = Ifn = conn(Rmtname); 46913639Ssam if (Ofn < 0) { 470*17767Sralph if (Ofn != CF_TIME) 471*17767Sralph logent(msg, _FAILED); 472*17767Sralph /* avoid excessive 'wrong time' info */ 473*17767Sralph if (Stattype[-Ofn] != SS_WRONGTIME || argv[0][0] != 'U'){ 474*17767Sralph systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]); 475*17767Sralph US_SST(-Ofn); 476*17767Sralph UB_SST(-Ofn); 477*17767Sralph } 47813639Ssam goto next; 479*17767Sralph } else { 48013639Ssam logent(msg, "SUCCEEDED"); 481*17767Sralph US_SST(us_s_cok); 482*17767Sralph UB_SST(ub_ok); 48313639Ssam } 484*17767Sralph #ifdef TCPIP 485*17767Sralph /* 486*17767Sralph * Determine if we are on TCPIP 487*17767Sralph */ 488*17767Sralph if (isatty(Ifn) == 0) { 489*17767Sralph IsTcpIp = 1; 490*17767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 491*17767Sralph } 492*17767Sralph #endif 493*17767Sralph 49413639Ssam if (setjmp(Sjbuf)) 49513639Ssam goto next; 49613639Ssam signal(SIGALRM, timeout); 49713639Ssam alarm(2 * MAXMSGTIME); 49813639Ssam for (;;) { 49913639Ssam ret = imsg(msg, Ifn); 50013639Ssam if (ret != 0) { 50113639Ssam alarm(0); 502*17767Sralph logent("imsg 1", _FAILED); 503*17767Sralph goto Failure; 50413639Ssam } 50513639Ssam if (msg[0] == 'S') 50613639Ssam break; 50713639Ssam } 50813639Ssam alarm(MAXMSGTIME); 509*17767Sralph #ifdef GNXSEQ 51013639Ssam seq = gnxseq(Rmtname); 511*17767Sralph #else !GNXSEQ 512*17767Sralph seq = 0; 513*17767Sralph #endif !GNXSEQ 51413639Ssam sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags); 51513639Ssam omsg('S', msg, Ofn); 51613639Ssam for (;;) { 51713639Ssam ret = imsg(msg, Ifn); 51813639Ssam DEBUG(4, "msg-%s\n", msg); 519*17767Sralph if (ret != SUCCESS) { 52013639Ssam alarm(0); 521*17767Sralph #ifdef GNXSEQ 52213639Ssam ulkseq(); 523*17767Sralph #endif GNXSEQ 524*17767Sralph logent("imsg 2", _FAILED); 525*17767Sralph goto Failure; 52613639Ssam } 52713639Ssam if (msg[0] == 'R') 52813639Ssam break; 52913639Ssam } 53013639Ssam alarm(0); 53113639Ssam if (msg[1] == 'B') { 53213639Ssam /* bad sequence */ 533*17767Sralph logent("BAD SEQ", "HANDSHAKE FAIL"); 534*17767Sralph US_SST(us_s_hand); 535*17767Sralph systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]); 536*17767Sralph #ifdef GNXSEQ 53713639Ssam ulkseq(); 538*17767Sralph #endif GNXSEQ 53913639Ssam goto next; 54013639Ssam } 54113639Ssam if (strcmp(&msg[1], "OK") != SAME) { 542*17767Sralph logent(&msg[1], "HANDSHAKE FAIL"); 543*17767Sralph US_SST(us_s_hand); 544*17767Sralph #ifdef GNXSEQ 54513639Ssam ulkseq(); 546*17767Sralph #endif GNXSEQ 547*17767Sralph systat(Rmtname, SS_INPROGRESS, 548*17767Sralph strcmp(&msg[1], "CB") == SAME? 549*17767Sralph "AWAITING CALLBACK": "HANDSHAKE FAIL"); 55013639Ssam goto next; 55113639Ssam } 552*17767Sralph #ifdef GNXSEQ 55313639Ssam cmtseq(); 554*17767Sralph #endif GNXSEQ 55513639Ssam } 556*17767Sralph DEBUG(1, "Rmtname %s, ", Rmtname); 55713639Ssam DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); 55813639Ssam DEBUG(1, "Ifn - %d, ", Ifn); 55913639Ssam DEBUG(1, "Loginuser - %s\n", Loginuser); 56013639Ssam 56113639Ssam alarm(MAXMSGTIME); 56213639Ssam if (setjmp(Sjbuf)) 56313639Ssam goto Failure; 56413639Ssam ret = startup(Role); 56513639Ssam alarm(0); 56613639Ssam if (ret != SUCCESS) { 567*17767Sralph logent("startup", _FAILED); 56813639Ssam Failure: 569*17767Sralph US_SST(us_s_start); 570*17767Sralph systat(Rmtname, SS_FAIL, "STARTUP FAILED"); 57113639Ssam goto next; 572*17767Sralph } else { 57313639Ssam logent("startup", "OK"); 574*17767Sralph US_SST(us_s_gress); 57513639Ssam systat(Rmtname, SS_INPROGRESS, "TALKING"); 57613639Ssam ret = cntrl(Role, wkpre); 57713639Ssam DEBUG(1, "cntrl - %d\n", ret); 57813639Ssam signal(SIGINT, SIG_IGN); 57913639Ssam signal(SIGHUP, SIG_IGN); 58013639Ssam signal(SIGALRM, timeout); 581*17767Sralph if (ret == SUCCESS) { 58213639Ssam logent("conversation complete", "OK"); 583*17767Sralph US_SST(us_s_ok); 58413639Ssam rmstat(Rmtname); 58513639Ssam 586*17767Sralph } else { 587*17767Sralph logent("conversation complete", _FAILED); 588*17767Sralph US_SST(us_s_cf); 589*17767Sralph systat(Rmtname, SS_FAIL, "CONVERSATION FAILED"); 59013639Ssam } 59113639Ssam alarm(MAXMSGTIME); 59213639Ssam DEBUG(4, "send OO %d,", ret); 59313639Ssam if (!setjmp(Sjbuf)) { 59413639Ssam for (;;) { 59513639Ssam omsg('O', "OOOOO", Ofn); 59613639Ssam ret = imsg(msg, Ifn); 59713639Ssam if (ret != 0) 59813639Ssam break; 59913639Ssam if (msg[0] == 'O') 60013639Ssam break; 60113639Ssam } 60213639Ssam } 60313639Ssam alarm(0); 604*17767Sralph clsacu(); 605*17767Sralph rmlock(CNULL); 60613639Ssam } 60713639Ssam next: 60813639Ssam if (!onesys) { 60913639Ssam goto loop; 61013639Ssam } 61113639Ssam cleanup(0); 61213639Ssam } 61313639Ssam 614*17767Sralph #ifndef USG 61513639Ssam struct sgttyb Hupvec; 61613639Ssam #endif 61713639Ssam 61813639Ssam /*** 61913639Ssam * cleanup(code) cleanup and exit with "code" status 62013639Ssam * int code; 62113639Ssam */ 62213639Ssam 62313639Ssam cleanup(code) 62413639Ssam register int code; 62513639Ssam { 62613639Ssam register int ret; 62713639Ssam register char *ttyn; 628*17767Sralph char bfr[BUFSIZ]; 629*17767Sralph struct stat sbuf; 63013639Ssam 63113639Ssam signal(SIGINT, SIG_IGN); 63213639Ssam signal(SIGHUP, SIG_IGN); 63313639Ssam rmlock(CNULL); 63413639Ssam clsacu(); 63513639Ssam logcls(); 63613639Ssam if (Role == SLAVE) { 637*17767Sralph if (!IsTcpIp) { 638*17767Sralph #ifdef USG 63913639Ssam Savettyb.c_cflag |= HUPCL; 64013639Ssam ret = ioctl(0, TCSETA, &Savettyb); 641*17767Sralph #else !USG 64213639Ssam ret = ioctl(0, TIOCHPCL, STBNULL); 64313639Ssam ret = ioctl(0, TIOCGETP, &Hupvec); 64413639Ssam Hupvec.sg_ispeed = B0; 64513639Ssam Hupvec.sg_ospeed = B0; 64613639Ssam ret = ioctl(0, TIOCSETP, &Hupvec); 64713639Ssam sleep(2); 64813639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 649*17767Sralph /* make *sure* exclusive access is off */ 650*17767Sralph ret = ioctl(0, TIOCNXCL, STBNULL); 651*17767Sralph #endif !USG 65213639Ssam DEBUG(4, "ret ioctl - %d\n", ret); 65313639Ssam } 65413639Ssam ttyn = ttyname(Ifn); 65513639Ssam if (ttyn != NULL) 65613639Ssam chmod(ttyn, 0600); 65713639Ssam } 65813639Ssam if (Ofn != -1) { 65913639Ssam if (Role == MASTER) 66013639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 66113639Ssam close(Ifn); 66213639Ssam close(Ofn); 66313639Ssam } 66413639Ssam if (code == 0) 66513639Ssam xuuxqt(); 666*17767Sralph else 667*17767Sralph DEBUG(1, "exit code %d\n", code); 668*17767Sralph sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname); 669*17767Sralph if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0) 670*17767Sralph unlink(bfr); 671*17767Sralph sprintf(bfr, "%s/%d", RMTDEBUG, getpid()); 672*17767Sralph unlink(bfr); 67313639Ssam exit(code); 67413639Ssam } 67513639Ssam 67613639Ssam /*** 67713639Ssam * onintr(inter) interrupt - remove locks and exit 67813639Ssam */ 67913639Ssam 68013639Ssam onintr(inter) 68113639Ssam register int inter; 68213639Ssam { 68313639Ssam char str[30]; 68413639Ssam signal(inter, SIG_IGN); 68513639Ssam sprintf(str, "SIGNAL %d", inter); 68613639Ssam logent(str, "CAUGHT"); 687*17767Sralph US_SST(us_s_intr); 688*17767Sralph if (*Rmtname && strcmp(Rmtname, Myname)) 689*17767Sralph systat(Rmtname, SS_FAIL, str); 690*17767Sralph if (inter == SIGPIPE && !onesys) 691*17767Sralph longjmp(Pipebuf, 1); 69213639Ssam cleanup(inter); 69313639Ssam } 69413639Ssam 69513639Ssam /* 69613639Ssam * Catch a special signal 69713639Ssam * (SIGFPE, ugh), and toggle debugging between 0 and 30. 69813639Ssam * Handy for looking in on long running uucicos. 69913639Ssam */ 700*17767Sralph setdebug(code) 701*17767Sralph int code; 70213639Ssam { 703*17767Sralph char buf[BUFSIZ]; 704*17767Sralph 705*17767Sralph if (!StdErrIsTty) { 706*17767Sralph sprintf(buf,"%s/%s", RMTDEBUG, Rmtname); 707*17767Sralph unlink(buf); 708*17767Sralph freopen(buf, "w", stderr); 709*17767Sralph #ifdef BSD4_2 710*17767Sralph setlinebuf(stderr); 711*17767Sralph #else !BSD4_2 712*17767Sralph setbuf(stderr, NULL); 713*17767Sralph #endif !BSD4_2 714*17767Sralph } 715*17767Sralph if (code) { 716*17767Sralph if (Debug == 0) 717*17767Sralph Debug = 30; 718*17767Sralph else 719*17767Sralph Debug = 0; 720*17767Sralph } 72113639Ssam } 72213639Ssam 72313639Ssam 72413639Ssam /*** 72513639Ssam * fixmode(tty) fix kill/echo/raw on line 72613639Ssam * 72713639Ssam * return codes: none 72813639Ssam */ 72913639Ssam 73013639Ssam fixmode(tty) 73113639Ssam register int tty; 73213639Ssam { 733*17767Sralph #ifdef USG 73413639Ssam struct termio ttbuf; 73513639Ssam #endif 736*17767Sralph #ifndef USG 73713639Ssam struct sgttyb ttbuf; 73813639Ssam #endif 73913639Ssam register int ret; 74013639Ssam 741*17767Sralph if (IsTcpIp) 74213639Ssam return; 743*17767Sralph #ifdef USG 744*17767Sralph ret = ioctl(tty, TCGETA, &ttbuf); 74513639Ssam ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 74613639Ssam ttbuf.c_cflag &= (CBAUD); 74713639Ssam ttbuf.c_cflag |= (CS8|CREAD); 74813639Ssam ttbuf.c_cc[VMIN] = 6; 74913639Ssam ttbuf.c_cc[VTIME] = 1; 75013639Ssam ret = ioctl(tty, TCSETA, &ttbuf); 75113639Ssam #endif 752*17767Sralph #ifndef USG 75313639Ssam ioctl(tty, TIOCGETP, &ttbuf); 75413639Ssam ttbuf.sg_flags = (ANYP | RAW); 75513639Ssam ret = ioctl(tty, TIOCSETP, &ttbuf); 75613639Ssam #endif 757*17767Sralph /* ASSERT(ret >= 0, "STTY FAILED", CNULL, ret); */ 758*17767Sralph #ifndef USG 759*17767Sralph ret = ioctl(tty, TIOCEXCL, STBNULL); 76013639Ssam #endif 76113639Ssam } 76213639Ssam 76313639Ssam 76413639Ssam /*** 76513639Ssam * timeout() catch SIGALRM routine 76613639Ssam */ 76713639Ssam 76813639Ssam timeout() 76913639Ssam { 77013639Ssam logent(Rmtname, "TIMEOUT"); 771*17767Sralph if (*Rmtname && strcmp(Rmtname, Myname)) { 772*17767Sralph US_SST(us_s_tmot); 773*17767Sralph systat(Rmtname, SS_FAIL, "TIMEOUT"); 774*17767Sralph } 77513639Ssam longjmp(Sjbuf, 1); 77613639Ssam } 77713639Ssam 77813639Ssam static char * 77913639Ssam pskip(p) 78013639Ssam register char *p; 78113639Ssam { 782*17767Sralph while(*p && *p != ' ') 78313639Ssam ++p; 784*17767Sralph if(*p) 785*17767Sralph *p++ = 0; 786*17767Sralph return p; 78713639Ssam } 788