Research V7 development
[unix-history] / usr / src / cmd / uucp / cico.c
CommitLineData
808bd6eb
N
1#include "uucp.h"
2#include "uucpdefs.h"
3#include <signal.h>
4#include <sgtty.h>
5#include <setjmp.h>
6
7jmp_buf Sjbuf;
8 /* call fail text */
9char *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
20int Role = 0;
21
22 /* call fail codes */
23int Stattype[] = {0, 0, 0, 0,
24 SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ
25 };
26
27
28int Errorrate = 0;
29struct 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
36main(argc, argv)
37char *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 }
207loop:
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 }
342next:
343 if (!onesys) {
344 goto loop;
345 }
346 cleanup(0);
347}
348
349
350int Hupvec[] = {0, 0, 1};
351
352/***
353 * cleanup(code) cleanup and exit with "code" status
354 * int code;
355 */
356
357cleanup(code)
358int 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
393onintr(inter)
394int 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
403intrINT() { onintr(SIGINT);}
404intrHUP() { onintr(SIGHUP);}
405intrQUIT() { onintr(SIGQUIT);}
406intrTERM() { onintr(SIGTERM);}
407intrEXIT() {_exit(77);}
408
409/***
410 * fixmode(tty) fix kill/echo/raw on line
411 *
412 * return codes: none
413 */
414
415fixmode(tty)
416int 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
435timeout()
436{
437 longjmp(Sjbuf, 1);
438}
439
440static char *
441pskip(p)
442register char *p;
443{
444 while( *p && *p != ' ' )
445 ++p;
446 if( *p ) *p++ = 0;
447 return(p);
448}