113639Ssam #ifndef lint 2*23590Sbloom static char sccsid[] = "@(#)cico.c 5.7 (Berkeley) 06/19/85"; 313639Ssam #endif 413639Ssam 5*23590Sbloom #include <signal.h> 613639Ssam #include "uucp.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 23*23590Sbloom #if defined(VMS) && defined(BSDTCP) 24*23590Sbloom #define NOGETPEER 25*23590Sbloom #endif 26*23590Sbloom 27*23590Sbloom #ifdef BSD2_9 28*23590Sbloom #define NOGETPEER 29*23590Sbloom #endif 30*23590Sbloom 3117767Sralph jmp_buf Sjbuf; 3217767Sralph jmp_buf Pipebuf; 3313639Ssam 3417767Sralph /* call fail text */ 3513639Ssam char *Stattext[] = { 3613639Ssam "", 3713639Ssam "BAD SYSTEM", 3817767Sralph "WRONG TIME TO CALL", 3913639Ssam "SYSTEM LOCKED", 4013639Ssam "NO DEVICE", 4113639Ssam "DIAL FAILED", 4213639Ssam "LOGIN FAILED", 4313639Ssam "BAD SEQUENCE" 4417767Sralph }; 4513639Ssam 4617767Sralph /* call fail codes */ 4717767Sralph int Stattype[] = { 4817767Sralph 0, 4917767Sralph 0, 5017767Sralph SS_WRONGTIME, 5117767Sralph 0, 5217767Sralph SS_NODEVICE, 5317767Sralph SS_FAIL, 5417767Sralph SS_FAIL, 5517767Sralph SS_BADSEQ 5617767Sralph }; 5713639Ssam 5813639Ssam 5917767Sralph int ReverseRole = 0; 6017767Sralph int StdErrIsTty = 0; 6117767Sralph int Role = SLAVE; 6217767Sralph int onesys = 0; 6318616Sralph int turntime = 30 * 60; /* 30 minutes expressed in seconds */ 6417767Sralph extern int LocalOnly; 6518616Sralph extern char MaxGrade, DefMaxGrade; 6618616Sralph extern char Myfullname[]; 6717767Sralph 6817767Sralph #ifdef USG 6913639Ssam struct termio Savettyb; 7013639Ssam #endif 7117767Sralph #ifndef USG 7213639Ssam struct sgttyb Savettyb; 7313639Ssam #endif 7413639Ssam 7513639Ssam /******* 7613639Ssam * cico - this program is used to place a call to a 7713639Ssam * remote machine, login, and copy files between the two machines. 7813639Ssam */ 7913639Ssam 8013639Ssam main(argc, argv) 8113639Ssam register char *argv[]; 8213639Ssam { 8313639Ssam register int ret; 8413639Ssam int seq; 8513639Ssam char wkpre[NAMESIZE], file[NAMESIZE]; 8617767Sralph char msg[MAXFULLNAME], *q, **alias; 8713639Ssam register char *p; 8813639Ssam extern onintr(), timeout(), setdebug(); 8913639Ssam extern char *pskip(); 9013639Ssam char rflags[30]; 9113639Ssam char *ttyn; 92*23590Sbloom #ifdef NOGETPEER 9317767Sralph u_long Hostnumber = 0; 94*23590Sbloom #endif NOGETPEER 9513639Ssam 9613639Ssam strcpy(Progname, "uucico"); 9713639Ssam 9813639Ssam signal(SIGINT, onintr); 9913639Ssam signal(SIGHUP, onintr); 10013639Ssam signal(SIGQUIT, onintr); 10113639Ssam signal(SIGTERM, onintr); 10213639Ssam signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */ 10313639Ssam signal(SIGFPE, setdebug); 10413639Ssam ret = guinfo(getuid(), User, msg); 10513639Ssam strcpy(Loginuser, User); 106*23590Sbloom uucpname(Myname); 10717767Sralph ASSERT(ret == 0, "BAD UID", CNULL, ret); 10813639Ssam 10917767Sralph #ifdef BSD4_2 11017767Sralph setlinebuf(stderr); 11117767Sralph #endif 11213639Ssam rflags[0] = '\0'; 11313639Ssam umask(WFMASK); 11413639Ssam strcpy(Rmtname, Myname); 11513639Ssam Ifn = Ofn = -1; 11613639Ssam while(argc>1 && argv[1][0] == '-'){ 11713639Ssam switch(argv[1][1]){ 11813639Ssam case 'd': 11913639Ssam Spool = &argv[1][2]; 12013639Ssam break; 12113639Ssam case 'g': 12218616Sralph case 'p': 12318616Sralph MaxGrade = DefMaxGrade = argv[1][2]; 12413639Ssam break; 12513639Ssam case 'r': 12613639Ssam Role = atoi(&argv[1][2]); 12713639Ssam break; 12817767Sralph case 'R': 12917767Sralph ReverseRole++; 13017767Sralph Role = MASTER; 13117767Sralph break; 13213639Ssam case 's': 133*23590Sbloom strncpy(Rmtname, &argv[1][2], MAXBASENAME); 134*23590Sbloom Rmtname[MAXBASENAME] = '\0'; 13513639Ssam if (Rmtname[0] != '\0') 13613639Ssam onesys = 1; 13713639Ssam break; 13813639Ssam case 'x': 13917767Sralph chkdebug(); 14013639Ssam Debug = atoi(&argv[1][2]); 14113639Ssam if (Debug <= 0) 14213639Ssam Debug = 1; 14313639Ssam strcat(rflags, argv[1]); 14413639Ssam logent("ENABLED", "DEBUG"); 14513639Ssam break; 14618616Sralph case 't': 14718616Sralph turntime = atoi(&argv[1][2])*60;/* minutes to seconds */ 14818616Sralph break; 14917767Sralph case 'L': /* local calls only */ 15017767Sralph LocalOnly++; 15117767Sralph break; 152*23590Sbloom #ifdef NOGETPEER 15317767Sralph case 'h': 15417767Sralph Hostnumber = inet_addr(&argv[1][2]); 15517767Sralph break; 156*23590Sbloom #endif NOGETPEER 15713639Ssam default: 15817767Sralph printf("unknown flag %s (ignored)\n", argv[1]); 15913639Ssam break; 16013639Ssam } 16113639Ssam --argc; argv++; 16213639Ssam } 16313639Ssam 16417767Sralph while (argc > 1) { 16517767Sralph printf("unknown argument %s (ignored)\n", argv[1]); 16617767Sralph --argc; argv++; 16717767Sralph } 16817767Sralph 16917767Sralph /* Try to run as uucp -- rti!trt */ 17017767Sralph setgid(getegid()); 17117767Sralph setuid(geteuid()); 17217767Sralph #ifdef TIOCNOTTY 17317767Sralph /* 17417767Sralph * detach uucico from controlling terminal 17517767Sralph * to defend against rlogind sending us a SIGKILL (!!!) 17617767Sralph */ 17717767Sralph if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) { 17817767Sralph ioctl(ret, TIOCNOTTY, STBNULL); 17917767Sralph close(ret); 18017767Sralph } 18117767Sralph #endif TIOCNOTTY 18217767Sralph #ifdef BSD4_2 18317767Sralph if (getpgrp(0) == 0) { /*We have no controlling terminal */ 18417767Sralph setpgrp(0, getpid()); 18517767Sralph } 18617767Sralph #endif BSD4_2 18717767Sralph 18817767Sralph ret = subchdir(Spool); 18917767Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 19013639Ssam strcpy(Wrkdir, Spool); 19113639Ssam 19213639Ssam if (Role == SLAVE) { 19317767Sralph /* check for /etc/nologin */ 19417767Sralph ultouch(); /* sets nologinflag as a side effect */ 19517767Sralph if (nologinflag) { 19617767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 197*23590Sbloom if (Debug > 4) 19817767Sralph logent("DEBUGGING", "continuing anyway"); 19917767Sralph else 20017767Sralph cleanup(1); 20117767Sralph } 20217767Sralph #ifdef TCPIP 20317767Sralph /* 20417767Sralph * Determine if we are on TCPIP 20517767Sralph */ 20617767Sralph if (isatty(0) == 0) { 20717767Sralph IsTcpIp = 1; 20817767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 209*23590Sbloom } else 210*23590Sbloom IsTcpIp = 0; 21117767Sralph #endif TCPIP 21213639Ssam /* initial handshake */ 21313639Ssam onesys = 1; 21417767Sralph if (!IsTcpIp) { 21517767Sralph #ifdef USG 21613639Ssam ret = ioctl(0, TCGETA, &Savettyb); 21713639Ssam Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; 21813639Ssam Savettyb.c_oflag |= OPOST; 21913639Ssam Savettyb.c_lflag |= (ISIG|ICANON|ECHO); 22017767Sralph #else !USG 22113639Ssam ret = ioctl(0, TIOCGETP, &Savettyb); 22213639Ssam Savettyb.sg_flags |= ECHO; 22313639Ssam Savettyb.sg_flags &= ~RAW; 22417767Sralph #endif !USG 22513639Ssam } 22613639Ssam Ifn = 0; 22713639Ssam Ofn = 1; 22813639Ssam fixmode(Ifn); 22917767Sralph sprintf(file,"%s/%d", RMTDEBUG, getpid()); 23017767Sralph #ifdef VMS 23117767Sralph /* hold the version number down */ 23217767Sralph unlink(file); 233*23590Sbloom #endif VMS 23417767Sralph freopen(file, "w", stderr); 23517767Sralph #ifdef BSD4_2 23617767Sralph setlinebuf(stderr); 23717767Sralph #else !BSD4_2 23817767Sralph setbuf(stderr, NULL); 23917767Sralph #endif !BSD4_2 24018616Sralph sprintf(msg, "here=%s", Myfullname); 24117767Sralph omsg('S', msg, Ofn); 24213639Ssam signal(SIGALRM, timeout); 24313639Ssam alarm(MAXMSGTIME); 24413639Ssam if (setjmp(Sjbuf)) { 24513639Ssam /* timed out */ 24617767Sralph if (!IsTcpIp) { 24717767Sralph #ifdef USG 24813639Ssam ret = ioctl(0, TCSETA, &Savettyb); 249*23590Sbloom #else !USG 25013639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 251*23590Sbloom #endif !USG 25213639Ssam } 25317767Sralph cleanup(0); 25413639Ssam } 25513639Ssam for (;;) { 25613639Ssam ret = imsg(msg, Ifn); 25713639Ssam if (ret != 0) { 25813639Ssam alarm(0); 25917767Sralph if (!IsTcpIp) { 26017767Sralph #ifdef USG 26113639Ssam ret = ioctl(0, TCSETA, &Savettyb); 262*23590Sbloom #else !USG 26313639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 264*23590Sbloom #endif !USG 26513639Ssam } 26617767Sralph cleanup(0); 26713639Ssam } 26813639Ssam if (msg[0] == 'S') 26913639Ssam break; 27013639Ssam } 27113639Ssam alarm(0); 27213639Ssam q = &msg[1]; 27313639Ssam p = pskip(q); 274*23590Sbloom strncpy(Rmtname, q, MAXBASENAME); 275*23590Sbloom Rmtname[MAXBASENAME] = '\0'; 27617767Sralph sprintf(wkpre,"%s/%s", RMTDEBUG, Rmtname); 27717767Sralph unlink(wkpre); 27817767Sralph if (link(file, wkpre) == 0) 27917767Sralph unlink(file); 28013639Ssam DEBUG(4, "sys-%s\n", Rmtname); 281*23590Sbloom #ifdef NOSTRANGERS 282*23590Sbloom /* If we don't know them, we won't talk to them... */ 283*23590Sbloom if (versys(&Rmtname)) { 284*23590Sbloom logent(Rmtname, "UNKNOWN HOST"); 285*23590Sbloom omsg('R', "You are unknown to me", Ofn); 286*23590Sbloom cleanup(0); 287*23590Sbloom } 288*23590Sbloom #endif NOSTRANGERS 28917767Sralph #ifdef BSDTCP 29017767Sralph /* we must make sure they are really who they say they 29117767Sralph * are. We compare the hostnumber with the number in the hosts 29217767Sralph * table for the site they claim to be. 29317767Sralph */ 29417767Sralph if (IsTcpIp) { 29517767Sralph struct hostent *hp; 29617767Sralph char *cpnt, *inet_ntoa(); 29717767Sralph int fromlen; 29817767Sralph struct sockaddr_in from; 29917767Sralph 300*23590Sbloom #ifdef NOGETPEER 301*23590Sbloom from.sin_addr.s_addr = Hostnumber; 302*23590Sbloom from.sin_family = AF_INET; 303*23590Sbloom #else !NOGETPEER 30417767Sralph fromlen = sizeof(from); 30517767Sralph if (getpeername(0, &from, &fromlen) < 0) { 30617767Sralph logent(Rmtname, "NOT A TCP CONNECTION"); 30717767Sralph omsg('R', "NOT TCP", Ofn); 30817767Sralph cleanup(0); 30917767Sralph } 310*23590Sbloom #endif !NOGETPEER 31117767Sralph hp = gethostbyaddr(&from.sin_addr, 31217767Sralph sizeof (struct in_addr), from.sin_family); 31317767Sralph if (hp == 0) { 31417767Sralph /* security break or just old host table? */ 31517767Sralph logent(Rmtname, "UNKNOWN IP-HOST Name ="); 31617767Sralph cpnt = inet_ntoa(from.sin_addr), 31717767Sralph logent(cpnt, "UNKNOWN IP-HOST Number ="); 31817767Sralph sprintf(wkpre, "%s/%s isn't in my host table", 31917767Sralph Rmtname, cpnt); 32017767Sralph omsg('R' ,wkpre ,Ofn); 32117767Sralph cleanup(0); 32217767Sralph } 32317767Sralph if (Debug>99) 32417767Sralph logent(Rmtname,"Request from IP-Host name ="); 32517767Sralph /* The following is to determine if the name given us by 32617767Sralph * the Remote uucico matches any of the names(aliases) 32717767Sralph * given its network number (remote machine) in our 32817767Sralph * host table. 32917767Sralph */ 330*23590Sbloom if (strncmp(q, hp->h_name, MAXBASENAME) == 0) { 33117767Sralph if (Debug > 99) 33217767Sralph logent(q,"Found in host Tables"); 33317767Sralph } else { /* Scan The host aliases */ 33417767Sralph for(alias=hp->h_aliases; *alias!=0 && 335*23590Sbloom strncmp(q, *alias, MAXBASENAME) != 0; ++alias) 33617767Sralph ; 337*23590Sbloom if (strncmp(q, *alias, MAXBASENAME) != 0) { 33817767Sralph logent(q, "FORGED HOSTNAME"); 33917767Sralph logent(inet_ntoa(from.sin_addr), "ORIGINATED AT"); 340*23590Sbloom omsg('R',"You're not who you claim to be", Ofn); 34117767Sralph cleanup(0); 34217767Sralph } 34317767Sralph #ifdef DEBUG 34417767Sralph if (Debug> 99) 34517767Sralph logent(q,"Found in host Tables"); 346*23590Sbloom #endif DEBUG 34717767Sralph } 34817767Sralph } 34917767Sralph #endif BSDTCP 35017767Sralph 35113639Ssam if (mlock(Rmtname)) { 35213639Ssam omsg('R', "LCK", Ofn); 35313639Ssam cleanup(0); 35413639Ssam } 35513639Ssam else if (callback(Loginuser)) { 35613639Ssam signal(SIGINT, SIG_IGN); 35713639Ssam signal(SIGHUP, SIG_IGN); 35813639Ssam omsg('R', "CB", Ofn); 35913639Ssam logent("CALLBACK", "REQUIRED"); 36013639Ssam /* set up for call back */ 36117767Sralph systat(Rmtname, SS_CALLBACK, "CALLING BACK"); 36213639Ssam gename(CMDPRE, Rmtname, 'C', file); 36313639Ssam close(creat(subfile(file), 0666)); 36413639Ssam xuucico(Rmtname); 36513639Ssam cleanup(0); 36613639Ssam } 36713639Ssam seq = 0; 36813639Ssam while (*p == '-') { 36913639Ssam q = pskip(p); 37013639Ssam switch(*(++p)) { 37113639Ssam case 'x': 37213639Ssam Debug = atoi(++p); 37313639Ssam if (Debug <= 0) 37413639Ssam Debug = 1; 37513639Ssam break; 37613639Ssam case 'Q': 37713639Ssam seq = atoi(++p); 37813639Ssam break; 37918616Sralph case 'p': 38018616Sralph MaxGrade = DefMaxGrade = *++p; 38118616Sralph DEBUG(4, "MaxGrade set to %c\n", MaxGrade); 38218616Sralph break; 383*23590Sbloom case 'v': 384*23590Sbloom if (strncmp(p, "grade", 5) == 0) { 385*23590Sbloom p += 6; 386*23590Sbloom MaxGrade = DefMaxGrade = *p++; 387*23590Sbloom DEBUG(4, "MaxGrade set to %c\n", MaxGrade); 388*23590Sbloom } 389*23590Sbloom break; 39013639Ssam default: 39113639Ssam break; 39213639Ssam } 39313639Ssam p = q; 39413639Ssam } 39513639Ssam if (callok(Rmtname) == SS_BADSEQ) { 39613639Ssam logent("BADSEQ", "PREVIOUS"); 39713639Ssam omsg('R', "BADSEQ", Ofn); 39813639Ssam cleanup(0); 39913639Ssam } 40017767Sralph #ifdef GNXSEQ 40113639Ssam if ((ret = gnxseq(Rmtname)) == seq) { 40213639Ssam omsg('R', "OK", Ofn); 40313639Ssam cmtseq(); 40417767Sralph } else { 40517767Sralph #else !GNXSEQ 40617767Sralph if (seq == 0) 40717767Sralph omsg('R', "OK", Ofn); 40813639Ssam else { 40917767Sralph #endif !GNXSEQ 41013639Ssam systat(Rmtname, Stattype[7], Stattext[7]); 411*23590Sbloom logent("BAD SEQ", "FAILED HANDSHAKE"); 41217767Sralph #ifdef GNXSEQ 41313639Ssam ulkseq(); 41417767Sralph #endif GNXSEQ 41513639Ssam omsg('R', "BADSEQ", Ofn); 41613639Ssam cleanup(0); 41713639Ssam } 41813639Ssam ttyn = ttyname(Ifn); 41913639Ssam if (ttyn != NULL) 42013639Ssam chmod(ttyn, 0600); 42117767Sralph } else { /* Role == MASTER */ 42217767Sralph struct stat stbuf; 42317767Sralph if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0 42417767Sralph && stbuf.st_mode&S_IFREG) ) 42517767Sralph StdErrIsTty = 1; 42617767Sralph setdebug(0); 42713639Ssam } 42817767Sralph 42913639Ssam loop: 43017767Sralph if(setjmp(Pipebuf)) { /* come here on SIGPIPE */ 43117767Sralph clsacu(); 43217767Sralph close(Ofn); 43317767Sralph close(Ifn); 43417767Sralph Ifn = Ofn = -1; 43517767Sralph rmlock(CNULL); 43617767Sralph sleep(3); 43717767Sralph } 43813639Ssam if (!onesys) { 43917767Sralph struct stat sbuf; 44017767Sralph 44117767Sralph if (!StdErrIsTty) { 44217767Sralph sprintf(file, "%s/%s", RMTDEBUG, Rmtname); 44317767Sralph if (stat(file, &sbuf) == 0 && sbuf.st_size == 0) 44417767Sralph unlink(file); 44517767Sralph } 44613639Ssam ret = gnsys(Rmtname, Spool, CMDPRE); 44717767Sralph setdebug(0); 44813639Ssam if (ret == FAIL) 44913639Ssam cleanup(100); 450*23590Sbloom if (ret == SUCCESS) 45113639Ssam cleanup(0); 45217767Sralph } else if (Role == MASTER && callok(Rmtname) != 0) { 45313639Ssam logent("SYSTEM STATUS", "CAN NOT CALL"); 45413639Ssam cleanup(0); 45513639Ssam } 45613639Ssam 457*23590Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 45813639Ssam 45917767Sralph signal(SIGINT, SIG_IGN); 46017767Sralph signal(SIGQUIT, SIG_IGN); 46113639Ssam if (Role == MASTER) { 46217767Sralph /* check for /etc/nologin */ 46317767Sralph ultouch(); /* sets nologinflag as a side effect */ 46417767Sralph if (nologinflag) { 46517767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 466*23590Sbloom if (Debug > 4) 46717767Sralph logent("DEBUGGING", "continuing anyway"); 46817767Sralph else 46917767Sralph cleanup(1); 47017767Sralph } 47113639Ssam /* master part */ 47213639Ssam signal(SIGHUP, SIG_IGN); 47313639Ssam if (Ifn != -1 && Role == MASTER) { 47413639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 47513639Ssam clsacu(); 47613639Ssam close(Ofn); 47713639Ssam close(Ifn); 47813639Ssam Ifn = Ofn = -1; 47913639Ssam rmlock(CNULL); 48013639Ssam sleep(3); 48113639Ssam } 48213639Ssam sprintf(msg, "call to %s ", Rmtname); 48313639Ssam if (mlock(Rmtname) != 0) { 48413639Ssam logent(msg, "LOCKED"); 48517767Sralph US_SST(us_s_lock); 48613639Ssam goto next; 48713639Ssam } 48813639Ssam Ofn = Ifn = conn(Rmtname); 48913639Ssam if (Ofn < 0) { 49017767Sralph if (Ofn != CF_TIME) 49117767Sralph logent(msg, _FAILED); 49217767Sralph /* avoid excessive 'wrong time' info */ 493*23590Sbloom if (Stattype[-Ofn] != SS_WRONGTIME){ 49417767Sralph systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]); 49517767Sralph US_SST(-Ofn); 49617767Sralph UB_SST(-Ofn); 49717767Sralph } 49813639Ssam goto next; 49917767Sralph } else { 50013639Ssam logent(msg, "SUCCEEDED"); 50117767Sralph US_SST(us_s_cok); 50217767Sralph UB_SST(ub_ok); 50313639Ssam } 50417767Sralph #ifdef TCPIP 50517767Sralph /* 50617767Sralph * Determine if we are on TCPIP 50717767Sralph */ 50817767Sralph if (isatty(Ifn) == 0) { 50917767Sralph IsTcpIp = 1; 51017767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 511*23590Sbloom } else 512*23590Sbloom IsTcpIp = 0; 51317767Sralph #endif 51417767Sralph 51513639Ssam if (setjmp(Sjbuf)) 51613639Ssam goto next; 51713639Ssam signal(SIGALRM, timeout); 51813639Ssam alarm(2 * MAXMSGTIME); 51913639Ssam for (;;) { 52013639Ssam ret = imsg(msg, Ifn); 52113639Ssam if (ret != 0) { 52213639Ssam alarm(0); 52317767Sralph logent("imsg 1", _FAILED); 52417767Sralph goto Failure; 52513639Ssam } 52613639Ssam if (msg[0] == 'S') 52713639Ssam break; 52813639Ssam } 52913639Ssam alarm(MAXMSGTIME); 53017767Sralph #ifdef GNXSEQ 53113639Ssam seq = gnxseq(Rmtname); 53217767Sralph #else !GNXSEQ 53317767Sralph seq = 0; 53417767Sralph #endif !GNXSEQ 53518616Sralph if (MaxGrade != '\177') { 53618616Sralph char buf[10]; 537*23590Sbloom sprintf(buf, " -p%c -vgrade=%c", MaxGrade, MaxGrade); 53818616Sralph strcat(rflags, buf); 53918616Sralph } 54018616Sralph 541*23590Sbloom sprintf(msg, "%s -Q%d %s", Myname, seq, rflags); 542*23590Sbloom if (MaxGrade != '\177') 543*23590Sbloom DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade); 54413639Ssam omsg('S', msg, Ofn); 54513639Ssam for (;;) { 54613639Ssam ret = imsg(msg, Ifn); 54713639Ssam DEBUG(4, "msg-%s\n", msg); 54817767Sralph if (ret != SUCCESS) { 54913639Ssam alarm(0); 55017767Sralph #ifdef GNXSEQ 55113639Ssam ulkseq(); 55217767Sralph #endif GNXSEQ 55317767Sralph logent("imsg 2", _FAILED); 55417767Sralph goto Failure; 55513639Ssam } 55613639Ssam if (msg[0] == 'R') 55713639Ssam break; 55813639Ssam } 55913639Ssam alarm(0); 56013639Ssam if (msg[1] == 'B') { 56113639Ssam /* bad sequence */ 562*23590Sbloom logent("BAD SEQ", "FAILED HANDSHAKE"); 56317767Sralph US_SST(us_s_hand); 56417767Sralph systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]); 56517767Sralph #ifdef GNXSEQ 56613639Ssam ulkseq(); 56717767Sralph #endif GNXSEQ 56813639Ssam goto next; 56913639Ssam } 57013639Ssam if (strcmp(&msg[1], "OK") != SAME) { 571*23590Sbloom logent(&msg[1], "FAILED HANDSHAKE"); 57217767Sralph US_SST(us_s_hand); 57317767Sralph #ifdef GNXSEQ 57413639Ssam ulkseq(); 57517767Sralph #endif GNXSEQ 57617767Sralph systat(Rmtname, SS_INPROGRESS, 57717767Sralph strcmp(&msg[1], "CB") == SAME? 578*23590Sbloom "AWAITING CALLBACK": "FAILED HANDSHAKE"); 57913639Ssam goto next; 58013639Ssam } 58117767Sralph #ifdef GNXSEQ 58213639Ssam cmtseq(); 58317767Sralph #endif GNXSEQ 58413639Ssam } 58517767Sralph DEBUG(1, "Rmtname %s, ", Rmtname); 58613639Ssam DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); 58713639Ssam DEBUG(1, "Ifn - %d, ", Ifn); 58813639Ssam DEBUG(1, "Loginuser - %s\n", Loginuser); 58913639Ssam 59013639Ssam alarm(MAXMSGTIME); 59118616Sralph if (ret=setjmp(Sjbuf)) 59213639Ssam goto Failure; 59313639Ssam ret = startup(Role); 59413639Ssam alarm(0); 59513639Ssam if (ret != SUCCESS) { 59617767Sralph logent("startup", _FAILED); 59713639Ssam Failure: 59817767Sralph US_SST(us_s_start); 59918616Sralph systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" : 60018616Sralph "STARTUP FAILED"); 60113639Ssam goto next; 60217767Sralph } else { 60313639Ssam logent("startup", "OK"); 60417767Sralph US_SST(us_s_gress); 60513639Ssam systat(Rmtname, SS_INPROGRESS, "TALKING"); 60613639Ssam ret = cntrl(Role, wkpre); 60713639Ssam DEBUG(1, "cntrl - %d\n", ret); 60813639Ssam signal(SIGINT, SIG_IGN); 60913639Ssam signal(SIGHUP, SIG_IGN); 61013639Ssam signal(SIGALRM, timeout); 61117767Sralph if (ret == SUCCESS) { 61213639Ssam logent("conversation complete", "OK"); 61317767Sralph US_SST(us_s_ok); 61413639Ssam rmstat(Rmtname); 61513639Ssam 61617767Sralph } else { 61717767Sralph logent("conversation complete", _FAILED); 61817767Sralph US_SST(us_s_cf); 61917767Sralph systat(Rmtname, SS_FAIL, "CONVERSATION FAILED"); 62013639Ssam } 62113639Ssam alarm(MAXMSGTIME); 62213639Ssam DEBUG(4, "send OO %d,", ret); 62313639Ssam if (!setjmp(Sjbuf)) { 62413639Ssam for (;;) { 62513639Ssam omsg('O', "OOOOO", Ofn); 62613639Ssam ret = imsg(msg, Ifn); 62713639Ssam if (ret != 0) 62813639Ssam break; 62913639Ssam if (msg[0] == 'O') 63013639Ssam break; 63113639Ssam } 63213639Ssam } 63313639Ssam alarm(0); 63417767Sralph clsacu(); 63517767Sralph rmlock(CNULL); 63613639Ssam } 63713639Ssam next: 63813639Ssam if (!onesys) { 63913639Ssam goto loop; 64013639Ssam } 64113639Ssam cleanup(0); 64213639Ssam } 64313639Ssam 64417767Sralph #ifndef USG 64513639Ssam struct sgttyb Hupvec; 64613639Ssam #endif 64713639Ssam 64813639Ssam /*** 64913639Ssam * cleanup(code) cleanup and exit with "code" status 65013639Ssam * int code; 65113639Ssam */ 65213639Ssam 65313639Ssam cleanup(code) 65413639Ssam register int code; 65513639Ssam { 65613639Ssam register char *ttyn; 65717767Sralph char bfr[BUFSIZ]; 65817767Sralph struct stat sbuf; 65913639Ssam 66013639Ssam signal(SIGINT, SIG_IGN); 66113639Ssam signal(SIGHUP, SIG_IGN); 66213639Ssam rmlock(CNULL); 66313639Ssam clsacu(); 66413639Ssam logcls(); 66513639Ssam if (Role == SLAVE) { 66617767Sralph if (!IsTcpIp) { 66717767Sralph #ifdef USG 66813639Ssam Savettyb.c_cflag |= HUPCL; 669*23590Sbloom (void) ioctl(0, TCSETA, &Savettyb); 67017767Sralph #else !USG 671*23590Sbloom (void) ioctl(0, TIOCHPCL, STBNULL); 67218616Sralph #ifdef TIOCSDTR 673*23590Sbloom (void) ioctl(0, TIOCCDTR, STBNULL); 67418616Sralph sleep(2); 675*23590Sbloom (void) ioctl(0, TIOCSDTR, STBNULL); 67618616Sralph #else !TIOCSDTR 677*23590Sbloom (void) ioctl(0, TIOCGETP, &Hupvec); 67818616Sralph #endif !TIOCSDTR 67913639Ssam Hupvec.sg_ispeed = B0; 68013639Ssam Hupvec.sg_ospeed = B0; 681*23590Sbloom (void) ioctl(0, TIOCSETP, &Hupvec); 68213639Ssam sleep(2); 683*23590Sbloom (void) ioctl(0, TIOCSETP, &Savettyb); 68417767Sralph /* make *sure* exclusive access is off */ 685*23590Sbloom (void) ioctl(0, TIOCNXCL, STBNULL); 68617767Sralph #endif !USG 68713639Ssam } 68813639Ssam ttyn = ttyname(Ifn); 68913639Ssam if (ttyn != NULL) 69013639Ssam chmod(ttyn, 0600); 69113639Ssam } 69213639Ssam if (Ofn != -1) { 69313639Ssam if (Role == MASTER) 69413639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 69513639Ssam close(Ifn); 69613639Ssam close(Ofn); 69713639Ssam } 69818616Sralph #ifdef DIALINOUT 69918616Sralph /* reenable logins on dialout */ 70018616Sralph reenable(); 70118616Sralph #endif DIALINOUT 70213639Ssam if (code == 0) 70313639Ssam xuuxqt(); 70417767Sralph else 70517767Sralph DEBUG(1, "exit code %d\n", code); 70617767Sralph sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname); 70717767Sralph if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0) 70817767Sralph unlink(bfr); 70917767Sralph sprintf(bfr, "%s/%d", RMTDEBUG, getpid()); 71017767Sralph unlink(bfr); 71113639Ssam exit(code); 71213639Ssam } 71313639Ssam 71413639Ssam /*** 71513639Ssam * onintr(inter) interrupt - remove locks and exit 71613639Ssam */ 71713639Ssam 71813639Ssam onintr(inter) 71913639Ssam register int inter; 72013639Ssam { 72113639Ssam char str[30]; 72213639Ssam signal(inter, SIG_IGN); 72313639Ssam sprintf(str, "SIGNAL %d", inter); 72413639Ssam logent(str, "CAUGHT"); 72517767Sralph US_SST(us_s_intr); 726*23590Sbloom if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) 72717767Sralph systat(Rmtname, SS_FAIL, str); 72817767Sralph if (inter == SIGPIPE && !onesys) 72917767Sralph longjmp(Pipebuf, 1); 73013639Ssam cleanup(inter); 73113639Ssam } 73213639Ssam 73313639Ssam /* 73413639Ssam * Catch a special signal 73513639Ssam * (SIGFPE, ugh), and toggle debugging between 0 and 30. 73613639Ssam * Handy for looking in on long running uucicos. 73713639Ssam */ 73817767Sralph setdebug(code) 73917767Sralph int code; 74013639Ssam { 74117767Sralph char buf[BUFSIZ]; 74217767Sralph 743*23590Sbloom if (code) { 744*23590Sbloom if (Debug == 0) 745*23590Sbloom Debug = 30; 746*23590Sbloom else 747*23590Sbloom Debug = 0; 748*23590Sbloom } 749*23590Sbloom if (Debug && !StdErrIsTty) { 75017767Sralph sprintf(buf,"%s/%s", RMTDEBUG, Rmtname); 75117767Sralph unlink(buf); 75217767Sralph freopen(buf, "w", stderr); 75317767Sralph #ifdef BSD4_2 75417767Sralph setlinebuf(stderr); 75517767Sralph #else !BSD4_2 75617767Sralph setbuf(stderr, NULL); 75717767Sralph #endif !BSD4_2 75817767Sralph } 75913639Ssam } 76013639Ssam 76113639Ssam 76213639Ssam /*** 76313639Ssam * fixmode(tty) fix kill/echo/raw on line 76413639Ssam * 76513639Ssam * return codes: none 76613639Ssam */ 76713639Ssam 76813639Ssam fixmode(tty) 76913639Ssam register int tty; 77013639Ssam { 77117767Sralph #ifdef USG 77213639Ssam struct termio ttbuf; 77313639Ssam #endif 77417767Sralph #ifndef USG 77513639Ssam struct sgttyb ttbuf; 77613639Ssam #endif 77713639Ssam 77817767Sralph if (IsTcpIp) 77913639Ssam return; 78017767Sralph #ifdef USG 781*23590Sbloom ioctl(tty, TCGETA, &ttbuf); 78213639Ssam ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 78313639Ssam ttbuf.c_cflag &= (CBAUD); 78413639Ssam ttbuf.c_cflag |= (CS8|CREAD); 78513639Ssam ttbuf.c_cc[VMIN] = 6; 78613639Ssam ttbuf.c_cc[VTIME] = 1; 787*23590Sbloom ioctl(tty, TCSETA, &ttbuf); 78813639Ssam #endif 78917767Sralph #ifndef USG 79013639Ssam ioctl(tty, TIOCGETP, &ttbuf); 79113639Ssam ttbuf.sg_flags = (ANYP | RAW); 792*23590Sbloom ioctl(tty, TIOCSETP, &ttbuf); 79313639Ssam #endif 79417767Sralph #ifndef USG 795*23590Sbloom ioctl(tty, TIOCEXCL, STBNULL); 79613639Ssam #endif 79713639Ssam } 79813639Ssam 79913639Ssam 800*23590Sbloom /* 80113639Ssam * timeout() catch SIGALRM routine 80213639Ssam */ 80313639Ssam 80413639Ssam timeout() 80513639Ssam { 806*23590Sbloom extern int HaveSentHup; 807*23590Sbloom if (!HaveSentHup) { 808*23590Sbloom logent(Rmtname, "TIMEOUT"); 809*23590Sbloom if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) { 810*23590Sbloom US_SST(us_s_tmot); 811*23590Sbloom systat(Rmtname, SS_FAIL, "TIMEOUT"); 812*23590Sbloom } 81317767Sralph } 81413639Ssam longjmp(Sjbuf, 1); 81513639Ssam } 81613639Ssam 81713639Ssam static char * 81813639Ssam pskip(p) 81913639Ssam register char *p; 82013639Ssam { 82117767Sralph while(*p && *p != ' ') 82213639Ssam ++p; 823*23590Sbloom while(*p && *p == ' ') 82417767Sralph *p++ = 0; 82517767Sralph return p; 82613639Ssam } 827