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