xref: /csrg-svn/usr.bin/uucp/uucico/cico.c (revision 18616)
1 #ifndef lint
2 static char sccsid[] = "@(#)cico.c	5.6 (Berkeley) 04/10/85";
3 #endif
4 
5 #include "uucp.h"
6 #include <signal.h>
7 #include <setjmp.h>
8 #ifdef	USG
9 #include <termio.h>
10 #endif
11 #ifndef	USG
12 #include <sgtty.h>
13 #endif
14 #ifdef BSDTCP
15 #include <netdb.h>
16 #include <netinet/in.h>
17 #include <sys/socket.h>
18 #endif BSDTCP
19 #include <sys/stat.h>
20 #include "uust.h"
21 #include "uusub.h"
22 
23 jmp_buf Sjbuf;
24 jmp_buf Pipebuf;
25 
26 /*  call fail text  */
27 char *Stattext[] = {
28 	"",
29 	"BAD SYSTEM",
30 	"WRONG TIME TO CALL",
31 	"SYSTEM LOCKED",
32 	"NO DEVICE",
33 	"DIAL FAILED",
34 	"LOGIN FAILED",
35 	"BAD SEQUENCE"
36 };
37 
38 /*  call fail codes  */
39 int Stattype[] = {
40 	0,
41 	0,
42 	SS_WRONGTIME,
43 	0,
44 	SS_NODEVICE,
45 	SS_FAIL,
46 	SS_FAIL,
47 	SS_BADSEQ
48 };
49 
50 
51 int Errorrate = 0;
52 int ReverseRole = 0;
53 int StdErrIsTty = 0;
54 int Role = SLAVE;
55 int onesys = 0;
56 int turntime = 30 * 60;	/* 30 minutes expressed in seconds */
57 extern int LocalOnly;
58 extern char MaxGrade, DefMaxGrade;
59 extern char Myfullname[];
60 
61 #ifdef	USG
62 struct termio Savettyb;
63 #endif
64 #ifndef	USG
65 struct sgttyb Savettyb;
66 #endif
67 
68 /*******
69  *	cico - this program is used  to place a call to a
70  *	remote machine, login, and copy files between the two machines.
71  */
72 
73 main(argc, argv)
74 register char *argv[];
75 {
76 	register int ret;
77 	int seq;
78 	char wkpre[NAMESIZE], file[NAMESIZE];
79 	char msg[MAXFULLNAME], *q, **alias;
80 	register char *p;
81 	extern onintr(), timeout(), setdebug();
82 	extern char *pskip();
83 	char rflags[30];
84 	char *ttyn;
85 #if defined(VMS) && defined(BSDTCP)
86 	u_long Hostnumber = 0;
87 #endif VMS && BSDTCP
88 
89 	strcpy(Progname, "uucico");
90 	uucpname(Myname);
91 
92 	signal(SIGINT, onintr);
93 	signal(SIGHUP, onintr);
94 	signal(SIGQUIT, onintr);
95 	signal(SIGTERM, onintr);
96 	signal(SIGPIPE, onintr);	/* 4.1a tcp-ip stupidity */
97 	signal(SIGFPE, setdebug);
98 	ret = guinfo(getuid(), User, msg);
99 	strcpy(Loginuser, User);
100 	ASSERT(ret == 0, "BAD UID", CNULL, ret);
101 
102 #ifdef BSD4_2
103 	setlinebuf(stderr);
104 #endif
105 	rflags[0] = '\0';
106 	umask(WFMASK);
107 	strcpy(Rmtname, Myname);
108 	Ifn = Ofn = -1;
109 	while(argc>1 && argv[1][0] == '-'){
110 		switch(argv[1][1]){
111 		case 'd':
112 			Spool = &argv[1][2];
113 			break;
114 		case 'g':
115 		case 'p':
116 			MaxGrade = DefMaxGrade = argv[1][2];
117 			break;
118 		case 'r':
119 			Role = atoi(&argv[1][2]);
120 			break;
121 		case 'R':
122 			ReverseRole++;
123 			Role = MASTER;
124 			break;
125 		case 's':
126 			sprintf(Rmtname, "%.7s", &argv[1][2]);
127 			if (Rmtname[0] != '\0')
128 				onesys = 1;
129 			break;
130 		case 'x':
131 			chkdebug();
132 			Debug = atoi(&argv[1][2]);
133 			if (Debug <= 0)
134 				Debug = 1;
135 			strcat(rflags, argv[1]);
136 			logent("ENABLED", "DEBUG");
137 			break;
138 		case 't':
139 			turntime = atoi(&argv[1][2])*60;/* minutes to seconds */
140 			break;
141 		case 'L':	/* local calls only */
142 			LocalOnly++;
143 			break;
144 #if defined(VMS) && defined(BSDTCP)
145 		case 'h':
146 			Hostnumber = inet_addr(&argv[1][2]);
147 			break;
148 #endif VMS && BSDTCP
149 		default:
150 			printf("unknown flag %s (ignored)\n", argv[1]);
151 			break;
152 		}
153 		--argc;  argv++;
154 	}
155 
156 	while (argc > 1) {
157 		printf("unknown argument %s (ignored)\n", argv[1]);
158 		--argc; argv++;
159 	}
160 
161 	/* Try to run as uucp -- rti!trt */
162 	setgid(getegid());
163 	setuid(geteuid());
164 #ifdef	TIOCNOTTY
165 	/*
166 	 * detach uucico from controlling terminal
167 	 * to defend against rlogind sending us a SIGKILL (!!!)
168 	 */
169 	if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) {
170 		ioctl(ret, TIOCNOTTY, STBNULL);
171 		close(ret);
172 	}
173 #endif TIOCNOTTY
174 #ifdef BSD4_2
175 	if (getpgrp(0) == 0) { /*We have no controlling terminal */
176 		setpgrp(0, getpid());
177 	}
178 #endif BSD4_2
179 
180 	ret = subchdir(Spool);
181 	ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret);
182 	strcpy(Wrkdir, Spool);
183 
184 	if (Role == SLAVE) {
185 		/* check for /etc/nologin */
186 		ultouch();	/* sets nologinflag as a side effect */
187 		if (nologinflag) {
188 			logent(NOLOGIN, "UUCICO SHUTDOWN");
189 			if (Debug)
190 				logent("DEBUGGING", "continuing anyway");
191 			else
192 				cleanup(1);
193 		}
194 #ifdef	TCPIP
195 		/*
196 		 * Determine if we are on TCPIP
197 		 */
198 		if (isatty(0) ==  0) {
199 			IsTcpIp = 1;
200 			DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
201 		}
202 #endif TCPIP
203 		/* initial handshake */
204 		onesys = 1;
205 		if (!IsTcpIp) {
206 #ifdef	USG
207 			ret = ioctl(0, TCGETA, &Savettyb);
208 			Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
209 			Savettyb.c_oflag |= OPOST;
210 			Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
211 #else !USG
212 			ret = ioctl(0, TIOCGETP, &Savettyb);
213 			Savettyb.sg_flags |= ECHO;
214 			Savettyb.sg_flags &= ~RAW;
215 #endif !USG
216 		}
217 		Ifn = 0;
218 		Ofn = 1;
219 		fixmode(Ifn);
220 		sprintf(file,"%s/%d", RMTDEBUG, getpid());
221 #ifdef VMS
222 		/* hold the version number down */
223 		unlink(file);
224 #endif
225 		freopen(file, "w", stderr);
226 #ifdef BSD4_2
227 		setlinebuf(stderr);
228 #else  !BSD4_2
229 		setbuf(stderr, NULL);
230 #endif !BSD4_2
231 		sprintf(msg, "here=%s", Myfullname);
232 		omsg('S', msg, Ofn);
233 		signal(SIGALRM, timeout);
234 		alarm(MAXMSGTIME);
235 		if (setjmp(Sjbuf)) {
236 			/* timed out */
237 			if (!IsTcpIp) {
238 #ifdef	USG
239 				ret = ioctl(0, TCSETA, &Savettyb);
240 #endif
241 #ifndef	USG
242 				ret = ioctl(0, TIOCSETP, &Savettyb);
243 #endif
244 			}
245 			cleanup(0);
246 		}
247 		for (;;) {
248 			ret = imsg(msg, Ifn);
249 			if (ret != 0) {
250 				alarm(0);
251 				if (!IsTcpIp) {
252 #ifdef	USG
253 					ret = ioctl(0, TCSETA, &Savettyb);
254 #endif
255 #ifndef	USG
256 					ret = ioctl(0, TIOCSETP, &Savettyb);
257 #endif
258 				}
259 				cleanup(0);
260 			}
261 			if (msg[0] == 'S')
262 				break;
263 		}
264 		alarm(0);
265 		q = &msg[1];
266 		p = pskip(q);
267 		sprintf(Rmtname, "%.7s", q);
268 		sprintf(wkpre,"%s/%s", RMTDEBUG, Rmtname);
269 		unlink(wkpre);
270 		if (link(file, wkpre) == 0)
271 			unlink(file);
272 		DEBUG(4, "sys-%s\n", Rmtname);
273 #ifdef BSDTCP
274 		/* we must make sure they are really who they say they
275 		 * are. We compare the hostnumber with the number in the hosts
276 		 * table for the site they claim to be.
277 		 */
278 		if (IsTcpIp) {
279 			struct hostent *hp;
280 			char *cpnt, *inet_ntoa();
281 			int fromlen;
282 			struct sockaddr_in from;
283 
284 #ifndef	VMS
285 			fromlen = sizeof(from);
286 			if (getpeername(0, &from, &fromlen) < 0) {
287 				logent(Rmtname, "NOT A TCP CONNECTION");
288 				omsg('R', "NOT TCP", Ofn);
289 				cleanup(0);
290 			}
291 #else	VMS
292 			from.sin_addr.s_addr = Hostnumber;
293 			from.sin_family = AF_INET;
294 #endif	VMS
295 			hp = gethostbyaddr(&from.sin_addr,
296 				sizeof (struct in_addr), from.sin_family);
297 			if (hp == 0) {
298 				/* security break or just old host table? */
299 				logent(Rmtname, "UNKNOWN IP-HOST Name =");
300 				cpnt = inet_ntoa(from.sin_addr),
301 				logent(cpnt, "UNKNOWN IP-HOST Number =");
302 				sprintf(wkpre, "%s/%s isn't in my host table",
303 					Rmtname, cpnt);
304 				omsg('R' ,wkpre ,Ofn);
305 				cleanup(0);
306 			}
307 			if (Debug>99)
308 				logent(Rmtname,"Request from IP-Host name =");
309 			/* The following is to determine if the name given us by
310 			 * the Remote uucico matches any of the names(aliases)
311 			 * given its network number (remote machine) in our
312 			 * host table.
313 			 */
314 			if (strncmp(q, hp->h_name, 7) == 0) {
315 				if (Debug > 99)
316 					logent(q,"Found in host Tables");
317 			} else { /* Scan The host aliases */
318 				for(alias=hp->h_aliases; *alias!=0 &&
319 				    strncmp(q, *alias, 7) != 0; ++alias)
320 					;
321 				if (strncmp(q, *alias, 7) != 0) {
322 					logent(q, "FORGED HOSTNAME");
323 					logent(inet_ntoa(from.sin_addr), "ORIGINATED AT");
324 					omsg('R',"You're not who you claim to be");
325 					cleanup(0);
326 				}
327 #ifdef DEBUG
328 				if (Debug> 99)
329 					logent(q,"Found in host Tables");
330 #endif
331 			}
332 		}
333 #endif	BSDTCP
334 
335 #ifdef	NOSTRANGERS
336 		/* If we don't know them, we won't talk to them... */
337 		if (versys(&Rmtname)) {
338 			logent(Rmtname, "UNKNOWN HOST");
339 			omsg('R', "You are unknown to me", Ofn);
340 			cleanup(0);
341 		}
342 #endif	NOSTRANGERS
343 		if (mlock(Rmtname)) {
344 			omsg('R', "LCK", Ofn);
345 			cleanup(0);
346 		}
347 		else if (callback(Loginuser)) {
348 			signal(SIGINT, SIG_IGN);
349 			signal(SIGHUP, SIG_IGN);
350 			omsg('R', "CB", Ofn);
351 			logent("CALLBACK", "REQUIRED");
352 			/*  set up for call back  */
353 			systat(Rmtname, SS_CALLBACK, "CALLING BACK");
354 			gename(CMDPRE, Rmtname, 'C', file);
355 			close(creat(subfile(file), 0666));
356 			xuucico(Rmtname);
357 			cleanup(0);
358 		}
359 		seq = 0;
360 		while (*p == '-') {
361 			q = pskip(p);
362 			switch(*(++p)) {
363 			case 'x':
364 				Debug = atoi(++p);
365 				if (Debug <= 0)
366 					Debug = 1;
367 				break;
368 			case 'Q':
369 				seq = atoi(++p);
370 				break;
371 			case 'p':
372 				MaxGrade = DefMaxGrade = *++p;
373 				DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
374 				break;
375 			default:
376 				break;
377 			}
378 			p = q;
379 		}
380 		if (callok(Rmtname) == SS_BADSEQ) {
381 			logent("BADSEQ", "PREVIOUS");
382 			omsg('R', "BADSEQ", Ofn);
383 			cleanup(0);
384 		}
385 #ifdef GNXSEQ
386 		if ((ret = gnxseq(Rmtname)) == seq) {
387 			omsg('R', "OK", Ofn);
388 			cmtseq();
389 		} else {
390 #else !GNXSEQ
391 		if (seq == 0)
392 			omsg('R', "OK", Ofn);
393 		else {
394 #endif !GNXSEQ
395 			systat(Rmtname, Stattype[7], Stattext[7]);
396 			logent("BAD SEQ", "HANDSHAKE FAIL");
397 #ifdef GNXSEQ
398 			ulkseq();
399 #endif GNXSEQ
400 			omsg('R', "BADSEQ", Ofn);
401 			cleanup(0);
402 		}
403 		ttyn = ttyname(Ifn);
404 		if (ttyn != NULL)
405 			chmod(ttyn, 0600);
406 	} else { /* Role == MASTER */
407 		struct stat stbuf;
408 		if (isatty(fileno(stderr)) || (fstat(fileno(stderr),&stbuf) == 0
409 		    && stbuf.st_mode&S_IFREG) )
410 			StdErrIsTty =  1;
411 		setdebug(0);
412 	}
413 
414 loop:
415 	if(setjmp(Pipebuf)) {	/* come here on SIGPIPE	*/
416 		clsacu();
417 		close(Ofn);
418 		close(Ifn);
419 		Ifn = Ofn = -1;
420 		rmlock(CNULL);
421 		sleep(3);
422 	}
423 	if (!onesys) {
424 		struct stat sbuf;
425 
426 		if (!StdErrIsTty) {
427 			sprintf(file, "%s/%s", RMTDEBUG, Rmtname);
428 			if (stat(file, &sbuf) == 0 && sbuf.st_size == 0)
429 				unlink(file);
430 		}
431 		ret = gnsys(Rmtname, Spool, CMDPRE);
432 		setdebug(0);
433 		if (ret == FAIL)
434 			cleanup(100);
435 		if (ret == 0)
436 			cleanup(0);
437 	} else if (Role == MASTER && callok(Rmtname) != 0) {
438 		logent("SYSTEM STATUS", "CAN NOT CALL");
439 		cleanup(0);
440 	}
441 
442 	sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname);
443 
444 	signal(SIGINT, SIG_IGN);
445 	signal(SIGQUIT, SIG_IGN);
446 	if (Role == MASTER) {
447 		/* check for /etc/nologin */
448 		ultouch();	/* sets nologinflag as a side effect */
449 		if (nologinflag) {
450 			logent(NOLOGIN, "UUCICO SHUTDOWN");
451 			if (Debug)
452 				logent("DEBUGGING", "continuing anyway");
453 			else
454 				cleanup(1);
455 		}
456 		/*  master part */
457 		signal(SIGHUP, SIG_IGN);
458 		MaxGrade = DefMaxGrade;
459 		if (!iswrk(file, "chk", Spool, wkpre) && !onesys) {
460 			logent(Rmtname, "NO WORK");
461 			goto next;
462 		}
463 		if (Ifn != -1 && Role == MASTER) {
464 			write(Ofn, EOTMSG, strlen(EOTMSG));
465 			clsacu();
466 			close(Ofn);
467 			close(Ifn);
468 			Ifn = Ofn = -1;
469 			rmlock(CNULL);
470 			sleep(3);
471 		}
472 		sprintf(msg, "call to %s ", Rmtname);
473 		if (mlock(Rmtname) != 0) {
474 			logent(msg, "LOCKED");
475 			US_SST(us_s_lock);
476 			goto next;
477 		}
478 		Ofn = Ifn = conn(Rmtname);
479 		if (Ofn < 0) {
480 			if (Ofn != CF_TIME)
481 				logent(msg, _FAILED);
482 			/* avoid excessive 'wrong time' info */
483 			if (Stattype[-Ofn] != SS_WRONGTIME || argv[0][0] != 'U'){
484 				systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]);
485 				US_SST(-Ofn);
486 				UB_SST(-Ofn);
487 			}
488 			goto next;
489 		} else {
490 			logent(msg, "SUCCEEDED");
491 			US_SST(us_s_cok);
492 			UB_SST(ub_ok);
493 		}
494 #ifdef	TCPIP
495 		/*
496 		 * Determine if we are on TCPIP
497 		 */
498 		if (isatty(Ifn) ==  0) {
499 			IsTcpIp = 1;
500 			DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
501 		}
502 #endif
503 
504 		if (setjmp(Sjbuf))
505 			goto next;
506 		signal(SIGALRM, timeout);
507 		alarm(2 * MAXMSGTIME);
508 		for (;;) {
509 			ret = imsg(msg, Ifn);
510 			if (ret != 0) {
511 				alarm(0);
512 				logent("imsg 1", _FAILED);
513 				goto Failure;
514 			}
515 			if (msg[0] == 'S')
516 				break;
517 		}
518 		alarm(MAXMSGTIME);
519 #ifdef GNXSEQ
520 		seq = gnxseq(Rmtname);
521 #else !GNXSEQ
522 		seq = 0;
523 #endif !GNXSEQ
524 		if (MaxGrade != '\177') {
525 			char buf[10];
526 			sprintf(buf, " -p%c", MaxGrade);
527 			strcat(rflags, buf);
528 		}
529 
530 		sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags);
531 		omsg('S', msg, Ofn);
532 		for (;;) {
533 			ret = imsg(msg, Ifn);
534 			DEBUG(4, "msg-%s\n", msg);
535 			if (ret != SUCCESS) {
536 				alarm(0);
537 #ifdef GNXSEQ
538 				ulkseq();
539 #endif GNXSEQ
540 				logent("imsg 2", _FAILED);
541 				goto Failure;
542 			}
543 			if (msg[0] == 'R')
544 				break;
545 		}
546 		alarm(0);
547 		if (msg[1] == 'B') {
548 			/* bad sequence */
549 			logent("BAD SEQ", "HANDSHAKE FAIL");
550 			US_SST(us_s_hand);
551 			systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]);
552 #ifdef GNXSEQ
553 			ulkseq();
554 #endif GNXSEQ
555 			goto next;
556 		}
557 		if (strcmp(&msg[1], "OK") != SAME)  {
558 			logent(&msg[1], "HANDSHAKE FAIL");
559 			US_SST(us_s_hand);
560 #ifdef GNXSEQ
561 			ulkseq();
562 #endif GNXSEQ
563 			systat(Rmtname, SS_INPROGRESS,
564 				strcmp(&msg[1], "CB") == SAME?
565 				"AWAITING CALLBACK": "HANDSHAKE FAIL");
566 			goto next;
567 		}
568 #ifdef GNXSEQ
569 		cmtseq();
570 #endif GNXSEQ
571 	}
572 	DEBUG(1, "Rmtname %s, ", Rmtname);
573 	DEBUG(1, "Role %s,  ", Role ? "MASTER" : "SLAVE");
574 	DEBUG(1, "Ifn - %d, ", Ifn);
575 	DEBUG(1, "Loginuser - %s\n", Loginuser);
576 
577 	alarm(MAXMSGTIME);
578 	if (ret=setjmp(Sjbuf))
579 		goto Failure;
580 	ret = startup(Role);
581 	alarm(0);
582 	if (ret != SUCCESS) {
583 		logent("startup", _FAILED);
584 Failure:
585 		US_SST(us_s_start);
586 		systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" :
587 			"STARTUP FAILED");
588 		goto next;
589 	} else {
590 		logent("startup", "OK");
591 		US_SST(us_s_gress);
592 		systat(Rmtname, SS_INPROGRESS, "TALKING");
593 		ret = cntrl(Role, wkpre);
594 		DEBUG(1, "cntrl - %d\n", ret);
595 		signal(SIGINT, SIG_IGN);
596 		signal(SIGHUP, SIG_IGN);
597 		signal(SIGALRM, timeout);
598 		if (ret == SUCCESS) {
599 			logent("conversation complete", "OK");
600 			US_SST(us_s_ok);
601 			rmstat(Rmtname);
602 
603 		} else {
604 			logent("conversation complete", _FAILED);
605 			US_SST(us_s_cf);
606 			systat(Rmtname, SS_FAIL, "CONVERSATION FAILED");
607 		}
608 		alarm(MAXMSGTIME);
609 		DEBUG(4, "send OO %d,", ret);
610 		if (!setjmp(Sjbuf)) {
611 			for (;;) {
612 				omsg('O', "OOOOO", Ofn);
613 				ret = imsg(msg, Ifn);
614 				if (ret != 0)
615 					break;
616 				if (msg[0] == 'O')
617 					break;
618 			}
619 		}
620 		alarm(0);
621 		clsacu();
622 		rmlock(CNULL);
623 	}
624 next:
625 	if (!onesys) {
626 		goto loop;
627 	}
628 	cleanup(0);
629 }
630 
631 #ifndef	USG
632 struct sgttyb Hupvec;
633 #endif
634 
635 /***
636  *	cleanup(code)	cleanup and exit with "code" status
637  *	int code;
638  */
639 
640 cleanup(code)
641 register int code;
642 {
643 	register int ret;
644 	register char *ttyn;
645 	char bfr[BUFSIZ];
646 	struct stat sbuf;
647 
648 	signal(SIGINT, SIG_IGN);
649 	signal(SIGHUP, SIG_IGN);
650 	rmlock(CNULL);
651 	clsacu();
652 	logcls();
653 	if (Role == SLAVE) {
654 		if (!IsTcpIp) {
655 #ifdef USG
656 			Savettyb.c_cflag |= HUPCL;
657 			ret = ioctl(0, TCSETA, &Savettyb);
658 #else !USG
659 			ret = ioctl(0, TIOCHPCL, STBNULL);
660 #ifdef TIOCSDTR
661 			ret = ioctl(0, TIOCCDTR, STBNULL);
662 			sleep(2);
663 			ret = ioctl(0, TIOCSDTR, STBNULL);
664 #else !TIOCSDTR
665 			ret = ioctl(0, TIOCGETP, &Hupvec);
666 #endif !TIOCSDTR
667 			Hupvec.sg_ispeed = B0;
668 			Hupvec.sg_ospeed = B0;
669 			ret = ioctl(0, TIOCSETP, &Hupvec);
670 			sleep(2);
671 			ret = ioctl(0, TIOCSETP, &Savettyb);
672 			/* make *sure* exclusive access is off */
673 			ret = ioctl(0, TIOCNXCL, STBNULL);
674 #endif !USG
675 			DEBUG(4, "ret ioctl - %d\n", ret);
676 		}
677 		ttyn = ttyname(Ifn);
678 		if (ttyn != NULL)
679 			chmod(ttyn, 0600);
680 	}
681 	if (Ofn != -1) {
682 		if (Role == MASTER)
683 			write(Ofn, EOTMSG, strlen(EOTMSG));
684 		close(Ifn);
685 		close(Ofn);
686 	}
687 #ifdef DIALINOUT
688 	/* reenable logins on dialout */
689 	reenable();
690 #endif DIALINOUT
691 	if (code == 0)
692 		xuuxqt();
693 	else
694 		DEBUG(1, "exit code %d\n", code);
695 	sprintf(bfr, "%s/%s", RMTDEBUG, Rmtname);
696 	if (stat(bfr, &sbuf) == 0 && sbuf.st_size == 0)
697 		unlink(bfr);
698 	sprintf(bfr, "%s/%d", RMTDEBUG, getpid());
699 	unlink(bfr);
700 	exit(code);
701 }
702 
703 /***
704  *	onintr(inter)	interrupt - remove locks and exit
705  */
706 
707 onintr(inter)
708 register int inter;
709 {
710 	char str[30];
711 	signal(inter, SIG_IGN);
712 	sprintf(str, "SIGNAL %d", inter);
713 	logent(str, "CAUGHT");
714 	US_SST(us_s_intr);
715 	if (*Rmtname && strncmp(Rmtname, Myname, 7))
716 		systat(Rmtname, SS_FAIL, str);
717 	if (inter == SIGPIPE && !onesys)
718 		longjmp(Pipebuf, 1);
719 	cleanup(inter);
720 }
721 
722 /*
723  * Catch a special signal
724  * (SIGFPE, ugh), and toggle debugging between 0 and 30.
725  * Handy for looking in on long running uucicos.
726  */
727 setdebug(code)
728 int code;
729 {
730 	char buf[BUFSIZ];
731 
732 	if (!StdErrIsTty) {
733 		sprintf(buf,"%s/%s", RMTDEBUG, Rmtname);
734 		unlink(buf);
735 		freopen(buf, "w", stderr);
736 #ifdef BSD4_2
737 		setlinebuf(stderr);
738 #else  !BSD4_2
739 		setbuf(stderr, NULL);
740 #endif !BSD4_2
741 	}
742 	if (code) {
743 		if (Debug == 0)
744 			Debug = 30;
745 		else
746 			Debug = 0;
747 	}
748 }
749 
750 
751 /***
752  *	fixmode(tty)	fix kill/echo/raw on line
753  *
754  *	return codes:  none
755  */
756 
757 fixmode(tty)
758 register int tty;
759 {
760 #ifdef	USG
761 	struct termio ttbuf;
762 #endif
763 #ifndef	USG
764 	struct sgttyb ttbuf;
765 #endif
766 	register int ret;
767 
768 	if (IsTcpIp)
769 		return;
770 #ifdef	USG
771 	ret = ioctl(tty, TCGETA, &ttbuf);
772 	ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0;
773 	ttbuf.c_cflag &= (CBAUD);
774 	ttbuf.c_cflag |= (CS8|CREAD);
775 	ttbuf.c_cc[VMIN] = 6;
776 	ttbuf.c_cc[VTIME] = 1;
777 	ret = ioctl(tty, TCSETA, &ttbuf);
778 #endif
779 #ifndef	USG
780 	ioctl(tty, TIOCGETP, &ttbuf);
781 	ttbuf.sg_flags = (ANYP | RAW);
782 	ret = ioctl(tty, TIOCSETP, &ttbuf);
783 #endif
784 /*	ASSERT(ret >= 0, "STTY FAILED", CNULL, ret); */
785 #ifndef	USG
786 	ret = ioctl(tty, TIOCEXCL, STBNULL);
787 #endif
788 }
789 
790 
791 /***
792  *	timeout()	catch SIGALRM routine
793  */
794 
795 timeout()
796 {
797 	logent(Rmtname, "TIMEOUT");
798 	if (*Rmtname && strncmp(Rmtname, Myname, 7)) {
799 		US_SST(us_s_tmot);
800 		systat(Rmtname, SS_FAIL, "TIMEOUT");
801 	}
802 	longjmp(Sjbuf, 1);
803 }
804 
805 static char *
806 pskip(p)
807 register char *p;
808 {
809 	while(*p && *p != ' ')
810 		++p;
811 	if(*p)
812 		*p++ = 0;
813 	return p;
814 }
815