Fix typo.
[dragonfly.git] / share / examples / isdn / i4brunppp / i4brunppp.c
1 /*
2  * Copyright (c) 1999, 2001 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4brunppp - run userland ppp for incoming call from rbch i/f
28  *      ------------------------------------------------------------
29  *
30  * $FreeBSD: src/share/examples/isdn/i4brunppp/i4brunppp.c,v 1.2.2.1 2001/08/12 01:57:09 obrien Exp $
31  * $DragonFly: src/share/examples/isdn/i4brunppp/i4brunppp.c,v 1.2 2003/06/17 04:36:57 dillon Exp $
32  *
33  *      last edit-date: [Sat Jul 21 13:38:10 2001]
34  *
35  *---------------------------------------------------------------------------
36  *
37  * BEWARE: HIGHLY EXPERIMENTAL!
38  * ---------------------------
39  * 
40  * This program is used in conjunction with a isdnd.rc entry similar to
41  *
42  *  regexpr = "ULPPP.*call active"   # look for matches in log messages
43  *  regprog = i4brunppp              # execute program when match is found
44  *
45  * this one. It _must_ be put into /etc/isdn!
46  * When an active call is detected, isdnd fires off i4brunppp, which attaches
47  * the rbch device used to stdin/stdout and then runs ppp which is given the
48  * "-direct" command and the string "inc_rbchX" (where X is the i4brbch unit
49  * number) as arguments.
50  *
51  *---------------------------------------------------------------------------*/
52
53 #include <stdio.h>
54 #include <errno.h>
55 #include <unistd.h>
56 #include <fcntl.h>
57 #include <syslog.h>
58 #include <errno.h>
59 #include <string.h>
60 #include <time.h>
61 #include <ctype.h>
62
63 #include <machine/i4b_ioctl.h>
64 #include <machine/i4b_rbch_ioctl.h>
65
66 #define I4BDEVICE       "/dev/i4b"      
67
68 #define PPPPROG         "/usr/sbin/ppp"
69 #define PPPNAME         "ppp"
70 #define PPPARG1         "-direct"
71 #define PPPLABEL        "inc_"
72
73 #define VERIFYSTRING    "call active"
74 #define DEVSTRING       "rbch"
75
76 #define PPPDEBUG
77
78 /*---------------------------------------------------------------------------*
79  *      program entry
80  *---------------------------------------------------------------------------*/
81 int
82 main(int argc, char **argv)
83 {
84         char buffer[256];
85         int rbch_fd;
86         char *p = "DeadPointer";
87         int found;
88         int i;
89         
90 #ifdef PPPDEBUG
91         FILE *dfp;
92         time_t tim;
93         register struct tm *tp;
94 #endif
95         
96         /* open syslog */
97         
98         (void)openlog("i4brunppp", LOG_PID|LOG_CONS|LOG_NDELAY, LOG_USER);
99
100 #ifdef PPPDEBUG
101
102         /* open debug log */
103         
104         if((dfp = fopen("/tmp/i4brunppp-debug.log", "a")) == NULL)
105         {
106                 syslog(LOG_INFO, "cannot open logfile: %s", strerror(errno));
107                 exit(1);
108         }
109
110         tim = time(NULL);
111         tp = localtime(&tim);
112         strftime(buffer, 40, I4B_TIME_FORMAT, tp);
113         fprintf(dfp, "\n=================== %s ===================\n", buffer);
114
115         for(i=0; i < argc; i++)
116                 fprintf(dfp, "\t%s\n", argv[i]);
117 #endif
118
119         /* check if this is the right message */
120         
121         found = 0;
122         
123         for(i=0; i < argc; i++)
124         {
125                 if((strstr(argv[i], VERIFYSTRING)) != NULL)
126                 {
127                         found = 1;
128                         break;
129                 }
130         }
131
132         if(found == 0)
133         {
134 #ifdef PPPDEBUG
135                 fprintf(dfp, "did not found [%s], exit\n", VERIFYSTRING);
136 #endif
137                 exit(0);
138         }
139                 
140         found = 0;
141
142         /* check if we got a good device name */
143         
144         for(; i < argc; i++)
145         {
146                 if((p = strstr(argv[i], DEVSTRING)) != NULL)
147                 {
148                         found = 1;
149                         break;
150                 }
151         }
152
153         if(found == 0)
154         {
155 #ifdef PPPDEBUG
156                 fprintf(dfp, "did not found [%s], exit\n", DEVSTRING);
157 #endif
158                 exit(0);
159         }
160
161         /* everything ok, now prepare for running ppp */        
162
163         /* close all file descriptors */
164         
165         i = getdtablesize();
166
167         for(;i >= 0; i--)
168            if (i != 2)
169                 close(i);
170
171         /* fiddle a terminating zero after the rbch unit number */
172         
173         p += strlen(DEVSTRING);
174
175         if(isdigit(*p) && isdigit(*(p+1)))
176                 *(p+2) = '\0';
177         else
178                 *(p+1) = '\0';
179
180         /* construct /dev/i4brbchX device name */
181         
182         sprintf(buffer, "%s%s%s", I4BDEVICE, DEVSTRING, p);
183
184         /* open the rbch device as fd 0 = stdin */
185         
186         rbch_fd = open(buffer, O_RDWR);
187
188         if(rbch_fd != 0)
189         {
190                 if(rbch_fd < 0)         
191                         syslog(LOG_INFO, "cannot open %s: %s", buffer, strerror(errno));
192                 else
193                         syslog(LOG_INFO, "cannot open %s as fd 0 (is %d): %s", buffer, rbch_fd, strerror(errno));
194                 exit(1);
195         }
196
197         /* dup rbch device fd as fd 1 = stdout */
198         
199         if((i = dup(rbch_fd)) != 1)
200         {
201                 if(i < 0)               
202                         syslog(LOG_INFO, "cannot dup rbch_fd: %s", strerror(errno));
203                 else
204                         syslog(LOG_INFO, "cannot dup rbch as fd 1 (is %d): %s", i, strerror(errno));
205                 exit(1);
206         }
207
208         /* construct the label for ppp's ppp.conf file */
209         
210         sprintf(buffer, "%s%s%s", PPPLABEL, DEVSTRING, p);
211
212         syslog(LOG_INFO, "executing: %s %s %s %s", PPPPROG, PPPNAME, PPPARG1, buffer);
213
214         /* execute ppp */
215         
216         if((execl(PPPPROG, PPPNAME, PPPARG1, buffer, NULL)) == -1)
217         {
218                 syslog(LOG_INFO, "cannot exec: %s", strerror(errno));
219                 exit(1);
220         }
221         syslog(LOG_INFO, "finished: %s %s %s %s", PPPPROG, PPPNAME, PPPARG1, buffer);
222         return(0);
223 }
224
225 /* EOF */