BSD 3 development
[unix-history] / usr / src / cmd / uucp / cico.c
CommitLineData
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
8char Scico[] = "@(#)cico 2.2";
9
10jmp_buf Sjbuf;
11 /* call fail text */
12char *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
23int Role = 0;
24char *ttyname();
25
26 /* call fail codes */
27int Stattype[] = {0, 0, 0, 0,
28 SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ
29 };
30
31
32int Errorrate = 0;
33struct 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
40main(argc, argv)
41char *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 }
211loop:
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 }
351next:
352 if (!onesys) {
353 goto loop;
354 }
355 cleanup(0);
356}
357
358
359int Hupvec[] = {0, 0, 1};
360
361/***
362 * cleanup(code) cleanup and exit with "code" status
363 * int code;
364 */
365
366cleanup(code)
367int 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
406onintr(inter)
407int 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
416intrINT() { onintr(SIGINT);}
417intrHUP() { onintr(SIGHUP);}
418intrQUIT() { onintr(SIGQUIT);}
419intrTERM() { onintr(SIGTERM);}
420intrEXIT()
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
433fixmode(tty)
434int 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
452timeout()
453{
454 longjmp(Sjbuf, 1);
455}
456
457static char *
458pskip(p)
459register char *p;
460{
461 while( *p && *p != ' ' )
462 ++p;
463 if( *p ) *p++ = 0;
464 return(p);
465}