xref: /csrg-svn/usr.bin/uucp/uucico/cico.c (revision 33945)
113639Ssam #ifndef lint
2*33945Srick static char sccsid[] = "@(#)cico.c	5.16	(Berkeley) 04/05/88";
313639Ssam #endif
413639Ssam 
523590Sbloom #include <signal.h>
613639Ssam #include "uucp.h"
713639Ssam #include <setjmp.h>
817767Sralph #ifdef	USG
913639Ssam #include <termio.h>
1033559Srick #include <fcntl.h>
1113639Ssam #endif
1217767Sralph #ifndef	USG
1313639Ssam #include <sgtty.h>
1413639Ssam #endif
1517767Sralph #ifdef BSDTCP
1617767Sralph #include <netdb.h>
1717767Sralph #include <netinet/in.h>
1817767Sralph #include <sys/socket.h>
1917767Sralph #endif BSDTCP
2017767Sralph #include <sys/stat.h>
2133559Srick #ifdef BSD4_2
2233559Srick #include <sys/time.h>
2333559Srick #include <fcntl.h>
2433559Srick #else
2533559Srick #include <time.h>
2633559Srick #endif
2717767Sralph #include "uust.h"
2817767Sralph #include "uusub.h"
2913639Ssam 
3023590Sbloom #if defined(VMS) && defined(BSDTCP)
3123590Sbloom #define NOGETPEER
3223590Sbloom #endif
3323590Sbloom 
3417767Sralph jmp_buf Sjbuf;
3517767Sralph jmp_buf Pipebuf;
3613639Ssam 
3717767Sralph /*  call fail text  */
3813639Ssam char *Stattext[] = {
3913639Ssam 	"",
4013639Ssam 	"BAD SYSTEM",
4117767Sralph 	"WRONG TIME TO CALL",
4213639Ssam 	"SYSTEM LOCKED",
4313639Ssam 	"NO DEVICE",
4425703Sbloom 	"CALL FAILED",
4513639Ssam 	"LOGIN FAILED",
4613639Ssam 	"BAD SEQUENCE"
4717767Sralph };
4813639Ssam 
4917767Sralph /*  call fail codes  */
5017767Sralph int Stattype[] = {
5117767Sralph 	0,
5217767Sralph 	0,
5317767Sralph 	SS_WRONGTIME,
5417767Sralph 	0,
5517767Sralph 	SS_NODEVICE,
5617767Sralph 	SS_FAIL,
5717767Sralph 	SS_FAIL,
5817767Sralph 	SS_BADSEQ
5917767Sralph };
6013639Ssam 
6125703Sbloom 				/* Arguments to setdebug():		     */
6225703Sbloom #define DBG_TEMP  0		/*   Create a temporary audit file	     */
6325703Sbloom #define DBG_PERM  1		/*   Create a permanent audit file	     */
6425703Sbloom #define DBG_CLEAN 2		/*   Cleanup, discard temp file		     */
6513639Ssam 
6617767Sralph int ReverseRole = 0;
6717767Sralph int Role = SLAVE;
6833559Srick int InitialRole = SLAVE;
6933559Srick long StartTime;
7017767Sralph int onesys = 0;
7118616Sralph int turntime = 30 * 60;	/* 30 minutes expressed in seconds */
7225703Sbloom char *ttyn = NULL;
7317767Sralph extern int LocalOnly;
7425703Sbloom extern int errno;
7518616Sralph extern char MaxGrade, DefMaxGrade;
7618616Sralph extern char Myfullname[];
7717767Sralph 
7833559Srick long Bytes_Sent, Bytes_Received;
7933559Srick 
8017767Sralph #ifdef	USG
8113639Ssam struct termio Savettyb;
8213639Ssam #endif
8317767Sralph #ifndef	USG
8413639Ssam struct sgttyb Savettyb;
8513639Ssam #endif
8613639Ssam 
8725703Sbloom /*
8825703Sbloom  *	this program is used  to place a call to a
8913639Ssam  *	remote machine, login, and copy files between the two machines.
9013639Ssam  */
9113639Ssam main(argc, argv)
9225703Sbloom int argc;
93*33945Srick char **argv;
9413639Ssam {
9513639Ssam 	register int ret;
9613639Ssam 	int seq;
9713639Ssam 	char wkpre[NAMESIZE], file[NAMESIZE];
9825703Sbloom 	char msg[MAXFULLNAME], *q;
9913639Ssam 	register char *p;
10025703Sbloom 	extern onintr(), timeout(), dbg_signal();
10113639Ssam 	extern char *pskip();
102*33945Srick 	extern char *optarg;
103*33945Srick 	extern int optind;
10423725Sbloom 	char rflags[MAXFULLNAME];
10523590Sbloom #ifdef NOGETPEER
10617767Sralph 	u_long Hostnumber = 0;
10723590Sbloom #endif NOGETPEER
10813639Ssam 
10913639Ssam 	strcpy(Progname, "uucico");
11013639Ssam 
11126149Sbloom #ifdef BSD4_2
112*33945Srick 	sigsetmask(0L);	/* in case we inherit blocked signals */
11326149Sbloom #endif BSD4_2
11413639Ssam 	signal(SIGINT, onintr);
11513639Ssam 	signal(SIGHUP, onintr);
11613639Ssam 	signal(SIGQUIT, onintr);
11713639Ssam 	signal(SIGTERM, onintr);
11813639Ssam 	signal(SIGPIPE, onintr);	/* 4.1a tcp-ip stupidity */
11925703Sbloom 	signal(SIGFPE, dbg_signal);
12013639Ssam 	ret = guinfo(getuid(), User, msg);
12113639Ssam 	strcpy(Loginuser, User);
12223590Sbloom 	uucpname(Myname);
123*33945Srick 	if (ret == FAIL) {
124*33945Srick 		syslog(LOG_ERR, "can't get uid");
125*33945Srick 		cleanup(FAIL);
126*33945Srick 	}
12713639Ssam 
12825703Sbloom 	setbuf (stderr, CNULL);
12925703Sbloom 
13025703Sbloom 	rflags[0] = '\0';
13113639Ssam 	umask(WFMASK);
13213639Ssam 	strcpy(Rmtname, Myname);
13313639Ssam 	Ifn = Ofn = -1;
134*33945Srick 	while ((ret = getopt(argc, argv, "RLd:g:p:r:s:x:t:")) != EOF)
135*33945Srick 		switch(ret){
13613639Ssam 		case 'd':
137*33945Srick 			Spool = optarg;
13813639Ssam 			break;
13913639Ssam 		case 'g':
14018616Sralph 		case 'p':
141*33945Srick 			MaxGrade = DefMaxGrade = *optarg;
14213639Ssam 			break;
14313639Ssam 		case 'r':
144*33945Srick 			Role = atoi(optarg);
14513639Ssam 			break;
14617767Sralph 		case 'R':
14717767Sralph 			ReverseRole++;
14817767Sralph 			Role = MASTER;
14917767Sralph 			break;
15013639Ssam 		case 's':
151*33945Srick 			strncpy(Rmtname, optarg, MAXBASENAME);
15223590Sbloom 			Rmtname[MAXBASENAME] = '\0';
15313639Ssam 			if (Rmtname[0] != '\0')
15413639Ssam 				onesys = 1;
15513639Ssam 			break;
15613639Ssam 		case 'x':
157*33945Srick 			Debug = atoi(optarg);
15813639Ssam 			if (Debug <= 0)
15913639Ssam 				Debug = 1;
160*33945Srick 			strcat(rflags, argv[optind-1]);
16113639Ssam 			break;
16218616Sralph 		case 't':
163*33945Srick 			turntime = atoi(optarg)*60;/* minutes to seconds */
16418616Sralph 			break;
16517767Sralph 		case 'L':	/* local calls only */
16617767Sralph 			LocalOnly++;
16717767Sralph 			break;
16823590Sbloom #ifdef NOGETPEER
16917767Sralph 		case 'h':
17017767Sralph 			Hostnumber = inet_addr(&argv[1][2]);
17117767Sralph 			break;
17223590Sbloom #endif NOGETPEER
173*33945Srick 		case '?':
17413639Ssam 		default:
175*33945Srick 			fprintf(stderr, "unknown flag %s (ignored)\n",
176*33945Srick 				argv[optind-1]);
17713639Ssam 			break;
17813639Ssam 		}
17913639Ssam 
180*33945Srick 	while (optind < argc)
181*33945Srick 		fprintf(stderr, "unknown argument %s (ignored)\n",
182*33945Srick 			argv[optind++]);
18317767Sralph 
18427069Sbloom 	if (Debug && Role == MASTER)
18527069Sbloom 		chkdebug();
18627069Sbloom 
18725124Sbloom 	/* Try to run as uucp */
18817767Sralph 	setgid(getegid());
18917767Sralph 	setuid(geteuid());
19017767Sralph #ifdef	TIOCNOTTY
19117767Sralph 	/*
19217767Sralph 	 * detach uucico from controlling terminal
19317767Sralph 	 * to defend against rlogind sending us a SIGKILL (!!!)
19417767Sralph 	 */
19517767Sralph 	if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) {
19617767Sralph 		ioctl(ret, TIOCNOTTY, STBNULL);
19717767Sralph 		close(ret);
19817767Sralph 	}
19917767Sralph #endif TIOCNOTTY
20017767Sralph #ifdef BSD4_2
20125517Stef 	if (getpgrp(0) == 0) { /* We have no controlling terminal */
20217767Sralph 		setpgrp(0, getpid());
20317767Sralph 	}
204*33945Srick #ifdef USE_SYSLOG
205*33945Srick #ifdef BSD4_3
206*33945Srick 	openlog("uucico", LOG_PID, LOG_UUCP);
207*33945Srick #else /* !BSD4_3 */
208*33945Srick 	openlog("uucico", LOG_PID);
209*33945Srick #endif /* !BSD4_3 */
210*33945Srick #endif /* USE_SYSLOG */
21117767Sralph #endif BSD4_2
21217767Sralph 
213*33945Srick #ifdef BSD4_3
214*33945Srick 	unsetenv("TZ");		/* We don't want him resetting our time zone */
215*33945Srick #endif /* !BSD4_3 */
216*33945Srick 
217*33945Srick 	if (subchdir(Spool) < 0) {
218*33945Srick 		syslog(LOG_ERR, "chdir(%s) failed: %m", Spool);
219*33945Srick 		cleanup(FAIL);
220*33945Srick 	}
221*33945Srick 
22213639Ssam 	strcpy(Wrkdir, Spool);
22313639Ssam 
22425703Sbloom 	if (Debug) {
22525703Sbloom 		setdebug ((Role == SLAVE) ? DBG_TEMP : DBG_PERM);
22625703Sbloom 		if (Debug > 0)
22725703Sbloom 			logent ("Local Enabled", "DEBUG");
22825703Sbloom 	}
22925703Sbloom 
23025703Sbloom 	/*
23125703Sbloom 	 * First time through: If we're the slave, do initial checking.
23225703Sbloom 	 */
23313639Ssam 	if (Role == SLAVE) {
23417767Sralph 		/* check for /etc/nologin */
23525124Sbloom 		if (access(NOLOGIN, 0) == 0) {
23617767Sralph 			logent(NOLOGIN, "UUCICO SHUTDOWN");
23723590Sbloom 			if (Debug > 4)
23817767Sralph 				logent("DEBUGGING", "continuing anyway");
23917767Sralph 			else
24017767Sralph 				cleanup(1);
24117767Sralph 		}
24225703Sbloom 		Ifn = 0;
24325703Sbloom 		Ofn = 1;
24417767Sralph #ifdef	TCPIP
24517767Sralph 		/*
24617767Sralph 		 * Determine if we are on TCPIP
24717767Sralph 		 */
24833559Srick 		if (isatty(Ifn) == 0) {
24917767Sralph 			IsTcpIp = 1;
25017767Sralph 			DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
25123590Sbloom 		} else
25223590Sbloom 			IsTcpIp = 0;
25317767Sralph #endif TCPIP
25413639Ssam 		/* initial handshake */
25513639Ssam 		onesys = 1;
25617767Sralph 		if (!IsTcpIp) {
25717767Sralph #ifdef	USG
25825703Sbloom 			ret = ioctl(Ifn, TCGETA, &Savettyb);
25913639Ssam 			Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
26013639Ssam 			Savettyb.c_oflag |= OPOST;
26113639Ssam 			Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
26217767Sralph #else !USG
26325703Sbloom 			ret = ioctl(Ifn, TIOCGETP, &Savettyb);
26413639Ssam 			Savettyb.sg_flags |= ECHO;
26513639Ssam 			Savettyb.sg_flags &= ~RAW;
26617767Sralph #endif !USG
26725703Sbloom 			ttyn = ttyname(Ifn);
26813639Ssam 		}
26913639Ssam 		fixmode(Ifn);
27025703Sbloom 
27125703Sbloom 		/*
27225703Sbloom 		 * Initial Message -- tell them we're here, and who we are.
27325703Sbloom 		 */
27418616Sralph 		sprintf(msg, "here=%s", Myfullname);
27517767Sralph 		omsg('S', msg, Ofn);
27613639Ssam 		signal(SIGALRM, timeout);
27733559Srick 		alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
27813639Ssam 		if (setjmp(Sjbuf)) {
27913639Ssam 			/* timed out */
28017767Sralph 			if (!IsTcpIp) {
28117767Sralph #ifdef	USG
28225703Sbloom 				ret = ioctl(Ifn, TCSETA, &Savettyb);
28325703Sbloom 
28423590Sbloom #else	!USG
28525703Sbloom 				ret = ioctl(Ifn, TIOCSETP, &Savettyb);
28623590Sbloom #endif !USG
28713639Ssam 			}
28817767Sralph 			cleanup(0);
28913639Ssam 		}
29013639Ssam 		for (;;) {
29113639Ssam 			ret = imsg(msg, Ifn);
29225703Sbloom 			if (ret != SUCCESS) {
29313639Ssam 				alarm(0);
29417767Sralph 				if (!IsTcpIp) {
29517767Sralph #ifdef	USG
29625703Sbloom 					ret = ioctl(Ifn, TCSETA, &Savettyb);
29723590Sbloom #else	!USG
29825703Sbloom 					ret = ioctl(Ifn, TIOCSETP, &Savettyb);
29923590Sbloom #endif !USG
30013639Ssam 				}
30117767Sralph 				cleanup(0);
30213639Ssam 			}
30313639Ssam 			if (msg[0] == 'S')
30413639Ssam 				break;
30513639Ssam 		}
30613639Ssam 		alarm(0);
30713639Ssam 		q = &msg[1];
30813639Ssam 		p = pskip(q);
30923590Sbloom 		strncpy(Rmtname, q, MAXBASENAME);
31023590Sbloom 		Rmtname[MAXBASENAME] = '\0';
31125703Sbloom 
31225703Sbloom 		/*
31325703Sbloom 		 * Now that we know who they are, give the audit file the right
31425703Sbloom 		 * name.
31525703Sbloom 		 */
31625703Sbloom 		setdebug (DBG_PERM);
31713639Ssam 		DEBUG(4, "sys-%s\n", Rmtname);
31823725Sbloom 		/* The versys will also do an alias on the incoming name */
31923725Sbloom 		if (versys(&Rmtname)) {
32033559Srick #ifdef	NOSTRANGERS
32123725Sbloom 			/* If we don't know them, we won't talk to them... */
322*33945Srick 			syslog(LOG_WARNING, "Unknown host: %s", Rmtname);
32323590Sbloom 			omsg('R', "You are unknown to me", Ofn);
32423590Sbloom 			cleanup(0);
32523725Sbloom #endif	NOSTRANGERS
32623590Sbloom 		}
32717767Sralph #ifdef BSDTCP
32817767Sralph 		/* we must make sure they are really who they say they
32917767Sralph 		 * are. We compare the hostnumber with the number in the hosts
33017767Sralph 		 * table for the site they claim to be.
33117767Sralph 		 */
33217767Sralph 		if (IsTcpIp) {
33317767Sralph 			struct hostent *hp;
33417767Sralph 			char *cpnt, *inet_ntoa();
33525703Sbloom 			int fromlen;
33617767Sralph 			struct sockaddr_in from;
33725124Sbloom 			extern char PhoneNumber[];
33817767Sralph 
33923590Sbloom #ifdef	NOGETPEER
34023590Sbloom 			from.sin_addr.s_addr = Hostnumber;
34123590Sbloom 			from.sin_family = AF_INET;
34223590Sbloom #else	!NOGETPEER
34325703Sbloom 			fromlen = sizeof(from);
34425703Sbloom 			if (getpeername(Ifn, &from, &fromlen) < 0) {
34517767Sralph 				logent(Rmtname, "NOT A TCP CONNECTION");
34617767Sralph 				omsg('R', "NOT TCP", Ofn);
34717767Sralph 				cleanup(0);
34817767Sralph 			}
34923590Sbloom #endif	!NOGETPEER
35017767Sralph 			hp = gethostbyaddr(&from.sin_addr,
35117767Sralph 				sizeof (struct in_addr), from.sin_family);
35225703Sbloom 			if (hp == NULL) {
35317767Sralph 				/* security break or just old host table? */
35417767Sralph 				logent(Rmtname, "UNKNOWN IP-HOST Name =");
35517767Sralph 				cpnt = inet_ntoa(from.sin_addr),
35617767Sralph 				logent(cpnt, "UNKNOWN IP-HOST Number =");
35717767Sralph 				sprintf(wkpre, "%s/%s isn't in my host table",
35817767Sralph 					Rmtname, cpnt);
35917767Sralph 				omsg('R' ,wkpre ,Ofn);
36017767Sralph 				cleanup(0);
36117767Sralph 			}
36225703Sbloom 			if (Debug > 99)
36317767Sralph 				logent(Rmtname,"Request from IP-Host name =");
36425124Sbloom 			/*
36525124Sbloom 			 * The following is to determine if the name given us by
36625124Sbloom 			 * the Remote uucico matches any of the names
36717767Sralph 			 * given its network number (remote machine) in our
36817767Sralph 			 * host table.
36925124Sbloom 			 * We could check the aliases, but that won't work in
37025124Sbloom 			 * all cases (like if you are running the domain
37125124Sbloom 			 * server, where you don't get any aliases). The only
37225124Sbloom 			 * reliable way I can think of that works in ALL cases
37325124Sbloom 			 * is too look up the site in L.sys and see if the
37425124Sbloom 			 * sitename matches what we would call him if we
37525124Sbloom 			 * originated the call.
37617767Sralph 			 */
37725124Sbloom 			/* PhoneNumber contains the official network name of the 			   host we are checking. (set in versys.c) */
37825124Sbloom 			if (sncncmp(PhoneNumber, hp->h_name, SYSNSIZE) == 0) {
37917767Sralph 				if (Debug > 99)
38017767Sralph 					logent(q,"Found in host Tables");
38125124Sbloom 			} else {
38225124Sbloom 				logent(hp->h_name, "FORGED HOSTNAME");
38325124Sbloom 				logent(inet_ntoa(from.sin_addr), "ORIGINATED AT");
38425124Sbloom 				logent(PhoneNumber, "SHOULD BE");
38525124Sbloom 				sprintf(wkpre, "You're not who you claim to be: %s !=  %s", hp->h_name, PhoneNumber);
38625124Sbloom 				omsg('R', wkpre, Ofn);
38725124Sbloom 				cleanup(0);
38817767Sralph 			}
38917767Sralph 		}
39017767Sralph #endif	BSDTCP
39117767Sralph 
39225703Sbloom 		if (mlock(Rmtname)) {
39313639Ssam 			omsg('R', "LCK", Ofn);
39413639Ssam 			cleanup(0);
39513639Ssam 		}
39613639Ssam 		else if (callback(Loginuser)) {
39713639Ssam 			signal(SIGINT, SIG_IGN);
39813639Ssam 			signal(SIGHUP, SIG_IGN);
39913639Ssam 			omsg('R', "CB", Ofn);
40013639Ssam 			logent("CALLBACK", "REQUIRED");
40113639Ssam 			/*  set up for call back  */
40217767Sralph 			systat(Rmtname, SS_CALLBACK, "CALLING BACK");
40313639Ssam 			gename(CMDPRE, Rmtname, 'C', file);
40413639Ssam 			close(creat(subfile(file), 0666));
40513639Ssam 			xuucico(Rmtname);
40613639Ssam 			cleanup(0);
40713639Ssam 		}
40813639Ssam 		seq = 0;
40913639Ssam 		while (*p == '-') {
41013639Ssam 			q = pskip(p);
41113639Ssam 			switch(*(++p)) {
41213639Ssam 			case 'x':
41325703Sbloom 				if (Debug == 0) {
41425703Sbloom 					Debug = atoi(++p);
41525703Sbloom 					if (Debug <= 0)
41625703Sbloom 						Debug = 1;
41725703Sbloom 					setdebug(DBG_PERM);
41825703Sbloom 					if (Debug > 0)
41925703Sbloom 						logent("Remote Enabled", "DEBUG");
42025703Sbloom 				} else {
42125703Sbloom 					DEBUG(1, "Remote debug request ignored\n",
42225703Sbloom 					   CNULL);
42325703Sbloom 				}
42413639Ssam 				break;
42513639Ssam 			case 'Q':
42613639Ssam 				seq = atoi(++p);
42713639Ssam 				break;
42818616Sralph 			case 'p':
42918616Sralph 				MaxGrade = DefMaxGrade = *++p;
43018616Sralph 				DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
43118616Sralph 				break;
43223590Sbloom 			case 'v':
43323590Sbloom 				if (strncmp(p, "grade", 5) == 0) {
43423590Sbloom 					p += 6;
43523590Sbloom 					MaxGrade = DefMaxGrade = *p++;
43623590Sbloom 					DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
43723590Sbloom 				}
43823590Sbloom 				break;
43913639Ssam 			default:
44013639Ssam 				break;
44113639Ssam 			}
44213639Ssam 			p = q;
44313639Ssam 		}
44413639Ssam 		if (callok(Rmtname) == SS_BADSEQ) {
44513639Ssam 			logent("BADSEQ", "PREVIOUS");
44613639Ssam 			omsg('R', "BADSEQ", Ofn);
44713639Ssam 			cleanup(0);
44813639Ssam 		}
44917767Sralph #ifdef GNXSEQ
45013639Ssam 		if ((ret = gnxseq(Rmtname)) == seq) {
45113639Ssam 			omsg('R', "OK", Ofn);
45213639Ssam 			cmtseq();
45317767Sralph 		} else {
45417767Sralph #else !GNXSEQ
45517767Sralph 		if (seq == 0)
45617767Sralph 			omsg('R', "OK", Ofn);
45713639Ssam 		else {
45817767Sralph #endif !GNXSEQ
45913639Ssam 			systat(Rmtname, Stattype[7], Stattext[7]);
46023590Sbloom 			logent("BAD SEQ", "FAILED HANDSHAKE");
46117767Sralph #ifdef GNXSEQ
46213639Ssam 			ulkseq();
46317767Sralph #endif GNXSEQ
46413639Ssam 			omsg('R', "BADSEQ", Ofn);
46513639Ssam 			cleanup(0);
46613639Ssam 		}
46713639Ssam 		if (ttyn != NULL)
46813639Ssam 			chmod(ttyn, 0600);
46913639Ssam 	}
47017767Sralph 
47113639Ssam loop:
47217767Sralph 	if(setjmp(Pipebuf)) {	/* come here on SIGPIPE	*/
47317767Sralph 		clsacu();
47417767Sralph 		close(Ofn);
47517767Sralph 		close(Ifn);
47617767Sralph 		Ifn = Ofn = -1;
47717767Sralph 		rmlock(CNULL);
47817767Sralph 		sleep(3);
47917767Sralph 	}
48013639Ssam 	if (!onesys) {
48133559Srick 		do_connect_accounting();
482*33945Srick #ifdef DIALINOUT
483*33945Srick 		/* reenable logins on dialout */
484*33945Srick 		reenable();
485*33945Srick #endif DIALINOUT
48633559Srick 		StartTime = 0;
48713639Ssam 		ret = gnsys(Rmtname, Spool, CMDPRE);
48825703Sbloom 		setdebug(DBG_PERM);
48913639Ssam 		if (ret == FAIL)
49013639Ssam 			cleanup(100);
49133559Srick 		else if (ret == SUCCESS)
49213639Ssam 			cleanup(0);
49317767Sralph 	} else if (Role == MASTER && callok(Rmtname) != 0) {
49413639Ssam 		logent("SYSTEM STATUS", "CAN NOT CALL");
49513639Ssam 		cleanup(0);
49613639Ssam 	}
49713639Ssam 
49823590Sbloom 	sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname);
49933559Srick 	StartTime = 0;
50033559Srick 	Bytes_Sent = Bytes_Received = 0L;
50113639Ssam 
50217767Sralph 	signal(SIGINT, SIG_IGN);
50317767Sralph 	signal(SIGQUIT, SIG_IGN);
50413639Ssam 	if (Role == MASTER) {
50533559Srick 		extern char LineType[];
50617767Sralph 		/* check for /etc/nologin */
50725124Sbloom 		if (access(NOLOGIN, 0) == 0) {
50817767Sralph 			logent(NOLOGIN, "UUCICO SHUTDOWN");
50923590Sbloom 			if (Debug > 4)
51017767Sralph 				logent("DEBUGGING", "continuing anyway");
51117767Sralph 			else
51217767Sralph 				cleanup(1);
51317767Sralph 		}
51413639Ssam 		/*  master part */
51513639Ssam 		signal(SIGHUP, SIG_IGN);
51613639Ssam 		if (Ifn != -1 && Role == MASTER) {
51713639Ssam 			write(Ofn, EOTMSG, strlen(EOTMSG));
51813639Ssam 			clsacu();
51913639Ssam 			close(Ofn);
52013639Ssam 			close(Ifn);
52113639Ssam 			Ifn = Ofn = -1;
52213639Ssam 			rmlock(CNULL);
52313639Ssam 			sleep(3);
52413639Ssam 		}
52525124Sbloom 		if (mlock(Rmtname) != SUCCESS) {
52633559Srick 			DEBUG(1, "LOCKED: call to %s\n", Rmtname);
52717767Sralph 			US_SST(us_s_lock);
52813639Ssam 			goto next;
52913639Ssam 		}
53013639Ssam 		Ofn = Ifn = conn(Rmtname);
53133559Srick 		sprintf(msg, "call to %s via %s", Rmtname, LineType);
53213639Ssam 		if (Ofn < 0) {
53317767Sralph 			if (Ofn != CF_TIME)
53417767Sralph 				logent(msg, _FAILED);
53517767Sralph 			/* avoid excessive 'wrong time' info */
53623590Sbloom 			if (Stattype[-Ofn] != SS_WRONGTIME){
53717767Sralph 				systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]);
53817767Sralph 				US_SST(-Ofn);
53917767Sralph 				UB_SST(-Ofn);
54017767Sralph 			}
54113639Ssam 			goto next;
54217767Sralph 		} else {
54313639Ssam 			logent(msg, "SUCCEEDED");
54417767Sralph 			US_SST(us_s_cok);
54517767Sralph 			UB_SST(ub_ok);
54613639Ssam 		}
54733559Srick 		InitialRole = MASTER;
54817767Sralph #ifdef	TCPIP
54917767Sralph 		/*
55017767Sralph 		 * Determine if we are on TCPIP
55117767Sralph 		 */
55225703Sbloom 		if (isatty(Ifn) == 0) {
55317767Sralph 			IsTcpIp = 1;
55417767Sralph 			DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
55523590Sbloom 		} else
55623590Sbloom 			IsTcpIp = 0;
55717767Sralph #endif
55817767Sralph 
55913639Ssam 		if (setjmp(Sjbuf))
56013639Ssam 			goto next;
56113639Ssam 		signal(SIGALRM, timeout);
56233559Srick 		alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME*2);
56313639Ssam 		for (;;) {
56413639Ssam 			ret = imsg(msg, Ifn);
56533559Srick 			if (ret != SUCCESS) {
56613639Ssam 				alarm(0);
56733559Srick 				DEBUG(4,"\nimsg failed: errno %d\n", errno);
56817767Sralph 				logent("imsg 1", _FAILED);
56917767Sralph 				goto Failure;
57013639Ssam 			}
57113639Ssam 			if (msg[0] == 'S')
57213639Ssam 				break;
57313639Ssam 		}
57433559Srick 		alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
57517767Sralph #ifdef GNXSEQ
57613639Ssam 		seq = gnxseq(Rmtname);
57717767Sralph #else !GNXSEQ
57817767Sralph 		seq = 0;
57917767Sralph #endif !GNXSEQ
58018616Sralph 		if (MaxGrade != '\177') {
58123590Sbloom 			DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade);
58225963Sbloom 			sprintf(msg, "%s -Q%d -p%c -vgrade=%c %s",
58325963Sbloom 				Myname, seq, MaxGrade, MaxGrade, rflags);
58425963Sbloom 		} else
58525963Sbloom 			sprintf(msg, "%s -Q%d %s", Myname, seq, rflags);
58613639Ssam 		omsg('S', msg, Ofn);
58713639Ssam 		for (;;) {
58813639Ssam 			ret = imsg(msg, Ifn);
58913639Ssam 			DEBUG(4, "msg-%s\n", msg);
59017767Sralph 			if (ret != SUCCESS) {
59113639Ssam 				alarm(0);
59217767Sralph #ifdef GNXSEQ
59313639Ssam 				ulkseq();
59417767Sralph #endif GNXSEQ
59517767Sralph 				logent("imsg 2", _FAILED);
59617767Sralph 				goto Failure;
59713639Ssam 			}
59813639Ssam 			if (msg[0] == 'R')
59913639Ssam 				break;
60013639Ssam 		}
60113639Ssam 		alarm(0);
60213639Ssam 		if (msg[1] == 'B') {
60313639Ssam 			/* bad sequence */
60423590Sbloom 			logent("BAD SEQ", "FAILED HANDSHAKE");
60517767Sralph 			US_SST(us_s_hand);
60617767Sralph 			systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]);
60717767Sralph #ifdef GNXSEQ
60813639Ssam 			ulkseq();
60917767Sralph #endif GNXSEQ
61013639Ssam 			goto next;
61113639Ssam 		}
61213639Ssam 		if (strcmp(&msg[1], "OK") != SAME)  {
61323590Sbloom 			logent(&msg[1], "FAILED HANDSHAKE");
61417767Sralph 			US_SST(us_s_hand);
61517767Sralph #ifdef GNXSEQ
61613639Ssam 			ulkseq();
61717767Sralph #endif GNXSEQ
61817767Sralph 			systat(Rmtname, SS_INPROGRESS,
61917767Sralph 				strcmp(&msg[1], "CB") == SAME?
62023590Sbloom 				"AWAITING CALLBACK": "FAILED HANDSHAKE");
62113639Ssam 			goto next;
62213639Ssam 		}
62317767Sralph #ifdef GNXSEQ
62413639Ssam 		cmtseq();
62517767Sralph #endif GNXSEQ
62613639Ssam 	}
62717767Sralph 	DEBUG(1, "Rmtname %s, ", Rmtname);
62813639Ssam 	DEBUG(1, "Role %s,  ", Role ? "MASTER" : "SLAVE");
62913639Ssam 	DEBUG(1, "Ifn - %d, ", Ifn);
63013639Ssam 	DEBUG(1, "Loginuser - %s\n", Loginuser);
63113639Ssam 
63225703Sbloom 	ttyn = ttyname(Ifn);
63325703Sbloom 
63433559Srick 	alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
63518616Sralph 	if (ret=setjmp(Sjbuf))
63613639Ssam 		goto Failure;
63713639Ssam 	ret = startup(Role);
63813639Ssam 	alarm(0);
63913639Ssam 	if (ret != SUCCESS) {
64017767Sralph 		logent("startup", _FAILED);
64113639Ssam Failure:
64217767Sralph 		US_SST(us_s_start);
64318616Sralph 		systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" :
64418616Sralph 			"STARTUP FAILED");
64513639Ssam 		goto next;
64617767Sralph 	} else {
64733559Srick 		char smsg[BUFSIZ], gmsg[10], pmsg[20], bpsmsg[20];
64833559Srick 		extern char UsingProtocol;
64933559Srick 		extern int linebaudrate;
65033559Srick 		if (ttyn != NULL)
65133559Srick 			sprintf(bpsmsg, " %s %d bps", &ttyn[5], linebaudrate);
65233559Srick 		else
65333559Srick 			bpsmsg[0] = '\0';
65433559Srick 		if (UsingProtocol != 'g')
65533559Srick 			sprintf(pmsg, " %c protocol", UsingProtocol);
65633559Srick 		else
65733559Srick 			pmsg[0] = '\0';
65833559Srick 		if (MaxGrade != '\177')
65933559Srick 			sprintf(gmsg, " grade %c", MaxGrade);
66033559Srick 		else
66133559Srick 			gmsg[0] = '\0';
66233559Srick 		sprintf(smsg, "startup%s%s%s", bpsmsg, pmsg, gmsg);
66333559Srick 		logent(smsg, "OK");
66417767Sralph 		US_SST(us_s_gress);
66533559Srick 		StartTime = Now.time;
66613639Ssam 		systat(Rmtname, SS_INPROGRESS, "TALKING");
66713639Ssam 		ret = cntrl(Role, wkpre);
66813639Ssam 		DEBUG(1, "cntrl - %d\n", ret);
66913639Ssam 		signal(SIGINT, SIG_IGN);
67013639Ssam 		signal(SIGHUP, SIG_IGN);
67113639Ssam 		signal(SIGALRM, timeout);
67233559Srick 		sprintf(smsg, "conversation complete %ld sent %ld received",
67333559Srick 			Bytes_Sent, Bytes_Received);
67417767Sralph 		if (ret == SUCCESS) {
67533559Srick 			logent(smsg, "OK");
67617767Sralph 			US_SST(us_s_ok);
67713639Ssam 			rmstat(Rmtname);
67813639Ssam 
67917767Sralph 		} else {
68033559Srick 			logent(smsg, _FAILED);
68117767Sralph 			US_SST(us_s_cf);
68217767Sralph 			systat(Rmtname, SS_FAIL, "CONVERSATION FAILED");
68313639Ssam 		}
68433559Srick 		alarm(IsTcpIp?MAXMSGTIME*4:MAXMSGTIME);
68513639Ssam 		DEBUG(4, "send OO %d,", ret);
68613639Ssam 		if (!setjmp(Sjbuf)) {
68713639Ssam 			for (;;) {
68813639Ssam 				omsg('O', "OOOOO", Ofn);
68913639Ssam 				ret = imsg(msg, Ifn);
69013639Ssam 				if (ret != 0)
69113639Ssam 					break;
69213639Ssam 				if (msg[0] == 'O')
69313639Ssam 					break;
69413639Ssam 			}
69513639Ssam 		}
69613639Ssam 		alarm(0);
69717767Sralph 		clsacu();
69817767Sralph 		rmlock(CNULL);
69933559Srick 
70013639Ssam 	}
70113639Ssam next:
70213639Ssam 	if (!onesys) {
70313639Ssam 		goto loop;
70413639Ssam 	}
70513639Ssam 	cleanup(0);
70613639Ssam }
70713639Ssam 
70817767Sralph #ifndef	USG
70913639Ssam struct sgttyb Hupvec;
71013639Ssam #endif
71113639Ssam 
71225703Sbloom /*
71325703Sbloom  *	cleanup and exit with "code" status
71413639Ssam  */
71513639Ssam cleanup(code)
71613639Ssam register int code;
71713639Ssam {
71813639Ssam 	signal(SIGINT, SIG_IGN);
71913639Ssam 	signal(SIGHUP, SIG_IGN);
72013639Ssam 	rmlock(CNULL);
72125703Sbloom 	sleep(5);			/* Wait for any pending output	  */
72213639Ssam 	clsacu();
72313639Ssam 	logcls();
72413639Ssam 	if (Role == SLAVE) {
72517767Sralph 		if (!IsTcpIp) {
72617767Sralph #ifdef USG
72713639Ssam 			Savettyb.c_cflag |= HUPCL;
72823590Sbloom 			(void) ioctl(0, TCSETA, &Savettyb);
72917767Sralph #else !USG
73023590Sbloom 			(void) ioctl(0, TIOCHPCL, STBNULL);
73118616Sralph #ifdef TIOCSDTR
73223590Sbloom 			(void) ioctl(0, TIOCCDTR, STBNULL);
73318616Sralph 			sleep(2);
73423590Sbloom 			(void) ioctl(0, TIOCSDTR, STBNULL);
73518616Sralph #else !TIOCSDTR
73623590Sbloom 			(void) ioctl(0, TIOCGETP, &Hupvec);
73713639Ssam 			Hupvec.sg_ispeed = B0;
73813639Ssam 			Hupvec.sg_ospeed = B0;
73923590Sbloom 			(void) ioctl(0, TIOCSETP, &Hupvec);
74025703Sbloom #endif !TIOCSDTR
74113639Ssam 			sleep(2);
74223590Sbloom 			(void) ioctl(0, TIOCSETP, &Savettyb);
74317767Sralph 			/* make *sure* exclusive access is off */
74423590Sbloom 			(void) ioctl(0, TIOCNXCL, STBNULL);
74517767Sralph #endif !USG
74613639Ssam 		}
74713639Ssam 		if (ttyn != NULL)
74813639Ssam 			chmod(ttyn, 0600);
74913639Ssam 	}
75013639Ssam 	if (Ofn != -1) {
75113639Ssam 		if (Role == MASTER)
75213639Ssam 			write(Ofn, EOTMSG, strlen(EOTMSG));
75313639Ssam 		close(Ifn);
75413639Ssam 		close(Ofn);
75513639Ssam 	}
75618616Sralph #ifdef DIALINOUT
75718616Sralph 	/* reenable logins on dialout */
75818616Sralph 	reenable();
75918616Sralph #endif DIALINOUT
76013639Ssam 	if (code == 0)
76113639Ssam 		xuuxqt();
76217767Sralph 	else
76317767Sralph 		DEBUG(1, "exit code %d\n", code);
76425703Sbloom 	setdebug (DBG_CLEAN);
76533559Srick 	do_connect_accounting();
76613639Ssam 	exit(code);
76713639Ssam }
76813639Ssam 
76933559Srick do_connect_accounting()
77033559Srick {
771*33945Srick #ifdef DO_CONNECT_ACCOUNTING
77233559Srick 	register FILE *fp;
77333559Srick 	struct tm *localtime();
77433559Srick 	register struct tm *tm;
77533559Srick 	int flags;
77633559Srick 
77733559Srick 	if (StartTime == 0)
77833559Srick 		return;
77933559Srick 
780*33945Srick 	fp = fopen(DO_CONNECT_ACCOUNTING, "a");
781*33945Srick 	if (fp == NULL) {
782*33945Srick 		syslog(LOG_ALERT, "fopen(%s) failed: %m",DO_CONNECT_ACCOUNTING);
783*33945Srick 		cleanup(FAIL);
784*33945Srick 	}
78533559Srick 
78633559Srick 	tm = localtime(&StartTime);
78733559Srick #ifdef F_SETFL
78833559Srick 	flags = fcntl(fileno(fp), F_GETFL, 0);
78933559Srick 	fcntl(fileno(fp), F_SETFL, flags|O_APPEND);
79033559Srick #endif
79133559Srick #ifdef USG
79233559Srick 	fprintf(fp,"%s %d %d%.2d%.2d %.2d%.2d %d %ld %s %ld %ld\n",
79333559Srick #else /* V7 */
79433559Srick 	fprintf(fp,"%s %d %d%02d%02d %02d%02d %d %ld %s %ld %ld\n",
79533559Srick #endif /* V7 */
79633559Srick 		Rmtname, InitialRole, tm->tm_year, tm->tm_mon + 1,
79733559Srick 		tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_wday,
79833559Srick 		(Now.time - StartTime + 59) / 60,
79933559Srick 		ttyn == NULL ? "ttyp0" : &ttyn[5],
80033559Srick 			Bytes_Sent, Bytes_Received);
80133559Srick 	fclose(fp);
80233559Srick #endif /* DO_CONNECT_ACCOUNTING */
80333559Srick }
80433559Srick 
80525703Sbloom /*
80625703Sbloom  *	on interrupt - remove locks and exit
80713639Ssam  */
80813639Ssam 
80913639Ssam onintr(inter)
81013639Ssam register int inter;
81113639Ssam {
81233559Srick 	char str[BUFSIZ];
81313639Ssam 	signal(inter, SIG_IGN);
81413639Ssam 	sprintf(str, "SIGNAL %d", inter);
81513639Ssam 	logent(str, "CAUGHT");
81617767Sralph 	US_SST(us_s_intr);
81723590Sbloom 	if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME))
81817767Sralph 		systat(Rmtname, SS_FAIL, str);
81933559Srick 	sprintf(str, "conversation complete %ld sent %ld received",
82033559Srick 		Bytes_Sent, Bytes_Received);
82133559Srick 	logent(str, _FAILED);
82217767Sralph 	if (inter == SIGPIPE && !onesys)
82317767Sralph 		longjmp(Pipebuf, 1);
82413639Ssam 	cleanup(inter);
82513639Ssam }
82613639Ssam 
82713639Ssam /*
82813639Ssam  * Catch a special signal
82913639Ssam  * (SIGFPE, ugh), and toggle debugging between 0 and 30.
83013639Ssam  * Handy for looking in on long running uucicos.
83113639Ssam  */
83225703Sbloom dbg_signal()
83313639Ssam {
83425703Sbloom 	Debug = (Debug == 0) ? 30 : 0;
83525703Sbloom 	setdebug(DBG_PERM);
83625703Sbloom 	if (Debug > 0)
83725703Sbloom 		logent("Signal Enabled", "DEBUG");
83825703Sbloom }
83917767Sralph 
84025703Sbloom 
84125703Sbloom /*
84225703Sbloom  * Check debugging requests, and open RMTDEBUG audit file if necessary. If an
84325703Sbloom  * audit file is needed, the parm argument indicates how to create the file:
84425703Sbloom  *
84525703Sbloom  *	DBG_TEMP  - Open a temporary file, with filename = RMTDEBUG/pid.
84625703Sbloom  *	DBG_PERM  - Open a permanent audit file, filename = RMTDEBUG/Rmtname.
84725703Sbloom  *		    If a temp file already exists, it is mv'ed to be permanent.
84825703Sbloom  *	DBG_CLEAN - Cleanup; unlink temp files.
84925703Sbloom  *
85025703Sbloom  * Restrictions - this code can only cope with one open debug file at a time.
85125703Sbloom  * Each call creates a new file; if an old one of the same name exists it will
85225703Sbloom  * be overwritten.
85325703Sbloom  */
85425703Sbloom setdebug(parm)
85525703Sbloom int parm;
85625703Sbloom {
85725703Sbloom 	char buf[BUFSIZ];		/* Buffer for building filenames     */
85825703Sbloom 	static char *temp = NULL;	/* Ptr to temporary file name	     */
85925703Sbloom 	static int auditopen = 0;	/* Set to 1 when we open a file	     */
86025703Sbloom 	struct stat stbuf;		/* File status buffer		     */
86125703Sbloom 
86225703Sbloom 	/*
86325703Sbloom 	 * If movement or cleanup of a temp file is indicated, we do it no
86425703Sbloom 	 * matter what.
86525703Sbloom 	 */
86625703Sbloom 	if (temp != CNULL && parm == DBG_PERM) {
86725703Sbloom 		sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
86825703Sbloom 		unlink(buf);
86925703Sbloom 		if (link(temp, buf) != 0) {
87023590Sbloom 			Debug = 0;
871*33945Srick 			syslog(LOG_ERR, "RMTDEBUG link(%s,%s) failed: %m",
872*33945Srick 				temp, buf);
873*33945Srick 			cleanup(FAIL);
87425703Sbloom 		}
87525703Sbloom 		parm = DBG_CLEAN;
87623590Sbloom 	}
87725703Sbloom 	if (parm == DBG_CLEAN) {
87825703Sbloom 		if (temp != CNULL) {
87925703Sbloom 			unlink(temp);
88025703Sbloom 			free(temp);
88125703Sbloom 			temp = CNULL;
88225703Sbloom 		}
88325703Sbloom 		return;
88425703Sbloom 	}
88525703Sbloom 
88625703Sbloom 	if (Debug == 0)
88725703Sbloom 		return;		/* Gotta be in debug to come here.   */
88825703Sbloom 
88925703Sbloom 	/*
89025703Sbloom 	 * If we haven't opened a file already, we can just return if it's
89125703Sbloom 	 * alright to use the stderr we came in with. We can if:
89225703Sbloom 	 *
89325703Sbloom 	 *	Role == MASTER, and Stderr is a regular file, a TTY or a pipe.
89425703Sbloom 	 *
89525703Sbloom 	 * Caution: Detecting when stderr is a pipe is tricky, because the 4.2
89625703Sbloom 	 * man page for fstat(2) disagrees with reality, and System V leaves it
89725703Sbloom 	 * undefined, which means different implementations act differently.
89825703Sbloom 	 */
89925703Sbloom 	if (!auditopen && Role == MASTER) {
90025703Sbloom 		if (isatty(fileno(stderr)))
90125703Sbloom 			return;
90225703Sbloom 		else if (fstat(fileno(stderr), &stbuf) == 0) {
90325703Sbloom #ifdef USG
90425703Sbloom 			/* Is Regular File or Fifo   */
90525703Sbloom 			if ((stbuf.st_mode & 0060000) == 0)
90625703Sbloom 				return;
90725703Sbloom #else !USG
90817767Sralph #ifdef BSD4_2
90925703Sbloom 					/* Is Regular File */
91025703Sbloom 			if ((stbuf.st_mode & S_IFMT) == S_IFREG ||
91125703Sbloom 			    stbuf.st_mode == 0)		/* Is a pipe */
91225703Sbloom 				return;
91325703Sbloom #else !BSD4_2
91425703Sbloom 					 /* Is Regular File or Pipe  */
91525703Sbloom 			if ((stbuf.st_mode & S_IFMT) == S_IFREG)
91625703Sbloom 				return;
91725703Sbloom #endif BSD4_2
91825703Sbloom #endif USG
91925703Sbloom 		}
92017767Sralph 	}
92113639Ssam 
92225703Sbloom 	/*
92325703Sbloom 	 * We need RMTDEBUG directory to do auditing. If the file doesn't exist,
92425703Sbloom 	 * then we forget about debugging; if it exists but has improper owner-
92525703Sbloom 	 * ship or modes, we gripe about it in ERRLOG.
92625703Sbloom 	 */
92725703Sbloom 	if (stat(RMTDEBUG, &stbuf) != SUCCESS) {
92825703Sbloom 		Debug = 0;
92925703Sbloom 		return;
93025703Sbloom 	}
93125703Sbloom 	if ((geteuid() != stbuf.st_uid) ||	  	/* We must own it    */
93225703Sbloom 	    ((stbuf.st_mode & 0170700) != 040700)) {	/* Directory, rwx    */
93325703Sbloom 		Debug = 0;
934*33945Srick 		syslog(LOG_ERR, "%s: invalid directory mode: %o", RMTDEBUG,
935*33945Srick 			stbuf.st_mode);
93625703Sbloom 		return;
93725703Sbloom 	}
93813639Ssam 
93925703Sbloom 	if (parm == DBG_TEMP) {
94025703Sbloom 		sprintf(buf, "%s/%d", RMTDEBUG, getpid());
94125703Sbloom 		temp = malloc(strlen (buf) + 1);
94225703Sbloom 		if (temp == CNULL) {
94325703Sbloom 			Debug = 0;
944*33945Srick 			syslog(LOG_ERR, "RMTDEBUG malloc failed: %m");
945*33945Srick 			cleanup(FAIL);
94625703Sbloom 		}
94725703Sbloom 		strcpy(temp, buf);
94825703Sbloom 	} else
94925703Sbloom 		sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
95013639Ssam 
95125703Sbloom 	unlink(buf);
95225703Sbloom 	if (freopen(buf, "w", stderr) != stderr) {
95325703Sbloom 		Debug = 0;
954*33945Srick 		syslog(LOG_ERR, "RMTDEBUG freopen(%s) failed: %m", buf);
955*33945Srick 		cleanup(FAIL);
95625703Sbloom 	}
95725703Sbloom 	setbuf(stderr, CNULL);
95825703Sbloom 	auditopen = 1;
95913639Ssam }
96013639Ssam 
96123590Sbloom /*
96225703Sbloom  *	catch SIGALRM routine
96313639Ssam  */
96413639Ssam timeout()
96513639Ssam {
96623590Sbloom 	extern int HaveSentHup;
96723590Sbloom 	if (!HaveSentHup) {
96823590Sbloom 		logent(Rmtname, "TIMEOUT");
96923590Sbloom 		if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) {
97023590Sbloom 			US_SST(us_s_tmot);
97123590Sbloom 			systat(Rmtname, SS_FAIL, "TIMEOUT");
97223590Sbloom 		}
97317767Sralph 	}
97413639Ssam 	longjmp(Sjbuf, 1);
97513639Ssam }
97613639Ssam 
97713639Ssam static char *
97813639Ssam pskip(p)
97913639Ssam register char *p;
98013639Ssam {
98117767Sralph 	while(*p && *p != ' ')
98213639Ssam 		++p;
98323590Sbloom 	while(*p && *p == ' ')
98417767Sralph 		*p++ = 0;
98517767Sralph 	return p;
98613639Ssam }
987