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