BSD 4_1c_2 release
[unix-history] / usr / src / usr.bin / uucp / cico.c
CommitLineData
e804469b
C
1static 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
10char Scico[] = "@(#)cico 2.2";
11
12jmp_buf Sjbuf;
13 /* call fail text */
14char *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
25int Role = 0;
26char *ttyname();
27
28 /* call fail codes */
29int Stattype[] = {0, 0, 0, 0,
30 SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ
31 };
32
33
34int Errorrate = 0;
35struct 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
42main(argc, argv)
43char *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 }
213loop:
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 }
354next:
355 if (!onesys) {
356 goto loop;
357 }
358 cleanup(0);
359}
360
361
362int Hupvec[] = {0, 0, 1};
363
364/***
365 * cleanup(code) cleanup and exit with "code" status
366 * int code;
367 */
368
369cleanup(code)
370int 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
409onintr(inter)
410int 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
419intrINT() { onintr(SIGINT);}
420intrHUP() { onintr(SIGHUP);}
421intrQUIT() { onintr(SIGQUIT);}
422intrTERM() { onintr(SIGTERM);}
e804469b
C
423intrEXIT(signo)
424int 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
437fixmode(tty)
438int 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
456timeout()
457{
458 longjmp(Sjbuf, 1);
459}
460
461static char *
462pskip(p)
463register char *p;
464{
465 while( *p && *p != ' ' )
466 ++p;
467 if( *p ) *p++ = 0;
468 return(p);
469}