|
|
1.1 root 1: #include <sgtty.h>
2: #include <signal.h>
3: #include <errno.h>
4: #include <stdio.h>
5: #include <sys/types.h>
6: #include <sys/stat.h>
7: #include <pwd.h>
8: #include <ipc.h>
9: #include "defs.h"
10:
11: #define ACUFILE1 "/usr/lib/aculist"
12: #define ACUFILE "/etc/aculist"
13:
14: extern int logevent();
15: extern char *malloc();
16: static char *word();
17: static struct aculine *readacu();
18: static int sigalrm();
19: static int getspeed();
20: static int recordit();
21:
22: struct aculine {
23: char *class;
24: char *line;
25: char *acu;
26: char *speed;
27: char *prefix;
28: char *postfix;
29: };
30:
31: #define MONITOR
32: #define eq(x, y) (strcmp(x, y)==0)
33:
34: extern int dt_ld;
35: extern int tty_ld;
36: extern int buf_ld;
37:
38: /* dummy in-dial routines */
39: int
40: net_announce(ip)
41: ipcinfo *ip;
42: {
43: USE(ip);
44: return ABORT(EACCES, "cannot announce to tpc", NULLINFO);
45: }
46: ipcinfo *
47: net_listen(fd)
48: int fd;
49: {
50: USE(fd);
51: return NULL;
52: }
53: void
54: net_accept(ip)
55: ipcinfo *ip;
56: {
57: USE(ip);
58: return;
59: }
60: void
61: net_reject(ip, no, str)
62: ipcinfo *ip;
63: int no;
64: char *str;
65: {
66: USE((ip, no, str));
67: return;
68: }
69:
70: /* dial out on an acu */
71: int
72: net_dial(ip)
73: ipcinfo *ip;
74: {
75: char digits[30];
76: char *params[10];
77: int i, np;
78: register struct aculine *ap;
79: int pid, dh, retval, r, acu;
80: int (*sal)();
81: time_t starttime, time();
82:
83: sal = signal(SIGALRM, sigalrm);
84: alarm(0);
85: errno = -9;
86: errstr = "unknown service class";
87: ap = readacu();
88: if (ap == NULL)
89: return -1;
90: setfields(" \t");
91: np = getmfields(ip->param, params, 10);
92: for (; ap->class; ap++) {
93: #ifdef DEBUG
94: printf("class %s, line %s, acu %s, speed %s, prefix %s, postfix %s\n",
95: ap->class, ap->line, ap->acu, ap->speed, ap->prefix, ap->postfix);
96: #endif
97: for (i=0; i<np; i++) {
98: fprintf(stderr, "%s==%s?\n", ap->class, params[i]);
99: if(eq(ap->class, params[i]))
100: break;
101: }
102: if (i==np)
103: continue;
104: acu = -1;
105: if (eq(ap->acu, "none"))
106: goto noACU;
107: retval = -1; /* acu busy */
108: if (eq(ap->line, "DKVENTEL") || eq(ap->line, "DKACU")){
109: retval = tdkdialout(ap->acu, ip->name, ap->class);
110: if(retval >= 0)
111: break;
112: continue;
113: }
114: for (r=0; r<60; r += 3) {
115: acu = open(ap->acu, 1);
116: if (acu<0 && !eq(ap->prefix, "-")) {
117: sleep(3);
118: continue;
119: }
120: break;
121: }
122: if (acu < 0)
123: continue;
124: digits[0] = '\0';
125: if (!eq(ap->prefix, "-"))
126: strcpy(digits, ap->prefix);
127: strcat(digits, ip->name);
128: strcat(digits, ap->postfix);
129: if ((pid=fork())==0) {
130: alarm(60);
131: close(acu);
132: open(ap->line, 2);
133: exit(0);
134: }
135: alarm(20);
136: #ifdef DEBUG
137: printf("dial %s\n", digits);
138: #endif
139: r = write(acu, digits, strlen(digits));
140: #ifdef DEBUG
141: printf("wrote %d\n", r);
142: #endif
143: alarm(0);
144: close(acu);
145: if (r!=strlen(digits)) {
146: kill(pid, 9);
147: wait(0);
148: continue;
149: }
150: noACU:
151: alarm(60);
152: starttime = time(NULL);
153: retval = -3; /* no carrier */
154: dh = open(ap->line, 2);
155: #ifdef DEBUG
156: printf("open %s\n", ap->line);
157: #endif
158: alarm(0);
159: kill(pid, 9);
160: wait(0);
161: if (dh>=0) {
162: #ifdef DEBUG
163: printf("open succeeds\n");
164: #endif
165: retval = dh;
166: break;
167: }
168: close(acu); /* This compensates for a system bug. */
169: #ifdef DEBUG
170: printf("open failed\n");
171: #endif
172: if (time(NULL) > starttime+45) /* quit if timeout */
173: break;
174: }
175: ret:
176: errstr = "no carrier";
177: if (retval > 0) {
178: struct sgttyb vec;
179: struct ttydevb dvec;
180: int ld;
181:
182: ioctl(retval, FIOPUSHLD, &buf_ld);
183: ld = ioctl(retval, FIOLOOKLD, (char *)0);
184: if (ld != tty_ld)
185: ioctl(retval, FIOPUSHLD, &tty_ld);
186: ioctl(retval, TIOCGETP, &vec);
187: ioctl(retval, TIOCGDEV, &dvec);
188: vec.sg_flags &= ~ECHO;
189: dvec.flags &= ~ECHO;
190: vec.sg_flags |= RAW|EVENP|ODDP;
191: dvec.flags |= RAW|EVENP|ODDP;
192: dvec.ispeed = dvec.ospeed =
193: vec.sg_ispeed = vec.sg_ospeed = getspeed(ap->speed);
194: ioctl(retval, TIOCSETP, &vec);
195: ioctl(retval, TIOCHPCL, 0);
196: ioctl(retval, TIOCEXCL, 0);
197: if (vec.sg_ispeed == 0) {
198: close(retval);
199: retval = -3;
200: }
201: }
202: signal(SIGALRM, sal);
203: recordit(params[i], retval, ip);
204: return(retval);
205: }
206:
207: static
208: sigalrm()
209: {
210: signal(SIGALRM, sigalrm);
211: return;
212: }
213:
214: static struct aculine *
215: readacu()
216: {
217: char *ap;
218: int nline, i, f;
219: struct stat sb;
220: struct aculine *acp;
221:
222: if ((f = open(ACUFILE, 0)) < 0){
223: if((f = open(ACUFILE1, 0)) < 0){
224: errstr = "can't open acu";
225: return(NULL);
226: }
227: }
228: fstat(f, &sb);
229: ap = malloc(2*(unsigned short)sb.st_size);
230: if (ap == NULL) {
231: errstr = "out of memory";
232: return(NULL);
233: }
234: i = read(f, ap, (unsigned short)sb.st_size);
235: close(f);
236: if (i < 0)
237: i = 0;
238: ap[i] = '\0';
239: for (nline=0, i=0; ap[i]; i++)
240: if (ap[i] == '\n')
241: nline++;
242: acp = (struct aculine *)malloc(2*(nline+1)*sizeof(struct aculine));
243: if (acp == NULL) {
244: errstr = "out of memory";
245: return(NULL);
246: }
247: for (i=0; i<nline; i++) {
248: ap = word(ap, &acp[i].class, 1);
249: ap = word(ap, &acp[i].line, 0);
250: ap = word(ap, &acp[i].acu, 0);
251: ap = word(ap, &acp[i].speed, 0);
252: ap = word(ap, &acp[i].prefix, 0);
253: ap = word(ap, &acp[i].postfix, 0);
254: }
255: acp[nline].class = NULL;
256: *ap = '\0';
257:
258: return(acp);
259: }
260:
261: static char *
262: word(cp, loc, f)
263: register char *cp, **loc;
264: {
265: register char *bw;
266:
267: while (*cp == ' ' || *cp == '\t' || (*cp == '\n' && f))
268: *cp++ = '\0';
269: bw = cp;
270: while (*cp > ' ')
271: cp++;
272: *loc = bw;
273: return(cp);
274: }
275:
276: static
277: getspeed(sp)
278: char *sp;
279: {
280: switch(atoi(sp)) {
281:
282: case 50:
283: return(B50);
284: case 75:
285: return(B75);
286: case 110:
287: return(B110);
288: case 134:
289: return(B134);
290: case 150:
291: return(B150);
292: case 300:
293: return(B300);
294: case 600:
295: return(B600);
296: case 1200:
297: return(B1200);
298: case 1800:
299: return(B1800);
300: case 2400:
301: return(B2400);
302: case 4800:
303: return(B4800);
304: case 9600:
305: return(B9600);
306: default:
307: if (eq(sp, "exta"))
308: return(EXTA);
309: if (eq(sp, "extb"))
310: return(EXTB);
311: return(0);
312: }
313: }
314:
315: static
316: recordit(class, retval, ip)
317: char *class;
318: ipcinfo *ip;
319: {
320: FILE *fp;
321: long time();
322: long tm = time(0);
323:
324: fp = fopen("/usr/adm/smdr", "a");
325: if (fp == NULL)
326: return(0);
327: fprintf(fp, "%s %s %s %s!%s %.12s\n", ip->name, class, retval>=0?"OK":"NG",
328: ip->machine, ip->user, ctime(&tm)+4);
329: fclose(fp);
330: }
331:
332: #include <ctype.h>
333:
334: tdkdialout(addr, telno, dt)
335: char *addr;
336: char *telno, *dt;
337: {
338: char atelno[100];
339: char buf[100];
340: int fd, i;
341:
342: fprintf(stderr, "tdkdialout %s %s\n", addr, telno);
343: for(i = 0; telno[i]; i++){
344: if(telno[i] == '-'){
345: atelno[i] = '%';
346: } else if(telno[i] == '='){
347: atelno[i] = '%';
348: } else if(telno[i] == '+'){
349: atelno[i] = '&';
350: } else {
351: atelno[i] = telno[i];
352: }
353: }
354: atelno[i] = '\0';
355: if(dt[0] == 'C' && atelno[0] != '9' && atelno[0] != '8'){
356: /* C1200 or C300; ventel is on dimension, not centrex */
357: return(-9);
358: }
359: sprintf(buf, "/cs/dk!%s!%s", addr, atelno);
360: fd = ipcopen(buf, "");
361: if(fd < 0)
362: return(-3);
363: return(fd);
364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.