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