|
|
1.1 root 1: /* conn 2.1 5/23/79 19:07:44 */
2: #define CONN
3: #include "uucp.h"
4: #include <signal.h>
5: #include <sgtty.h>
6: #include <setjmp.h>
7: #include <ctype.h>
8: #include <sys/types.h>
9: #include <time.h>
10:
11: static char SiD[] = "@(#)conn 2.1";
12:
13: #ifdef DATAKIT
14: #include <dk.h>
15: #endif
16:
17:
18: #define F_NAME 0
19: #define F_TIME 1
20: #define F_LINE 2
21: #define F_SPEED 3
22: #define F_PHONE 4
23: #define F_LOGIN 5
24:
25: jmp_buf Sjbuf;
26: int alarmtr();
27: #define INVOKE(a, r) ret = a; if (ret<0) return(r);
28: /*******
29: * conn(system)
30: * char *system;
31: *
32: * conn - place a telephone call to system and
33: * login, etc.
34: *
35: * return codes:
36: * CF_SYSTEM: don't know system
37: * CF_TIME: wrong time to call
38: * CF_DIAL: call failed
39: * CF_LOGIN: login/password dialog failed
40: *
41: * >0 - file no. - connect ok
42: *
43: */
44:
45: conn(system)
46: char *system;
47: {
48: int ret, nf;
49: int fn;
50: char *flds[50];
51: DEBUG(4, "gdial %s\n", "called");
52: INVOKE(gdial(), CF_DIAL)
53: DEBUG(4, "finds %s\n", "called");
54: INVOKE(nf = finds(system, flds), nf)
55: DEBUG(4, "getto %s\n", "called");
56: INVOKE(fn = getto(flds), CF_DIAL)
57: DEBUG(4, "login %s\n", "called");
58: INVOKE(login(nf, flds, fn), CF_LOGIN)
59: return(fn);
60: }
61:
62: /***
63: * char *
64: * lastc(s) return pointer to last character
65: * char *s;
66: *
67: */
68:
69: char *
70: lastc(s)
71: char *s;
72: {
73: while (*s != '\0') s++;
74: return(s);
75: }
76:
77: #define MAXDEV 10
78: #define MAXDCH MAXDEV*20
79: #define MAXCODE 30
80: #define MAXCCH MAXCODE*20
81: /* This array tells us about possible acu's, etc. */
82: struct Devices {
83: char *D_type;
84: char *D_line;
85: char *D_calldev;
86: int D_speed;
87: } Devs [MAXDEV];
88:
89: char Devbuff[MAXDCH];
90:
91: struct Codes {
92: char *C_locs;
93: char *C_prefix;
94: } Dialcodes [MAXCODE];
95:
96: char Codebuff[MAXCCH];
97: int Dcfull = 0;
98:
99:
100: /***
101: * gdial() get device and dial info
102: *
103: * return codes: 0 | FAIL
104: */
105:
106: gdial()
107: {
108: char *flds[10], *lt;
109: char *lb = Devbuff;
110: char *lc = Codebuff;
111: FILE *fn;
112: int nr;
113: struct Devices *pd;
114: struct Codes *pc;
115: if (Dcfull) return(0);
116:
117: fn = fopen(Devfile, "r");
118: ASSERT(fn != NULL, "CAN'T OPEN %s", Devfile);
119: for (pd = Devs; fgets(lb, 200, fn); pd++) {
120: lt = lastc(lb);
121: nr = getargs(lb, flds);
122: ASSERT(nr == 4, "BAD LINE %s", lb);
123: pd->D_type = flds[0];
124: pd->D_line = flds[1];
125: pd->D_calldev = flds[2];
126: pd->D_speed = atoi(flds[3]);
127: lb = lt;
128: ASSERT(lb < Devbuff + MAXDCH, "TOO LONG %s", Devbuff);
129: ASSERT(pd < Devs + MAXDEV, "TOO MANY DEVICES %d", MAXCODE);
130: }
131: pd->D_line = NULL;
132: fclose(fn);
133: ASSERT(pd > Devs, "BAD FILE %s", Devfile);
134: /* Now dialcodes, same way */
135: fn = fopen(Dialfile, "r");
136: ASSERT(fn != NULL, "CAN'T OPEN %s", Dialfile);
137: for (pc = Dialcodes; fgets(lc, 200, fn); pc++) {
138: lt = lastc(lc);
139: nr = getargs(lc, flds);
140: if (nr == 1) flds[nr++] = "";
141: ASSERT(nr == 2, "BAD LINE %s", lc);
142: pc->C_locs = flds[0];
143: pc->C_prefix = flds[1];
144: lc = lt;
145: ASSERT(lc < Codebuff + MAXCCH, "TOO LONG %s", Codebuff);
146: ASSERT(pc < Dialcodes + MAXCODE, "MANY DEVICES %d", MAXCODE);
147: }
148: pc->C_locs = 0;
149: fclose(fn);
150: return(0);
151: }
152:
153:
154: /***
155: * ckdev(type, speed, ndev)
156: * char *type, *speed;
157: * int ndev;
158: *
159: * ckdev - return the device number in table Devs for
160: * a device with proper attributes.
161: *
162: * return codes: >= 0 (ok) | FAIL
163: */
164:
165: ckdev(type, speed, ndev)
166: char *type, *speed;
167: int ndev;
168: {
169: int sp;
170: struct Devices *pd;
171:
172: sp = atoi(speed);
173: for (pd = &Devs[ndev]; pd->D_line != NULL; pd++) {
174: if (sp != pd->D_speed)
175: continue;
176: if ((strcmp(pd->D_type, type) == SAME)
177: && !mlock(pd->D_line))
178: return(ndev = pd - Devs);
179: if ((strcmp(pd->D_line, type) == SAME)
180: && !mlock(type))
181: return(ndev = pd - Devs);
182: }
183: return(FAIL);
184: }
185:
186:
187: /***
188: * getto(flds) connect to remote machine
189: * char *flds[];
190: *
191: * return codes:
192: * >0 - file number - ok
193: * FAIL - failed
194: */
195:
196: getto(flds)
197: char *flds[];
198: {
199: DEBUG(F_PHONE, "call: no. %s ", flds[4]);
200: DEBUG(4, "for sys %s ", flds[F_NAME]);
201:
202: if (prefix("ACU", flds[F_LINE]))
203: return(call(flds));
204:
205: #ifdef DATAKIT
206: else if (prefix("DK", flds[F_LINE]))
207: return(dkcall(flds));
208: #endif
209:
210: else
211: return(direct(flds));
212: }
213:
214: /***
215: * call(flds) call remote machine
216: * char *flds[];
217: *
218: * "flds" contains the call information (name, date, type, speed,
219: * phone no. ...
220: * Ndev has the device no.
221: *
222: * return codes:
223: * >0 - file number - ok
224: * FAIL - failed
225: */
226:
227: call(flds)
228: char *flds[];
229: {
230: char *pno, pref[20], phone[20];
231: char *s1, *s2;
232: int dcr, i;
233: struct Codes *pc;
234:
235: pno = flds[F_PHONE];
236: s1 = pref; s2 = pno;
237: while (isalpha(*s2))
238: *s1++ = *s2++;
239: *s1 = '\0';
240: for (pc = Dialcodes; pc->C_locs; pc++)
241: if (strcmp(pc->C_locs, pref) == SAME) {
242: s1 = pc->C_prefix;
243: break;
244: }
245: sprintf(phone, "%s%s", s1, s2);
246: for (i = 0; i < TRYCALLS; i++) {
247: DEBUG(4, "Dial %s\n", phone);
248: dcr = dialup(phone, flds);
249: DEBUG(4, "dcr returned as %d\n", dcr);
250: if (dcr != FAIL)
251: break;
252: }
253: return(dcr);
254:
255: }
256:
257: /* file descriptor for call unit */
258: int Dnf = 0;
259:
260: /***
261: * dialup(ph, flds) dial remote machine
262: * char *ph;
263: * char *flds[];
264: *
265: * return codes:
266: * file descriptor - succeeded
267: * FAIL - failed
268: */
269:
270: dialup(ph, flds)
271: char *ph;
272: char *flds[];
273: {
274: #ifdef DIALOUT
275: int dcf;
276: if ((dcf = dialout(ph, flds[F_SPEED])) < 0)
277: return(FAIL);
278: return(dcf);
279: #endif
280:
281: #ifndef DIALOUT
282: char dcname[20], dnname[20], phone[20];
283: struct Devices *pd;
284: int nw, lt, pid, dcf, ndev, timelim;
285: extern int Error;
286:
287: for (ndev = 0;;ndev++) {
288: ndev = ckdev(flds[F_LINE], flds[F_SPEED], ndev);
289: if (ndev < 0) {
290: logent("AVAILABLE DEVICE", "NO");
291: DEBUG(4, "NO AVAILABLE DEVICE %s\n", "");
292: return(FAIL);
293: }
294: pd = &Devs[ndev];
295: sprintf(dnname, "/dev/%s", pd->D_calldev);
296: /* open call unit */
297: Dnf = open(dnname, 1);
298: if (Dnf >= 0)
299: break;
300: delock(pd->D_line);
301: }
302: sprintf(dcname, "/dev/%s", pd->D_line);
303: sprintf(phone, "%s%s", ph, ACULAST);
304: DEBUG(4, "dc - %s, ", dcname);
305: DEBUG(4, "acu - %s\n", dnname);
306: if (setjmp(Sjbuf)) {
307: DEBUG(1, "DN write %s\n", "timeout");
308: logent("DIALUP DN write", "TIMEOUT");
309: kill(pid, 9);
310: delock(pd->D_line);
311: close(Dnf);
312: return(FAIL);
313: }
314: signal(SIGALRM, alarmtr);
315: timelim = 5 * strlen(phone);
316: alarm(timelim < 30 ? 30 : timelim);
317: if ((pid = fork()) == 0) {
318: sleep(2);
319: fclose(stdin);
320: fclose(stdout);
321: nw = write(Dnf, phone, lt = strlen(phone));
322: if (nw != lt) {
323: DEBUG(1, "ACU write %s\n", "error");
324: logent("DIALUP ACU write", "FAILED");
325: exit(1);
326: }
327: DEBUG(4, "ACU write ok%s\n", "");
328: exit(0);
329: }
330: /* open line - will return on carrier */
331: dcf = open(dcname, 2);
332: DEBUG(4, "dcf is %d\n", dcf);
333: if (dcf < 0) {
334: DEBUG(1, "Line open %s\n", "failed");
335: logent("DIALUP LINE open", "FAILED");
336: alarm(0);
337: kill(pid, 9);
338: close(Dnf);
339: return(FAIL);
340: }
341: ioctl(dcf, TIOCHPCL, 0);
342: while ((nw = wait(<)) != pid && nw != -1)
343: ;
344: alarm(0);
345: fflush(stdout);
346: fixline(dcf, pd->D_speed);
347: DEBUG(4, "Forked %d ", pid);
348: DEBUG(4, "Wait got %d ", nw);
349: DEBUG(4, "Status %o\n", lt);
350: if (lt != 0) {
351: close(dcf);
352: close(Dnf);
353: return(FAIL);
354: }
355: return(dcf);
356: #endif
357: }
358:
359:
360: /***
361: * clsacu() close call unit
362: *
363: * return codes: none
364: */
365:
366: clsacu()
367: {
368: if (Dnf > 0) {
369: close(Dnf);
370: sleep(5);
371: Dnf = 0;
372: }
373: return;
374: }
375:
376:
377: /***
378: * direct(flds) connect to hardware line
379: * char *flds[];
380: *
381: * return codes:
382: * >0 - file number - ok
383: * FAIL - failed
384: */
385:
386: direct(flds)
387: char *flds[];
388: {
389: int dcr, ndev;
390: char dcname[20];
391:
392: ndev = 0;
393: if ((ndev = ckdev(flds[F_LINE], flds[F_SPEED], ndev)) < 0) {
394: logent("DEVICE", "NOT AVAILABLE");
395: return(FAIL);
396: }
397: sprintf(dcname, "/dev/%s", Devs[ndev].D_line);
398: signal(SIGALRM, alarmtr);
399: alarm(10);
400: if (setjmp(Sjbuf))
401: return(FAIL);
402: dcr = open(dcname, 2); /* read/write */
403: alarm(0);
404: if (dcr < 0)
405: return(FAIL);
406: fflush(stdout);
407: fixline(dcr, Devs[ndev].D_speed);
408: return(dcr);
409: }
410:
411: #ifdef DATAKIT
412:
413: #define DKTRIES 2
414:
415: /***
416: * dkcall(flds) make datakit connection
417: *
418: * return codes:
419: * >0 - file number - ok
420: * FAIL - failed
421: */
422:
423: dkcall(flds)
424: char *flds[];
425: {
426: int dkphone;
427: register char *cp;
428: register ret, i;
429:
430: if (setjmp(Sjbuf))
431: return(FAIL);
432: signal(SIGALRM, alarmtr);
433: dkphone = 0;
434: cp = flds[F_PHONE];
435: while(*cp)
436: dkphone = 10 * dkphone + (*cp++ - '0');
437: DEBUG(4, "dkphone (%d) ", dkphone);
438: for (i = 0; i < DKTRIES; i++) {
439: ret = dkdial(D_UU, dkphone, 0);
440: DEBUG(4, "dkdial (%d)\n", ret);
441: if (ret > -1)
442: break;
443: }
444: return(ret);
445: }
446: #endif
447:
448: #define MAXC 300
449:
450: /***
451: * finds(sysnam, flds) set system attribute vector
452: * char *sysnam, *flds[];
453: *
454: * return codes:
455: * >0 - number of arguments in vector - succeeded
456: * CF_SYSTEM - system name not found
457: * CF_TIME - wrong time to call
458: */
459:
460: finds(sysnam, flds)
461: char *sysnam, *flds[];
462: {
463: FILE *fsys;
464: static char info[MAXC];
465: char **fnp;
466: int na;
467: int fnd = 0;
468:
469: for (fnp = Sysfiles; *fnp != NULL && !fnd; fnp++) {
470: fsys = fopen(*fnp, "r");
471: if (fsys == NULL)
472: continue;
473: while (!fnd && (fgets(info, MAXC, fsys) != NULL)) {
474: na = getargs(info, flds);
475: if (prefix(sysnam, flds[F_NAME]))
476: fnd = 1;
477: }
478: fclose(fsys);
479: }
480: if (fnd == 0)
481: return(CF_SYSTEM);
482: /* format of fields
483: * 0 name;
484: * 1 time
485: * 2 acu/hardwired
486: * 3 speed
487: * etc
488: */
489: if (ifdate(flds[F_TIME]) == 0) {
490: DEBUG(1, "Wrong time to call %s\n", sysnam);
491: logent(sysnam, "WRONG TIME TO CALL");
492: return(CF_TIME);
493: }
494: return(na);
495: }
496:
497:
498: /***
499: * login(nf, flds, dcr) do log conversation
500: * char *flds[];
501: * int nf;
502: *
503: * return codes: 0 | FAIL
504: */
505:
506: login(nf, flds, fn)
507: char *flds[];
508: int nf, fn;
509: {
510: char *want, *altern;
511: extern char *index();
512: int k, ok;
513:
514: ASSERT(nf > 4, "TOO FEW LOG FIELDS %d", nf);
515: for (k = F_LOGIN; k < nf; k += 2) {
516: want = flds[k];
517: ok = FAIL;
518: while (ok != 0) {
519: altern = index(want, '-');
520: if (altern != NULL)
521: *altern++ = '\0';
522: DEBUG(4, "wanted %s ", want);
523: ok = expect(want, fn);
524: DEBUG(4, "got %s\n", ok ? "?" : "that");
525: if (ok == 0)
526: break;
527: if (altern == NULL) {
528: logent("LOGIN", "FAILED");
529: return(FAIL);
530: }
531: want = index(altern, '-');
532: if (want != NULL)
533: *want++ = '\0';
534: sendthem(altern, fn);
535: }
536: sleep(2);
537: sendthem(flds[k+1], fn);
538: }
539: return(0);
540: }
541:
542:
543: struct sg_spds {int sp_val, sp_name;} spds[] = {
544: { 300, B300},
545: {1200, B1200},
546: {4800, B4800},
547: {9600, B9600},
548: {0, 0} };
549:
550: /***
551: * fixline(tty, spwant) set speed/echo/mode...
552: * int tty, spwant;
553: *
554: * return codes: none
555: */
556:
557: fixline(tty, spwant)
558: int tty, spwant;
559: {
560: struct sgttyb ttbuf;
561: struct sg_spds *ps;
562: int speed = -1;
563: int ret;
564:
565: for (ps = spds; ps->sp_val; ps++)
566: if (ps->sp_val == spwant)
567: speed = ps->sp_name;
568: ASSERT(speed >= 0, "BAD SPEED %d", speed);
569: ioctl(tty, TIOCGETP, &ttbuf);
570: ttbuf.sg_flags =(ANYP|RAW);
571: ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed;
572: DEBUG(4, "Speed: want %d ", spwant);
573: DEBUG(4, "use %o ", speed);
574: DEBUG(4, "ps %d\n", ps-spds);
575: ret = ioctl(tty, TIOCSETP, &ttbuf);
576: ASSERT(ret >= 0, "RETURN FROM STTY %d", ret);
577: ioctl(tty, TIOCHPCL, 0);
578: ioctl(tty, TIOCEXCL, 0);
579: return;
580: }
581:
582:
583: #define MR 300
584:
585: int Error = 0;
586:
587: /***
588: * expect(str, fn) look for expected string
589: * char *str;
590: *
591: * return codes:
592: * 0 - found
593: * FAIL - lost line or too many characters read
594: * some character - timed out
595: */
596:
597: expect(str, fn)
598: char *str;
599: int fn;
600: {
601: static char rdvec[MR];
602: char *rp = rdvec;
603: int nextch = 0, kr;
604:
605: if (strcmp(str, "\"\"") == SAME)
606: return(0);
607: *rp = 0;
608: if (setjmp(Sjbuf)) {
609: return(FAIL);
610: }
611: signal(SIGALRM, alarmtr);
612: while (notin(str, rdvec)) {
613: alarm(MAXCHARTIME);
614: kr = read(fn, &nextch, 1);
615: if (kr <= 0) {
616: DEBUG(4, "kr - %d\n", kr);
617: alarm(0);
618: DEBUG(4, "lost line kr - %d, ", kr);
619: DEBUG(4, "fn - %d\n", fn);
620: logent("LOGIN", "LOST LINE");
621: return(FAIL);
622: }
623: {
624: int c;
625: c = nextch & 0177;
626: DEBUG(4, "%c", c > 040 ? c : '_');
627: }
628: if ((*rp = nextch & 0177) != '\0')
629: rp++;
630: *rp = '\0';
631: if (rp >= rdvec + MR)
632: return(FAIL);
633: }
634: alarm(0);
635: return(0);
636: }
637:
638:
639: /***
640: * alarmtr() - catch alarm routine for "expect".
641: */
642:
643: alarmtr()
644: {
645: longjmp(Sjbuf, 1);
646: }
647:
648:
649: /***
650: * sendthem(str, fn) send line of login sequence
651: * char *str;
652: *
653: * return codes: none
654: */
655:
656: sendthem(str, fn)
657: char *str;
658: int fn;
659: {
660: int nw, ns;
661: int nulls;
662:
663: if (prefix("BREAK", str)) {
664: sscanf(&str[5], "%1d", &nulls);
665: if (nulls <= 0 || nulls > 10)
666: nulls = 3;
667: /* send break */
668: DEBUG(5, "%s,", str);
669: DEBUG(5, "%d\n", nulls);
670: genbrk(fn, nulls);
671: return;
672: }
673:
674: if (strcmp(str, "EOT") == SAME) {
675: write(fn, EOTMSG, strlen(EOTMSG));
676: return;
677: }
678: if (strcmp(str, "") != SAME) {
679: nw = write(fn, str, ns = strlen(str));
680: ASSERT(nw == ns, "BAD WRITE $s", str);
681: }
682: write(fn, "\n", 1);
683: return;
684: }
685:
686: #define BSPEED B150
687:
688: /***
689: * genbrk send a break
690: *
691: * return codes; none
692: */
693:
694: genbrk(fn, bnulls)
695: {
696: struct sgttyb ttbuf;
697: int ret, sospeed;
698:
699: ret = ioctl(fn, TIOCGETP, &ttbuf);
700: DEBUG(5, "ioctl ret %d\n", ret);
701: sospeed = ttbuf.sg_ospeed;
702: ttbuf.sg_ospeed = BSPEED;
703: ret = ioctl(fn, TIOCSETP, &ttbuf);
704: DEBUG(5, "ioctl ret %d\n", ret);
705: ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls);
706: ASSERT(ret > 0, "BAD WRITE genbrk %d", ret);
707: ttbuf.sg_ospeed = sospeed;
708: ret = ioctl(fn, TIOCSETP, &ttbuf);
709: ret = write(fn, "@", 1);
710: ASSERT(ret > 0, "BAD WRITE genbrk %d", ret);
711: DEBUG(4, "sent BREAK nulls - %d\n", bnulls);
712: return;
713: }
714:
715:
716: /***
717: * notin(sh, lg) check for occurrence of substring "sh"
718: * char *sh, *lg;
719: *
720: * return codes:
721: * 0 - found the string
722: * 1 - not in the string
723: */
724:
725: notin(sh, lg)
726: char *sh, *lg;
727: {
728: while (*lg != '\0') {
729: if (prefix(sh, lg))
730: return(0);
731: else
732: lg++;
733: }
734: return(1);
735: }
736:
737:
738: /*******
739: * ifdate(s)
740: * char *s;
741: *
742: * ifdate - this routine will check a string (s)
743: * like "MoTu0800-1730" to see if the present
744: * time is within the given limits.
745: *
746: * String alternatives:
747: * Wk - Mo thru Fr
748: * zero or one time means all day
749: * Any - any day
750: *
751: * return codes:
752: * 0 - not within limits
753: * 1 - within limits
754: */
755:
756: ifdate(s)
757: char *s;
758: {
759: static char *days[]={
760: "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
761: };
762: long clock;
763: int i, tl, th, tn, dayok=0;
764: struct tm *localtime();
765: struct tm *tp;
766:
767: time(&clock);
768: tp = localtime(&clock);
769: while (isalpha(*s)) {
770: for (i = 0; days[i]; i++) {
771: if (prefix(days[i], s))
772: if (tp->tm_wday == i)
773: dayok = 1;
774: }
775:
776: if (prefix("Wk", s))
777: if (tp->tm_wday >= 1 && tp->tm_wday <= 5)
778: dayok = 1;
779: if (prefix("Any", s))
780: dayok = 1;
781: s++;
782: }
783:
784: if (dayok == 0)
785: return(0);
786: i = sscanf(s, "%d-%d", &tl, &th);
787: tn = tp->tm_hour * 100 + tp->tm_min;
788: if (i < 2)
789: return(1);
790: if (tn >= tl && tn <= th)
791: return(1);
792: return(0);
793: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.