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