Commit | Line | Data |
---|---|---|
e804469b C |
1 | static char sccsid[] = "@(#)cico.c 4.2 (Berkeley) 9/14/82"; |
2 | ||
33b16e6b BJ |
3 | /* @(#)cico 2.2 5/18/79 11:31:12 */ |
4 | #include "uucp.h" | |
5 | #include "uucpdefs.h" | |
6 | #include <signal.h> | |
7 | #include <sgtty.h> | |
8 | #include <setjmp.h> | |
9 | ||
10 | char Scico[] = "@(#)cico 2.2"; | |
11 | ||
12 | jmp_buf Sjbuf; | |
13 | /* call fail text */ | |
14 | char *Stattext[] = { | |
15 | "", | |
16 | "BAD SYSTEM", | |
17 | "WRONG TIME", | |
18 | "SYSTEM LOCKED", | |
19 | "NO DEVICE", | |
20 | "DIAL FAILED", | |
21 | "LOGIN FAILED", | |
22 | "BAD SEQUENCE" | |
23 | }; | |
24 | ||
25 | int Role = 0; | |
26 | char *ttyname(); | |
27 | ||
28 | /* call fail codes */ | |
29 | int Stattype[] = {0, 0, 0, 0, | |
30 | SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ | |
31 | }; | |
32 | ||
33 | ||
34 | int Errorrate = 0; | |
35 | struct sgttyb Savettyb; | |
36 | ||
37 | /******* | |
38 | * cico - this program is used to place a call to a | |
39 | * remote machine, login, and copy files between the two machines. | |
40 | */ | |
41 | ||
42 | main(argc, argv) | |
43 | char *argv[]; | |
44 | { | |
45 | int ret, seq; | |
46 | int onesys = 0; | |
47 | char wkpre[NAMESIZE], file[NAMESIZE]; | |
48 | char msg[BUFSIZ], *p, *q; | |
49 | extern onintr(), timeout(); | |
50 | extern intrINT(); | |
51 | extern intrHUP(); | |
52 | extern intrQUIT(); | |
53 | extern intrTERM(); | |
54 | extern intrEXIT(); | |
55 | extern char *pskip(); | |
56 | char rflags[30]; | |
57 | char *ttyn; | |
58 | ||
59 | signal(SIGILL, intrEXIT); | |
60 | signal(SIGTRAP, intrEXIT); | |
61 | signal(SIGIOT, intrEXIT); | |
62 | signal(SIGEMT, intrEXIT); | |
63 | signal(SIGFPE, intrEXIT); | |
64 | signal(SIGBUS, intrEXIT); | |
65 | signal(SIGSEGV, intrEXIT); | |
66 | signal(SIGSYS, intrEXIT); | |
67 | signal(SIGINT, intrINT); | |
68 | signal(SIGHUP, intrHUP); | |
69 | signal(SIGQUIT, intrQUIT); | |
70 | signal(SIGTERM, intrTERM); | |
71 | ret = guinfo(getuid(), User, msg); | |
72 | strcpy(Loginuser, User); | |
73 | ASSERT(ret == 0, "BAD UID ret %d", ret); | |
74 | ||
75 | rflags[0] = '\0'; | |
76 | uucpname(Myname); | |
77 | strcpy(Rmtname, Myname); | |
78 | Ifn = Ofn = -1; | |
79 | while(argc>1 && argv[1][0] == '-'){ | |
80 | switch(argv[1][1]){ | |
81 | case 'd': | |
82 | Spool = &argv[1][2]; | |
83 | break; | |
84 | /* | |
85 | * case 'E': | |
86 | * Errorrate = atoi(&argv[1][2]); | |
87 | * if (Errorrate <= 0) | |
88 | * Errorrate = 100; | |
89 | * break; | |
90 | * case 'g': | |
91 | * Pkdrvon = 1; | |
92 | * break; | |
93 | * case 'G': | |
94 | * Pkdrvon = 1; | |
95 | * strcat(rflags, " -g "); | |
96 | * break; | |
97 | */ | |
98 | case 'r': | |
99 | Role = atoi(&argv[1][2]); | |
100 | break; | |
101 | case 's': | |
102 | sprintf(Rmtname, "%.7s", &argv[1][2]); | |
103 | if (Rmtname[0] != '\0') | |
104 | onesys = 1; | |
105 | break; | |
106 | case 'x': | |
107 | Debug = atoi(&argv[1][2]); | |
108 | if (Debug <= 0) | |
109 | Debug = 1; | |
110 | strcat(rflags, argv[1]); | |
111 | break; | |
112 | default: | |
113 | printf("unknown flag %s\n", argv[1]); | |
114 | break; | |
115 | } | |
116 | --argc; argv++; | |
117 | } | |
118 | ||
119 | chdir(Spool); | |
120 | strcpy(Wrkdir, Spool); | |
121 | ||
122 | if (Role == SLAVE) { | |
123 | /* initial handshake */ | |
124 | onesys = 1; | |
125 | ret = ioctl(0, TIOCGETP, &Savettyb); | |
126 | Savettyb.sg_flags |= ECHO; | |
127 | Savettyb.sg_flags &= ~RAW; | |
128 | Ifn = 0; | |
129 | Ofn = 1; | |
130 | fixmode(Ifn); | |
131 | fclose(stderr); | |
132 | fopen(RMTDEBUG, "w"); | |
133 | chmod(RMTDEBUG, 0666); | |
134 | omsg('S', "here", Ofn); | |
135 | signal(SIGALRM, timeout); | |
136 | alarm(MAXMSGTIME); | |
137 | if (setjmp(Sjbuf)) { | |
138 | /* timed out */ | |
139 | ret = ioctl(0, TIOCSETP, &Savettyb); | |
140 | exit(0); | |
141 | } | |
142 | for (;;) { | |
143 | ret = imsg(msg, Ifn); | |
144 | if (ret != 0) { | |
145 | alarm(0); | |
146 | ret = ioctl(0, TIOCSETP, &Savettyb); | |
147 | exit(0); | |
148 | } | |
149 | if (msg[0] == 'S') | |
150 | break; | |
151 | } | |
152 | alarm(0); | |
153 | DEBUG(4, "msg-%s,", msg); | |
154 | q = &msg[1]; | |
155 | p = pskip(q); | |
156 | sprintf(Rmtname, "%.7s", q); | |
157 | DEBUG(4, "sys-%s\n", Rmtname); | |
158 | if (mlock(Rmtname)) { | |
159 | omsg('R', "LCK", Ofn); | |
160 | cleanup(0); | |
161 | } | |
162 | else if (callback(Loginuser)) { | |
163 | signal(SIGINT, SIG_IGN); | |
164 | signal(SIGHUP, SIG_IGN); | |
165 | omsg('R', "CB", Ofn); | |
166 | DEBUG(4, "CALLBACK Role %d\n", Role); | |
167 | logent("CALLBACK", "REQUIRED"); | |
168 | /* set up for call back */ | |
169 | systat(Rmtname, SS_CALLBACK, "CALL BACK"); | |
170 | gename(CMDPRE, Rmtname, 'C', file); | |
171 | close(creat(file, 0666)); | |
172 | chmod(file, 0666); | |
173 | xuucico(Rmtname); | |
174 | cleanup(0); | |
175 | } | |
176 | seq = 0; | |
177 | while (*p == '-') { | |
178 | q = pskip(p); | |
179 | switch(*(++p)) { | |
180 | case 'g': | |
181 | Pkdrvon = 1; | |
182 | break; | |
183 | case 'x': | |
184 | Debug = atoi(++p); | |
185 | if (Debug <= 0) | |
186 | Debug = 1; | |
187 | break; | |
188 | case 'Q': | |
189 | seq = atoi(++p); | |
190 | break; | |
191 | default: | |
192 | break; | |
193 | } | |
194 | p = q; | |
195 | } | |
196 | if (callok(Rmtname) == SS_BADSEQ) { | |
197 | logent("BADSEQ", "PREVIOUS"); | |
198 | omsg('R', "BADSEQ", Ofn); | |
199 | cleanup(0); | |
200 | } | |
201 | if ((ret = gnxseq(Rmtname)) == seq) { | |
202 | omsg('R', "OK", Ofn); | |
203 | cmtseq(); | |
204 | } | |
205 | else { | |
206 | systat(Rmtname, Stattype[7], Stattext[7]); | |
207 | logent("BAD SEQ", "HANDSHAKE FAILED"); | |
208 | ulkseq(); | |
209 | omsg('R', "BADSEQ", Ofn); | |
210 | cleanup(0); | |
211 | } | |
212 | } | |
213 | loop: | |
214 | if (!onesys) { | |
215 | ret = gnsys(Rmtname, Spool, CMDPRE); | |
216 | if (ret == FAIL) | |
217 | cleanup(100); | |
218 | if (ret == 0) | |
219 | cleanup(0); | |
220 | } | |
221 | else if (Role == MASTER && callok(Rmtname) != 0) { | |
222 | logent("SYSTEM STATUS", "CAN NOT CALL"); | |
223 | cleanup(0); | |
224 | } | |
225 | ||
226 | sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname); | |
227 | ||
228 | if (Role == MASTER) { | |
229 | /* master part */ | |
230 | signal(SIGINT, SIG_IGN); | |
231 | signal(SIGHUP, SIG_IGN); | |
232 | signal(SIGQUIT, SIG_IGN); | |
233 | if (!iswrk(file, "chk", Spool, wkpre) && !onesys) { | |
234 | logent(Rmtname, "NO WORK"); | |
235 | cleanup(0); | |
236 | } | |
237 | if (Ifn != -1 && Role == MASTER) { | |
238 | write(Ofn, EOTMSG, strlen(EOTMSG)); | |
239 | close(Ofn); | |
240 | close(Ifn); | |
241 | Ifn = Ofn = -1; | |
242 | rmlock(NULL); | |
243 | clsacu(); | |
244 | sleep(3); | |
245 | } | |
246 | sprintf(msg, "call to %s ", Rmtname); | |
247 | if (mlock(Rmtname) != 0) { | |
248 | logent(msg, "LOCKED"); | |
249 | goto next; | |
250 | } | |
251 | Ofn = Ifn = conn(Rmtname); | |
252 | if (Ofn < 0) { | |
253 | logent(msg, "FAILED"); | |
254 | systat(Rmtname, Stattype[-Ofn], | |
255 | Stattext[-Ofn]); | |
256 | goto next; | |
257 | } | |
258 | else { | |
259 | logent(msg, "SUCCEEDED"); | |
260 | } | |
261 | ||
262 | if (setjmp(Sjbuf)) | |
263 | goto next; | |
264 | signal(SIGALRM, timeout); | |
265 | alarm(2 * MAXMSGTIME); | |
266 | for (;;) { | |
267 | ret = imsg(msg, Ifn); | |
268 | if (ret != 0) { | |
269 | alarm(0); | |
270 | goto next; | |
271 | } | |
272 | if (msg[0] == 'S') | |
273 | break; | |
274 | } | |
e804469b | 275 | alarm(0); |
33b16e6b BJ |
276 | seq = gnxseq(Rmtname); |
277 | sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags); | |
278 | omsg('S', msg, Ofn); | |
e804469b | 279 | alarm(MAXMSGTIME); |
33b16e6b BJ |
280 | for (;;) { |
281 | ret = imsg(msg, Ifn); | |
282 | DEBUG(4, "msg-%s\n", msg); | |
283 | if (ret != 0) { | |
284 | alarm(0); | |
285 | ulkseq(); | |
286 | goto next; | |
287 | } | |
288 | if (msg[0] == 'R') | |
289 | break; | |
290 | } | |
291 | alarm(0); | |
292 | if (msg[1] == 'B') { | |
293 | /* bad sequence */ | |
294 | logent("BAD SEQ", "HANDSHAKE FAILED"); | |
295 | systat(Rmtname, Stattype[7], Stattext[7]); | |
296 | ulkseq(); | |
297 | goto next; | |
298 | } | |
299 | if (strcmp(&msg[1], "OK") != SAME) { | |
300 | logent(&msg[1], "HANDSHAKE FAILED"); | |
301 | ulkseq(); | |
302 | goto next; | |
303 | } | |
304 | cmtseq(); | |
305 | } | |
306 | ttyn = ttyname(Ifn); | |
307 | if (ttyn != NULL) | |
308 | chmod(ttyn, 0600); | |
309 | DEBUG(1, " Rmtname %s, ", Rmtname); | |
310 | DEBUG(1, "my Role %s, ", Role ? "MASTER" : "SLAVE"); | |
311 | DEBUG(1, "Spool - %s\n", Spool); | |
312 | DEBUG(1, "Ifn - %d, ", Ifn); | |
313 | DEBUG(1, "Ofn - %d, ", Ofn); | |
314 | DEBUG(1, "Loginuser - %s\n", Loginuser); | |
315 | ||
316 | ret = startup(Role); | |
317 | if (ret != SUCCESS) { | |
318 | logent("startup", "FAILED"); | |
319 | systat(Rmtname, SS_FAIL, "STARTUP"); | |
320 | goto next; | |
321 | } | |
322 | else { | |
323 | logent("startup", "OK"); | |
324 | systat(Rmtname, SS_INPROGRESS, "TALKING"); | |
325 | ret = cntrl(Role, wkpre); | |
326 | DEBUG(1, "ret from cntrl - %d\n", ret); | |
327 | signal(SIGINT, SIG_IGN); | |
328 | signal(SIGHUP, SIG_IGN); | |
329 | signal(SIGALRM, timeout); | |
330 | if (ret == 0) { | |
331 | logent("conversation complete", "OK"); | |
332 | rmstat(Rmtname); | |
333 | ||
334 | } | |
335 | else { | |
336 | logent("conversation complete", "FAILED"); | |
337 | systat(Rmtname, SS_FAIL, "CONVERSATION"); | |
338 | } | |
339 | alarm(MAXMSGTIME); | |
340 | omsg('O', "OOOOO", Ofn); | |
341 | DEBUG(4, "send OO %d,", ret); | |
342 | if (!setjmp(Sjbuf)) { | |
343 | for (;;) { | |
344 | omsg('O', "OOOOO", Ofn); | |
345 | ret = imsg(msg, Ifn); | |
346 | if (ret != 0) | |
347 | break; | |
348 | if (msg[0] == 'O') | |
349 | break; | |
350 | } | |
351 | } | |
352 | alarm(0); | |
353 | } | |
354 | next: | |
355 | if (!onesys) { | |
356 | goto loop; | |
357 | } | |
358 | cleanup(0); | |
359 | } | |
360 | ||
361 | ||
362 | int Hupvec[] = {0, 0, 1}; | |
363 | ||
364 | /*** | |
365 | * cleanup(code) cleanup and exit with "code" status | |
366 | * int code; | |
367 | */ | |
368 | ||
369 | cleanup(code) | |
370 | int code; | |
371 | { | |
372 | int ret; | |
373 | char *ttyn; | |
374 | ||
375 | signal(SIGINT, SIG_IGN); | |
376 | signal(SIGHUP, SIG_IGN); | |
377 | rmlock(NULL); | |
378 | clsacu(); | |
379 | logcls(); | |
380 | if (Role == SLAVE) { | |
381 | ret = ioctl(0, TIOCSETP, &Savettyb); | |
382 | DEBUG(4, "\nIfn - %d, ", Ifn); | |
383 | DEBUG(4, "ret ioctl - %d\n", ret); | |
384 | DEBUG(4, "tty.flags %o,", Savettyb.sg_flags); | |
385 | DEBUG(4, "tty.ispeed %d, ", Savettyb.sg_ispeed); | |
386 | DEBUG(4, "tty.ospeed %d, ", Savettyb.sg_ospeed); | |
387 | ret = ioctl(0, TIOCSETP, Hupvec); | |
388 | DEBUG(4, "ret ioctl - %d\n", ret); | |
389 | } | |
390 | if (Ofn != -1) { | |
391 | if (Role == MASTER) | |
392 | write(Ofn, EOTMSG, strlen(EOTMSG)); | |
393 | ttyn = ttyname(Ifn); | |
394 | if (ttyn != NULL) | |
395 | chmod(ttyn, 0666); | |
396 | close(Ifn); | |
397 | close(Ofn); | |
398 | } | |
399 | DEBUG(1, "exit code %d\n", code); | |
400 | if (code == 0) | |
401 | xuuxqt(); | |
402 | exit(code); | |
403 | } | |
404 | ||
405 | /*** | |
406 | * onintr(inter) interrupt - remove locks and exit | |
407 | */ | |
408 | ||
409 | onintr(inter) | |
410 | int inter; | |
411 | { | |
412 | char str[30]; | |
413 | signal(inter, SIG_IGN); | |
414 | sprintf(str, "SIGNAL %d", inter); | |
415 | logent(str, "CAUGHT"); | |
416 | cleanup(inter); | |
417 | } | |
418 | ||
419 | intrINT() { onintr(SIGINT);} | |
420 | intrHUP() { onintr(SIGHUP);} | |
421 | intrQUIT() { onintr(SIGQUIT);} | |
422 | intrTERM() { onintr(SIGTERM);} | |
e804469b C |
423 | intrEXIT(signo) |
424 | int signo; | |
33b16e6b | 425 | { |
e804469b | 426 | signal(signo, SIG_DFL); |
33b16e6b BJ |
427 | setuid(getuid()); |
428 | abort(); | |
429 | } | |
430 | ||
431 | /*** | |
432 | * fixmode(tty) fix kill/echo/raw on line | |
433 | * | |
434 | * return codes: none | |
435 | */ | |
436 | ||
437 | fixmode(tty) | |
438 | int tty; | |
439 | { | |
440 | struct sgttyb ttbuf; | |
441 | int ret; | |
442 | ||
443 | ioctl(tty, TIOCGETP, &ttbuf); | |
444 | ttbuf.sg_flags = (ANYP | RAW); | |
445 | ret = ioctl(tty, TIOCSETP, &ttbuf); | |
446 | ASSERT(ret >= 0, "RETURN FROM STTY %d", ret); | |
447 | ioctl(tty, TIOCEXCL, 0); | |
448 | return; | |
449 | } | |
450 | ||
451 | ||
452 | /*** | |
453 | * timeout() catch SIGALRM routine | |
454 | */ | |
455 | ||
456 | timeout() | |
457 | { | |
458 | longjmp(Sjbuf, 1); | |
459 | } | |
460 | ||
461 | static char * | |
462 | pskip(p) | |
463 | register char *p; | |
464 | { | |
465 | while( *p && *p != ' ' ) | |
466 | ++p; | |
467 | if( *p ) *p++ = 0; | |
468 | return(p); | |
469 | } |