|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)cico.c 5.3 (Berkeley) 10/3/83";
3: #endif
4:
5: #include "uucp.h"
6: #include <signal.h>
7: #include <setjmp.h>
8: #include <sys/types.h>
9: #ifdef SYSIII
10: #include <termio.h>
11: #endif
12: #ifndef SYSIII
13: #include <sgtty.h>
14: #endif
15:
16:
17: #ifdef UNET
18: #include <UNET/unetio.h>
19: #include <UNET/tcp.h>
20: static struct uiocstate ust;
21: #endif
22:
23: jmp_buf Sjbuf;
24: /* call fail text */
25: char *Stattext[] = {
26: "",
27: "BAD SYSTEM",
28: "WRONG TIME",
29: "SYSTEM LOCKED",
30: "NO DEVICE",
31: "DIAL FAILED",
32: "LOGIN FAILED",
33: "BAD SEQUENCE"
34: };
35:
36: int Role = 0;
37: /* call fail codes */
38: int Stattype[] = {0, 0, 0, 0,
39: SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ
40: };
41:
42:
43: int Errorrate = 0;
44: #ifdef SYSIII
45: struct termio Savettyb;
46: #endif
47: #ifndef SYSIII
48: struct sgttyb Savettyb;
49: #endif
50:
51: /*******
52: * cico - this program is used to place a call to a
53: * remote machine, login, and copy files between the two machines.
54: */
55:
56: main(argc, argv)
57: register char *argv[];
58: {
59: register int ret;
60: int seq;
61: int onesys = 0;
62: char wkpre[NAMESIZE], file[NAMESIZE];
63: char msg[BUFSIZ], *q;
64: register char *p;
65: extern onintr(), timeout(), setdebug();
66: extern intrEXIT();
67: extern char *pskip();
68: char rflags[30];
69: char *ttyn;
70: int orig_uid = getuid();
71:
72: strcpy(Progname, "uucico");
73: uucpname(Myname);
74:
75: /* Try to run as uucp -- rti!trt */
76: setgid(getegid());
77: setuid(geteuid());
78:
79: signal(SIGILL, intrEXIT);
80: signal(SIGTRAP, intrEXIT);
81: signal(SIGIOT, intrEXIT);
82: signal(SIGEMT, intrEXIT);
83: signal(SIGFPE, intrEXIT);
84: signal(SIGBUS, intrEXIT);
85: signal(SIGSEGV, intrEXIT);
86: signal(SIGSYS, intrEXIT);
87: signal(SIGINT, onintr);
88: signal(SIGHUP, onintr);
89: signal(SIGQUIT, onintr);
90: signal(SIGTERM, onintr);
91: signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */
92: signal(SIGFPE, setdebug);
93: ret = guinfo(getuid(), User, msg);
94: strcpy(Loginuser, User);
95: ASSERT(ret == 0, "BAD UID ", "", ret);
96:
97: rflags[0] = '\0';
98: umask(WFMASK);
99: strcpy(Rmtname, Myname);
100: Ifn = Ofn = -1;
101: while(argc>1 && argv[1][0] == '-'){
102: switch(argv[1][1]){
103: case 'd':
104: Spool = &argv[1][2];
105: break;
106: #ifdef PROTODEBUG
107: case 'E':
108: Errorrate = atoi(&argv[1][2]);
109: if (Errorrate <= 0)
110: Errorrate = 100;
111: break;
112: case 'g':
113: Pkdrvon = 1;
114: break;
115: case 'G':
116: Pkdrvon = 1;
117: strcat(rflags, " -g ");
118: break;
119: #endif
120: case 'r':
121: Role = atoi(&argv[1][2]);
122: break;
123: case 's':
124: sprintf(Rmtname, "%.7s", &argv[1][2]);
125: if (Rmtname[0] != '\0')
126: onesys = 1;
127: break;
128: case 'x':
129: chkdebug(orig_uid);
130: Debug = atoi(&argv[1][2]);
131: if (Debug <= 0)
132: Debug = 1;
133: strcat(rflags, argv[1]);
134: logent("ENABLED", "DEBUG");
135: break;
136: default:
137: printf("unknown flag %s\n", argv[1]);
138: break;
139: }
140: --argc; argv++;
141: }
142:
143: subchdir(Spool);
144: strcpy(Wrkdir, Spool);
145:
146: #ifdef UNET
147: /*
148: * Determine if we are on UNET
149: */
150: ret = ioctl(0, UIOCSTATE, &ust);
151: if (ret == 0) {
152: Unet = 1;
153: DEBUG(4, "UNET connection -- ioctl-s disabled\n", "");
154: }
155: #endif
156: if (Role == SLAVE) {
157: /* initial handshake */
158: onesys = 1;
159: if (!Unet) {
160: #ifdef SYSIII
161: ret = ioctl(0, TCGETA, &Savettyb);
162: Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
163: Savettyb.c_oflag |= OPOST;
164: Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
165: #endif
166: #ifndef SYSIII
167: ret = ioctl(0, TIOCGETP, &Savettyb);
168: Savettyb.sg_flags |= ECHO;
169: Savettyb.sg_flags &= ~RAW;
170: #endif
171: }
172: Ifn = 0;
173: Ofn = 1;
174: fixmode(Ifn);
175: fclose(stderr);
176: fopen(RMTDEBUG, "w");
177: omsg('S', "here", Ofn);
178: signal(SIGALRM, timeout);
179: alarm(MAXMSGTIME);
180: if (setjmp(Sjbuf)) {
181: /* timed out */
182: if (!Unet) {
183: #ifdef SYSIII
184: ret = ioctl(0, TCSETA, &Savettyb);
185: #endif
186: #ifndef SYSIII
187: ret = ioctl(0, TIOCSETP, &Savettyb);
188: #endif
189: }
190: exit(0);
191: }
192: for (;;) {
193: ret = imsg(msg, Ifn);
194: if (ret != 0) {
195: alarm(0);
196: if (!Unet) {
197: #ifdef SYSIII
198: ret = ioctl(0, TCSETA, &Savettyb);
199: #endif
200: #ifndef SYSIII
201: ret = ioctl(0, TIOCSETP, &Savettyb);
202: #endif
203: }
204: exit(0);
205: }
206: if (msg[0] == 'S')
207: break;
208: }
209: alarm(0);
210: q = &msg[1];
211: p = pskip(q);
212: sprintf(Rmtname, "%.7s", q);
213: DEBUG(4, "sys-%s\n", Rmtname);
214: if (mlock(Rmtname)) {
215: omsg('R', "LCK", Ofn);
216: cleanup(0);
217: }
218: else if (callback(Loginuser)) {
219: signal(SIGINT, SIG_IGN);
220: signal(SIGHUP, SIG_IGN);
221: omsg('R', "CB", Ofn);
222: logent("CALLBACK", "REQUIRED");
223: /* set up for call back */
224: systat(Rmtname, SS_CALLBACK, "CALL BACK");
225: gename(CMDPRE, Rmtname, 'C', file);
226: close(creat(subfile(file), 0666));
227: xuucico(Rmtname);
228: cleanup(0);
229: }
230: seq = 0;
231: while (*p == '-') {
232: q = pskip(p);
233: switch(*(++p)) {
234: case 'g':
235: Pkdrvon = 1;
236: break;
237: case 'x':
238: Debug = atoi(++p);
239: if (Debug <= 0)
240: Debug = 1;
241: break;
242: case 'Q':
243: seq = atoi(++p);
244: break;
245: default:
246: break;
247: }
248: p = q;
249: }
250: if (callok(Rmtname) == SS_BADSEQ) {
251: logent("BADSEQ", "PREVIOUS");
252: omsg('R', "BADSEQ", Ofn);
253: cleanup(0);
254: }
255: if ((ret = gnxseq(Rmtname)) == seq) {
256: omsg('R', "OK", Ofn);
257: cmtseq();
258: }
259: else {
260: systat(Rmtname, Stattype[7], Stattext[7]);
261: logent("BAD SEQ", "HANDSHAKE FAILED");
262: ulkseq();
263: omsg('R', "BADSEQ", Ofn);
264: cleanup(0);
265: }
266: ttyn = ttyname(Ifn);
267: if (ttyn != NULL)
268: chmod(ttyn, 0600);
269: }
270: loop:
271: if (!onesys) {
272: ret = gnsys(Rmtname, Spool, CMDPRE);
273: if (ret == FAIL)
274: cleanup(100);
275: if (ret == 0)
276: cleanup(0);
277: }
278: else if (Role == MASTER && callok(Rmtname) != 0) {
279: logent("SYSTEM STATUS", "CAN NOT CALL");
280: cleanup(0);
281: }
282:
283: sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname);
284:
285: if (Role == MASTER) {
286: /* master part */
287: signal(SIGINT, SIG_IGN);
288: signal(SIGHUP, SIG_IGN);
289: signal(SIGQUIT, SIG_IGN);
290: if (!iswrk(file, "chk", Spool, wkpre) && !onesys) {
291: logent(Rmtname, "NO WORK");
292: goto next;
293: }
294: if (Ifn != -1 && Role == MASTER) {
295: write(Ofn, EOTMSG, strlen(EOTMSG));
296: clsacu();
297: close(Ofn);
298: close(Ifn);
299: Ifn = Ofn = -1;
300: rmlock(CNULL);
301: sleep(3);
302: }
303: sprintf(msg, "call to %s ", Rmtname);
304: if (mlock(Rmtname) != 0) {
305: logent(msg, "LOCKED");
306: goto next;
307: }
308: Ofn = Ifn = conn(Rmtname);
309: if (Ofn < 0) {
310: logent(msg, "FAILED");
311: systat(Rmtname, Stattype[-Ofn],
312: Stattext[-Ofn]);
313: goto next;
314: }
315: else {
316: logent(msg, "SUCCEEDED");
317: }
318:
319: if (setjmp(Sjbuf))
320: goto next;
321: signal(SIGALRM, timeout);
322: alarm(2 * MAXMSGTIME);
323: for (;;) {
324: ret = imsg(msg, Ifn);
325: if (ret != 0) {
326: alarm(0);
327: logent("imsg 1", "FAILED");
328: goto next;
329: }
330: if (msg[0] == 'S')
331: break;
332: }
333: alarm(MAXMSGTIME);
334: seq = gnxseq(Rmtname);
335: sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags);
336: omsg('S', msg, Ofn);
337: for (;;) {
338: ret = imsg(msg, Ifn);
339: DEBUG(4, "msg-%s\n", msg);
340: if (ret != 0) {
341: alarm(0);
342: ulkseq();
343: logent("imsg 2", "FAILED");
344: goto next;
345: }
346: if (msg[0] == 'R')
347: break;
348: }
349: alarm(0);
350: if (msg[1] == 'B') {
351: /* bad sequence */
352: logent("BAD SEQ", "HANDSHAKE FAILED");
353: systat(Rmtname, Stattype[7], Stattext[7]);
354: ulkseq();
355: goto next;
356: }
357: if (strcmp(&msg[1], "OK") != SAME) {
358: logent(&msg[1], "HANDSHAKE FAILED");
359: ulkseq();
360: goto next;
361: }
362: cmtseq();
363: }
364: DEBUG(1, " Rmtname %s, ", Rmtname);
365: DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE");
366: DEBUG(1, "Ifn - %d, ", Ifn);
367: DEBUG(1, "Loginuser - %s\n", Loginuser);
368:
369: alarm(MAXMSGTIME);
370: if (setjmp(Sjbuf))
371: goto Failure;
372: ret = startup(Role);
373: alarm(0);
374: if (ret != SUCCESS) {
375: Failure:
376: logent("startup", "FAILED");
377: systat(Rmtname, SS_FAIL, "STARTUP");
378: goto next;
379: }
380: else {
381: logent("startup", "OK");
382: systat(Rmtname, SS_INPROGRESS, "TALKING");
383: ret = cntrl(Role, wkpre);
384: DEBUG(1, "cntrl - %d\n", ret);
385: signal(SIGINT, SIG_IGN);
386: signal(SIGHUP, SIG_IGN);
387: signal(SIGALRM, timeout);
388: if (ret == 0) {
389: logent("conversation complete", "OK");
390: rmstat(Rmtname);
391:
392: }
393: else {
394: logent("conversation complete", "FAILED");
395: systat(Rmtname, SS_FAIL, "CONVERSATION");
396: }
397: alarm(MAXMSGTIME);
398: omsg('O', "OOOOO", Ofn);
399: DEBUG(4, "send OO %d,", ret);
400: if (!setjmp(Sjbuf)) {
401: for (;;) {
402: omsg('O', "OOOOO", Ofn);
403: ret = imsg(msg, Ifn);
404: if (ret != 0)
405: break;
406: if (msg[0] == 'O')
407: break;
408: }
409: }
410: alarm(0);
411: clsacu(); /* rti!trt: is this needed? */
412: }
413: next:
414: if (!onesys) {
415: goto loop;
416: }
417: cleanup(0);
418: }
419:
420: #ifndef SYSIII
421: struct sgttyb Hupvec;
422: #endif
423:
424: /***
425: * cleanup(code) cleanup and exit with "code" status
426: * int code;
427: */
428:
429: cleanup(code)
430: register int code;
431: {
432: register int ret;
433: register char *ttyn;
434:
435: signal(SIGINT, SIG_IGN);
436: signal(SIGHUP, SIG_IGN);
437: rmlock(CNULL);
438: clsacu();
439: logcls();
440: if (Role == SLAVE) {
441: if (!Unet) {
442: #ifdef SYSIII
443: Savettyb.c_cflag |= HUPCL;
444: ret = ioctl(0, TCSETA, &Savettyb);
445: #endif
446: #ifndef SYSIII
447: /* rti!trt: use more robust hang up sequence */
448: ret = ioctl(0, TIOCHPCL, STBNULL);
449: ret = ioctl(0, TIOCGETP, &Hupvec);
450: Hupvec.sg_ispeed = B0;
451: Hupvec.sg_ospeed = B0;
452: ret = ioctl(0, TIOCSETP, &Hupvec);
453: sleep(2);
454: ret = ioctl(0, TIOCSETP, &Savettyb);
455: #endif
456: DEBUG(4, "ret ioctl - %d\n", ret);
457: }
458: ttyn = ttyname(Ifn);
459: if (ttyn != NULL)
460: chmod(ttyn, 0600);
461: }
462: if (Ofn != -1) {
463: if (Role == MASTER)
464: write(Ofn, EOTMSG, strlen(EOTMSG));
465: close(Ifn);
466: close(Ofn);
467: }
468: DEBUG(1, "exit code %d\n", code);
469: if (code == 0)
470: xuuxqt();
471: exit(code);
472: }
473:
474: /***
475: * onintr(inter) interrupt - remove locks and exit
476: */
477:
478: onintr(inter)
479: register int inter;
480: {
481: char str[30];
482: signal(inter, SIG_IGN);
483: sprintf(str, "SIGNAL %d", inter);
484: logent(str, "CAUGHT");
485: systat(Rmtname, SS_FAIL, str);
486: cleanup(inter);
487: }
488:
489: /* changed to single version of intrEXIT. Is this okay? rti!trt */
490: intrEXIT(signo)
491: int signo;
492: {
493: #ifdef SIGIO
494: /* if using 4.2 signal mechanism, must unblock all signal handlers */
495: sigsetmask(0);
496: #endif
497: signal(signo, SIG_DFL);
498: setgid(getgid());
499: setuid(getuid());
500: abort();
501: }
502: /*
503: * Catch a special signal
504: * (SIGFPE, ugh), and toggle debugging between 0 and 30.
505: * Handy for looking in on long running uucicos.
506: */
507: setdebug()
508: {
509: if (Debug < 30)
510: Debug = 30;
511: else
512: Debug = 0;
513: }
514:
515:
516: /***
517: * fixmode(tty) fix kill/echo/raw on line
518: *
519: * return codes: none
520: */
521:
522: fixmode(tty)
523: register int tty;
524: {
525: #ifdef SYSIII
526: struct termio ttbuf;
527: #endif
528: #ifndef SYSIII
529: struct sgttyb ttbuf;
530: #endif
531: register int ret;
532:
533: if (Unet)
534: return;
535: #ifdef SYSIII
536: ioctl(tty, TCGETA, &ttbuf);
537: ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0;
538: ttbuf.c_cflag &= (CBAUD);
539: ttbuf.c_cflag |= (CS8|CREAD);
540: ttbuf.c_cc[VMIN] = 6;
541: ttbuf.c_cc[VTIME] = 1;
542: ret = ioctl(tty, TCSETA, &ttbuf);
543: #endif
544: #ifndef SYSIII
545: ioctl(tty, TIOCGETP, &ttbuf);
546: ttbuf.sg_flags = (ANYP | RAW);
547: ret = ioctl(tty, TIOCSETP, &ttbuf);
548: #endif
549: ASSERT(ret >= 0, "STTY FAILED", "", ret);
550: #ifndef SYSIII
551: ioctl(tty, TIOCEXCL, STBNULL);
552: #endif
553: }
554:
555:
556: /***
557: * timeout() catch SIGALRM routine
558: */
559:
560: timeout()
561: {
562: logent(Rmtname, "TIMEOUT");
563: systat(Rmtname, SS_FAIL, "TIMEOUT");
564: longjmp(Sjbuf, 1);
565: }
566:
567: static char *
568: pskip(p)
569: register char *p;
570: {
571: while( *p && *p != ' ' )
572: ++p;
573: if( *p ) *p++ = 0;
574: return(p);
575: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.