113639Ssam #ifndef lint 2*23725Sbloom static char sccsid[] = "@(#)cico.c 5.8 (Berkeley) 06/24/85"; 313639Ssam #endif 413639Ssam 523590Sbloom #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 2323590Sbloom #if defined(VMS) && defined(BSDTCP) 2423590Sbloom #define NOGETPEER 2523590Sbloom #endif 2623590Sbloom 2723590Sbloom #ifdef BSD2_9 2823590Sbloom #define NOGETPEER 2923590Sbloom #endif 3023590Sbloom 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(); 90*23725Sbloom char rflags[MAXFULLNAME]; 9113639Ssam char *ttyn; 9223590Sbloom #ifdef NOGETPEER 9317767Sralph u_long Hostnumber = 0; 9423590Sbloom #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); 10623590Sbloom 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': 13323590Sbloom strncpy(Rmtname, &argv[1][2], MAXBASENAME); 13423590Sbloom 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; 15223590Sbloom #ifdef NOGETPEER 15317767Sralph case 'h': 15417767Sralph Hostnumber = inet_addr(&argv[1][2]); 15517767Sralph break; 15623590Sbloom #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"); 19723590Sbloom 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); 20923590Sbloom } else 21023590Sbloom 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); 23323590Sbloom #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); 24923590Sbloom #else !USG 25013639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 25123590Sbloom #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); 26223590Sbloom #else !USG 26313639Ssam ret = ioctl(0, TIOCSETP, &Savettyb); 26423590Sbloom #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); 27423590Sbloom strncpy(Rmtname, q, MAXBASENAME); 27523590Sbloom 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*23725Sbloom /* The versys will also do an alias on the incoming name */ 282*23725Sbloom if (versys(&Rmtname)) { 283*23725Sbloom /* If we don't know them, we won't talk to them... */ 28423590Sbloom #ifdef NOSTRANGERS 28523590Sbloom logent(Rmtname, "UNKNOWN HOST"); 28623590Sbloom omsg('R', "You are unknown to me", Ofn); 28723590Sbloom cleanup(0); 288*23725Sbloom #endif NOSTRANGERS 28923590Sbloom } 29017767Sralph #ifdef BSDTCP 29117767Sralph /* we must make sure they are really who they say they 29217767Sralph * are. We compare the hostnumber with the number in the hosts 29317767Sralph * table for the site they claim to be. 29417767Sralph */ 29517767Sralph if (IsTcpIp) { 29617767Sralph struct hostent *hp; 29717767Sralph char *cpnt, *inet_ntoa(); 29817767Sralph int fromlen; 29917767Sralph struct sockaddr_in from; 30017767Sralph 30123590Sbloom #ifdef NOGETPEER 30223590Sbloom from.sin_addr.s_addr = Hostnumber; 30323590Sbloom from.sin_family = AF_INET; 30423590Sbloom #else !NOGETPEER 30517767Sralph fromlen = sizeof(from); 30617767Sralph if (getpeername(0, &from, &fromlen) < 0) { 30717767Sralph logent(Rmtname, "NOT A TCP CONNECTION"); 30817767Sralph omsg('R', "NOT TCP", Ofn); 30917767Sralph cleanup(0); 31017767Sralph } 31123590Sbloom #endif !NOGETPEER 31217767Sralph hp = gethostbyaddr(&from.sin_addr, 31317767Sralph sizeof (struct in_addr), from.sin_family); 31417767Sralph if (hp == 0) { 31517767Sralph /* security break or just old host table? */ 31617767Sralph logent(Rmtname, "UNKNOWN IP-HOST Name ="); 31717767Sralph cpnt = inet_ntoa(from.sin_addr), 31817767Sralph logent(cpnt, "UNKNOWN IP-HOST Number ="); 31917767Sralph sprintf(wkpre, "%s/%s isn't in my host table", 32017767Sralph Rmtname, cpnt); 32117767Sralph omsg('R' ,wkpre ,Ofn); 32217767Sralph cleanup(0); 32317767Sralph } 32417767Sralph if (Debug>99) 32517767Sralph logent(Rmtname,"Request from IP-Host name ="); 32617767Sralph /* The following is to determine if the name given us by 32717767Sralph * the Remote uucico matches any of the names(aliases) 32817767Sralph * given its network number (remote machine) in our 32917767Sralph * host table. 33017767Sralph */ 331*23725Sbloom if (strncmp(q, hp->h_name, SYSNSIZE) == 0) { 33217767Sralph if (Debug > 99) 33317767Sralph logent(q,"Found in host Tables"); 33417767Sralph } else { /* Scan The host aliases */ 33517767Sralph for(alias=hp->h_aliases; *alias!=0 && 336*23725Sbloom strncmp(q, *alias, SYSNSIZE) != 0; ++alias) 33717767Sralph ; 338*23725Sbloom if (strncmp(q, *alias, SYSNSIZE) != 0) { 33917767Sralph logent(q, "FORGED HOSTNAME"); 34017767Sralph logent(inet_ntoa(from.sin_addr), "ORIGINATED AT"); 34123590Sbloom omsg('R',"You're not who you claim to be", Ofn); 34217767Sralph cleanup(0); 34317767Sralph } 34417767Sralph #ifdef DEBUG 34517767Sralph if (Debug> 99) 34617767Sralph logent(q,"Found in host Tables"); 34723590Sbloom #endif DEBUG 34817767Sralph } 34917767Sralph } 35017767Sralph #endif BSDTCP 35117767Sralph 35213639Ssam if (mlock(Rmtname)) { 35313639Ssam omsg('R', "LCK", Ofn); 35413639Ssam cleanup(0); 35513639Ssam } 35613639Ssam else if (callback(Loginuser)) { 35713639Ssam signal(SIGINT, SIG_IGN); 35813639Ssam signal(SIGHUP, SIG_IGN); 35913639Ssam omsg('R', "CB", Ofn); 36013639Ssam logent("CALLBACK", "REQUIRED"); 36113639Ssam /* set up for call back */ 36217767Sralph systat(Rmtname, SS_CALLBACK, "CALLING BACK"); 36313639Ssam gename(CMDPRE, Rmtname, 'C', file); 36413639Ssam close(creat(subfile(file), 0666)); 36513639Ssam xuucico(Rmtname); 36613639Ssam cleanup(0); 36713639Ssam } 36813639Ssam seq = 0; 36913639Ssam while (*p == '-') { 37013639Ssam q = pskip(p); 37113639Ssam switch(*(++p)) { 37213639Ssam case 'x': 37313639Ssam Debug = atoi(++p); 37413639Ssam if (Debug <= 0) 37513639Ssam Debug = 1; 37613639Ssam break; 37713639Ssam case 'Q': 37813639Ssam seq = atoi(++p); 37913639Ssam break; 38018616Sralph case 'p': 38118616Sralph MaxGrade = DefMaxGrade = *++p; 38218616Sralph DEBUG(4, "MaxGrade set to %c\n", MaxGrade); 38318616Sralph break; 38423590Sbloom case 'v': 38523590Sbloom if (strncmp(p, "grade", 5) == 0) { 38623590Sbloom p += 6; 38723590Sbloom MaxGrade = DefMaxGrade = *p++; 38823590Sbloom DEBUG(4, "MaxGrade set to %c\n", MaxGrade); 38923590Sbloom } 39023590Sbloom break; 39113639Ssam default: 39213639Ssam break; 39313639Ssam } 39413639Ssam p = q; 39513639Ssam } 39613639Ssam if (callok(Rmtname) == SS_BADSEQ) { 39713639Ssam logent("BADSEQ", "PREVIOUS"); 39813639Ssam omsg('R', "BADSEQ", Ofn); 39913639Ssam cleanup(0); 40013639Ssam } 40117767Sralph #ifdef GNXSEQ 40213639Ssam if ((ret = gnxseq(Rmtname)) == seq) { 40313639Ssam omsg('R', "OK", Ofn); 40413639Ssam cmtseq(); 40517767Sralph } else { 40617767Sralph #else !GNXSEQ 40717767Sralph if (seq == 0) 40817767Sralph omsg('R', "OK", Ofn); 40913639Ssam else { 41017767Sralph #endif !GNXSEQ 41113639Ssam systat(Rmtname, Stattype[7], Stattext[7]); 41223590Sbloom logent("BAD SEQ", "FAILED HANDSHAKE"); 41317767Sralph #ifdef GNXSEQ 41413639Ssam ulkseq(); 41517767Sralph #endif GNXSEQ 41613639Ssam omsg('R', "BADSEQ", Ofn); 41713639Ssam cleanup(0); 41813639Ssam } 41913639Ssam ttyn = ttyname(Ifn); 42013639Ssam if (ttyn != NULL) 42113639Ssam chmod(ttyn, 0600); 42217767Sralph } else { /* Role == MASTER */ 42317767Sralph struct stat stbuf; 42417767Sralph if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0 42517767Sralph && stbuf.st_mode&S_IFREG) ) 42617767Sralph StdErrIsTty = 1; 42717767Sralph setdebug(0); 42813639Ssam } 42917767Sralph 43013639Ssam loop: 43117767Sralph if(setjmp(Pipebuf)) { /* come here on SIGPIPE */ 43217767Sralph clsacu(); 43317767Sralph close(Ofn); 43417767Sralph close(Ifn); 43517767Sralph Ifn = Ofn = -1; 43617767Sralph rmlock(CNULL); 43717767Sralph sleep(3); 43817767Sralph } 43913639Ssam if (!onesys) { 44017767Sralph struct stat sbuf; 44117767Sralph 44217767Sralph if (!StdErrIsTty) { 44317767Sralph sprintf(file, "%s/%s", RMTDEBUG, Rmtname); 44417767Sralph if (stat(file, &sbuf) == 0 && sbuf.st_size == 0) 44517767Sralph unlink(file); 44617767Sralph } 44713639Ssam ret = gnsys(Rmtname, Spool, CMDPRE); 44817767Sralph setdebug(0); 44913639Ssam if (ret == FAIL) 45013639Ssam cleanup(100); 45123590Sbloom if (ret == SUCCESS) 45213639Ssam cleanup(0); 45317767Sralph } else if (Role == MASTER && callok(Rmtname) != 0) { 45413639Ssam logent("SYSTEM STATUS", "CAN NOT CALL"); 45513639Ssam cleanup(0); 45613639Ssam } 45713639Ssam 45823590Sbloom sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); 45913639Ssam 46017767Sralph signal(SIGINT, SIG_IGN); 46117767Sralph signal(SIGQUIT, SIG_IGN); 46213639Ssam if (Role == MASTER) { 46317767Sralph /* check for /etc/nologin */ 46417767Sralph ultouch(); /* sets nologinflag as a side effect */ 46517767Sralph if (nologinflag) { 46617767Sralph logent(NOLOGIN, "UUCICO SHUTDOWN"); 46723590Sbloom if (Debug > 4) 46817767Sralph logent("DEBUGGING", "continuing anyway"); 46917767Sralph else 47017767Sralph cleanup(1); 47117767Sralph } 47213639Ssam /* master part */ 47313639Ssam signal(SIGHUP, SIG_IGN); 47413639Ssam if (Ifn != -1 && Role == MASTER) { 47513639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 47613639Ssam clsacu(); 47713639Ssam close(Ofn); 47813639Ssam close(Ifn); 47913639Ssam Ifn = Ofn = -1; 48013639Ssam rmlock(CNULL); 48113639Ssam sleep(3); 48213639Ssam } 48313639Ssam sprintf(msg, "call to %s ", Rmtname); 48413639Ssam if (mlock(Rmtname) != 0) { 48513639Ssam logent(msg, "LOCKED"); 48617767Sralph US_SST(us_s_lock); 48713639Ssam goto next; 48813639Ssam } 48913639Ssam Ofn = Ifn = conn(Rmtname); 49013639Ssam if (Ofn < 0) { 49117767Sralph if (Ofn != CF_TIME) 49217767Sralph logent(msg, _FAILED); 49317767Sralph /* avoid excessive 'wrong time' info */ 49423590Sbloom if (Stattype[-Ofn] != SS_WRONGTIME){ 49517767Sralph systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]); 49617767Sralph US_SST(-Ofn); 49717767Sralph UB_SST(-Ofn); 49817767Sralph } 49913639Ssam goto next; 50017767Sralph } else { 50113639Ssam logent(msg, "SUCCEEDED"); 50217767Sralph US_SST(us_s_cok); 50317767Sralph UB_SST(ub_ok); 50413639Ssam } 50517767Sralph #ifdef TCPIP 50617767Sralph /* 50717767Sralph * Determine if we are on TCPIP 50817767Sralph */ 50917767Sralph if (isatty(Ifn) == 0) { 51017767Sralph IsTcpIp = 1; 51117767Sralph DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); 51223590Sbloom } else 51323590Sbloom IsTcpIp = 0; 51417767Sralph #endif 51517767Sralph 51613639Ssam if (setjmp(Sjbuf)) 51713639Ssam goto next; 51813639Ssam signal(SIGALRM, timeout); 51913639Ssam alarm(2 * MAXMSGTIME); 52013639Ssam for (;;) { 52113639Ssam ret = imsg(msg, Ifn); 52213639Ssam if (ret != 0) { 52313639Ssam alarm(0); 52417767Sralph logent("imsg 1", _FAILED); 52517767Sralph goto Failure; 52613639Ssam } 52713639Ssam if (msg[0] == 'S') 52813639Ssam break; 52913639Ssam } 53013639Ssam alarm(MAXMSGTIME); 53117767Sralph #ifdef GNXSEQ 53213639Ssam seq = gnxseq(Rmtname); 53317767Sralph #else !GNXSEQ 53417767Sralph seq = 0; 53517767Sralph #endif !GNXSEQ 53618616Sralph if (MaxGrade != '\177') { 537*23725Sbloom char buf[MAXFULLNAME]; 53823590Sbloom sprintf(buf, " -p%c -vgrade=%c", MaxGrade, MaxGrade); 53918616Sralph strcat(rflags, buf); 54018616Sralph } 54118616Sralph 54223590Sbloom sprintf(msg, "%s -Q%d %s", Myname, seq, rflags); 54323590Sbloom if (MaxGrade != '\177') 54423590Sbloom DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade); 54513639Ssam omsg('S', msg, Ofn); 54613639Ssam for (;;) { 54713639Ssam ret = imsg(msg, Ifn); 54813639Ssam DEBUG(4, "msg-%s\n", msg); 54917767Sralph if (ret != SUCCESS) { 55013639Ssam alarm(0); 55117767Sralph #ifdef GNXSEQ 55213639Ssam ulkseq(); 55317767Sralph #endif GNXSEQ 55417767Sralph logent("imsg 2", _FAILED); 55517767Sralph goto Failure; 55613639Ssam } 55713639Ssam if (msg[0] == 'R') 55813639Ssam break; 55913639Ssam } 56013639Ssam alarm(0); 56113639Ssam if (msg[1] == 'B') { 56213639Ssam /* bad sequence */ 56323590Sbloom logent("BAD SEQ", "FAILED HANDSHAKE"); 56417767Sralph US_SST(us_s_hand); 56517767Sralph systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]); 56617767Sralph #ifdef GNXSEQ 56713639Ssam ulkseq(); 56817767Sralph #endif GNXSEQ 56913639Ssam goto next; 57013639Ssam } 57113639Ssam if (strcmp(&msg[1], "OK") != SAME) { 57223590Sbloom logent(&msg[1], "FAILED HANDSHAKE"); 57317767Sralph US_SST(us_s_hand); 57417767Sralph #ifdef GNXSEQ 57513639Ssam ulkseq(); 57617767Sralph #endif GNXSEQ 57717767Sralph systat(Rmtname, SS_INPROGRESS, 57817767Sralph strcmp(&msg[1], "CB") == SAME? 57923590Sbloom "AWAITING CALLBACK": "FAILED HANDSHAKE"); 58013639Ssam goto next; 58113639Ssam } 58217767Sralph #ifdef GNXSEQ 58313639Ssam cmtseq(); 58417767Sralph #endif GNXSEQ 58513639Ssam } 58617767Sralph DEBUG(1, "Rmtname %s, ", Rmtname); 58713639Ssam DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); 58813639Ssam DEBUG(1, "Ifn - %d, ", Ifn); 58913639Ssam DEBUG(1, "Loginuser - %s\n", Loginuser); 59013639Ssam 59113639Ssam alarm(MAXMSGTIME); 59218616Sralph if (ret=setjmp(Sjbuf)) 59313639Ssam goto Failure; 59413639Ssam ret = startup(Role); 59513639Ssam alarm(0); 59613639Ssam if (ret != SUCCESS) { 59717767Sralph logent("startup", _FAILED); 59813639Ssam Failure: 59917767Sralph US_SST(us_s_start); 60018616Sralph systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" : 60118616Sralph "STARTUP FAILED"); 60213639Ssam goto next; 60317767Sralph } else { 60413639Ssam logent("startup", "OK"); 60517767Sralph US_SST(us_s_gress); 60613639Ssam systat(Rmtname, SS_INPROGRESS, "TALKING"); 60713639Ssam ret = cntrl(Role, wkpre); 60813639Ssam DEBUG(1, "cntrl - %d\n", ret); 60913639Ssam signal(SIGINT, SIG_IGN); 61013639Ssam signal(SIGHUP, SIG_IGN); 61113639Ssam signal(SIGALRM, timeout); 61217767Sralph if (ret == SUCCESS) { 61313639Ssam logent("conversation complete", "OK"); 61417767Sralph US_SST(us_s_ok); 61513639Ssam rmstat(Rmtname); 61613639Ssam 61717767Sralph } else { 61817767Sralph logent("conversation complete", _FAILED); 61917767Sralph US_SST(us_s_cf); 62017767Sralph systat(Rmtname, SS_FAIL, "CONVERSATION FAILED"); 62113639Ssam } 62213639Ssam alarm(MAXMSGTIME); 62313639Ssam DEBUG(4, "send OO %d,", ret); 62413639Ssam if (!setjmp(Sjbuf)) { 62513639Ssam for (;;) { 62613639Ssam omsg('O', "OOOOO", Ofn); 62713639Ssam ret = imsg(msg, Ifn); 62813639Ssam if (ret != 0) 62913639Ssam break; 63013639Ssam if (msg[0] == 'O') 63113639Ssam break; 63213639Ssam } 63313639Ssam } 63413639Ssam alarm(0); 63517767Sralph clsacu(); 63617767Sralph rmlock(CNULL); 63713639Ssam } 63813639Ssam next: 63913639Ssam if (!onesys) { 64013639Ssam goto loop; 64113639Ssam } 64213639Ssam cleanup(0); 64313639Ssam } 64413639Ssam 64517767Sralph #ifndef USG 64613639Ssam struct sgttyb Hupvec; 64713639Ssam #endif 64813639Ssam 64913639Ssam /*** 65013639Ssam * cleanup(code) cleanup and exit with "code" status 65113639Ssam * int code; 65213639Ssam */ 65313639Ssam 65413639Ssam cleanup(code) 65513639Ssam register int code; 65613639Ssam { 65713639Ssam register char *ttyn; 65817767Sralph char bfr[BUFSIZ]; 65917767Sralph struct stat sbuf; 66013639Ssam 66113639Ssam signal(SIGINT, SIG_IGN); 66213639Ssam signal(SIGHUP, SIG_IGN); 66313639Ssam rmlock(CNULL); 66413639Ssam clsacu(); 66513639Ssam logcls(); 66613639Ssam if (Role == SLAVE) { 66717767Sralph if (!IsTcpIp) { 66817767Sralph #ifdef USG 66913639Ssam Savettyb.c_cflag |= HUPCL; 67023590Sbloom (void) ioctl(0, TCSETA, &Savettyb); 67117767Sralph #else !USG 67223590Sbloom (void) ioctl(0, TIOCHPCL, STBNULL); 67318616Sralph #ifdef TIOCSDTR 67423590Sbloom (void) ioctl(0, TIOCCDTR, STBNULL); 67518616Sralph sleep(2); 67623590Sbloom (void) ioctl(0, TIOCSDTR, STBNULL); 67718616Sralph #else !TIOCSDTR 67823590Sbloom (void) ioctl(0, TIOCGETP, &Hupvec); 67918616Sralph #endif !TIOCSDTR 68013639Ssam Hupvec.sg_ispeed = B0; 68113639Ssam Hupvec.sg_ospeed = B0; 68223590Sbloom (void) ioctl(0, TIOCSETP, &Hupvec); 68313639Ssam sleep(2); 68423590Sbloom (void) ioctl(0, TIOCSETP, &Savettyb); 68517767Sralph /* make *sure* exclusive access is off */ 68623590Sbloom (void) ioctl(0, TIOCNXCL, STBNULL); 68717767Sralph #endif !USG 68813639Ssam } 68913639Ssam ttyn = ttyname(Ifn); 69013639Ssam if (ttyn != NULL) 69113639Ssam chmod(ttyn, 0600); 69213639Ssam } 69313639Ssam if (Ofn != -1) { 69413639Ssam if (Role == MASTER) 69513639Ssam write(Ofn, EOTMSG, strlen(EOTMSG)); 69613639Ssam close(Ifn); 69713639Ssam close(Ofn); 69813639Ssam } 69918616Sralph #ifdef DIALINOUT 70018616Sralph /* reenable logins on dialout */ 70118616Sralph reenable(); 70218616Sralph #endif DIALINOUT 70313639Ssam if (code == 0) 70413639Ssam xuuxqt(); 70517767Sralph else 70617767Sralph DEBUG(1, "exit code %d\n", code); 70717767Sralph sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname); 70817767Sralph if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0) 70917767Sralph unlink(bfr); 71017767Sralph sprintf(bfr, "%s/%d", RMTDEBUG, getpid()); 71117767Sralph unlink(bfr); 71213639Ssam exit(code); 71313639Ssam } 71413639Ssam 71513639Ssam /*** 71613639Ssam * onintr(inter) interrupt - remove locks and exit 71713639Ssam */ 71813639Ssam 71913639Ssam onintr(inter) 72013639Ssam register int inter; 72113639Ssam { 72213639Ssam char str[30]; 72313639Ssam signal(inter, SIG_IGN); 72413639Ssam sprintf(str, "SIGNAL %d", inter); 72513639Ssam logent(str, "CAUGHT"); 72617767Sralph US_SST(us_s_intr); 72723590Sbloom if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) 72817767Sralph systat(Rmtname, SS_FAIL, str); 72917767Sralph if (inter == SIGPIPE && !onesys) 73017767Sralph longjmp(Pipebuf, 1); 73113639Ssam cleanup(inter); 73213639Ssam } 73313639Ssam 73413639Ssam /* 73513639Ssam * Catch a special signal 73613639Ssam * (SIGFPE, ugh), and toggle debugging between 0 and 30. 73713639Ssam * Handy for looking in on long running uucicos. 73813639Ssam */ 73917767Sralph setdebug(code) 74017767Sralph int code; 74113639Ssam { 74217767Sralph char buf[BUFSIZ]; 74317767Sralph 74423590Sbloom if (code) { 74523590Sbloom if (Debug == 0) 74623590Sbloom Debug = 30; 74723590Sbloom else 74823590Sbloom Debug = 0; 74923590Sbloom } 75023590Sbloom if (Debug && !StdErrIsTty) { 75117767Sralph sprintf(buf,"%s/%s", RMTDEBUG, Rmtname); 75217767Sralph unlink(buf); 75317767Sralph freopen(buf, "w", stderr); 75417767Sralph #ifdef BSD4_2 75517767Sralph setlinebuf(stderr); 75617767Sralph #else !BSD4_2 75717767Sralph setbuf(stderr, NULL); 75817767Sralph #endif !BSD4_2 75917767Sralph } 76013639Ssam } 76113639Ssam 76213639Ssam 76313639Ssam /*** 76413639Ssam * fixmode(tty) fix kill/echo/raw on line 76513639Ssam * 76613639Ssam * return codes: none 76713639Ssam */ 76813639Ssam 76913639Ssam fixmode(tty) 77013639Ssam register int tty; 77113639Ssam { 77217767Sralph #ifdef USG 77313639Ssam struct termio ttbuf; 77413639Ssam #endif 77517767Sralph #ifndef USG 77613639Ssam struct sgttyb ttbuf; 77713639Ssam #endif 77813639Ssam 77917767Sralph if (IsTcpIp) 78013639Ssam return; 78117767Sralph #ifdef USG 78223590Sbloom ioctl(tty, TCGETA, &ttbuf); 78313639Ssam ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; 78413639Ssam ttbuf.c_cflag &= (CBAUD); 78513639Ssam ttbuf.c_cflag |= (CS8|CREAD); 78613639Ssam ttbuf.c_cc[VMIN] = 6; 78713639Ssam ttbuf.c_cc[VTIME] = 1; 78823590Sbloom ioctl(tty, TCSETA, &ttbuf); 78913639Ssam #endif 79017767Sralph #ifndef USG 79113639Ssam ioctl(tty, TIOCGETP, &ttbuf); 79213639Ssam ttbuf.sg_flags = (ANYP | RAW); 79323590Sbloom ioctl(tty, TIOCSETP, &ttbuf); 79413639Ssam #endif 79517767Sralph #ifndef USG 79623590Sbloom ioctl(tty, TIOCEXCL, STBNULL); 79713639Ssam #endif 79813639Ssam } 79913639Ssam 80013639Ssam 80123590Sbloom /* 80213639Ssam * timeout() catch SIGALRM routine 80313639Ssam */ 80413639Ssam 80513639Ssam timeout() 80613639Ssam { 80723590Sbloom extern int HaveSentHup; 80823590Sbloom if (!HaveSentHup) { 80923590Sbloom logent(Rmtname, "TIMEOUT"); 81023590Sbloom if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) { 81123590Sbloom US_SST(us_s_tmot); 81223590Sbloom systat(Rmtname, SS_FAIL, "TIMEOUT"); 81323590Sbloom } 81417767Sralph } 81513639Ssam longjmp(Sjbuf, 1); 81613639Ssam } 81713639Ssam 81813639Ssam static char * 81913639Ssam pskip(p) 82013639Ssam register char *p; 82113639Ssam { 82217767Sralph while(*p && *p != ' ') 82313639Ssam ++p; 82423590Sbloom while(*p && *p == ' ') 82517767Sralph *p++ = 0; 82617767Sralph return p; 82713639Ssam } 828