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