Initial import from FreeBSD RELENG_4:
[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  *
32  *      last edit-date: [Sat Jul 21 13:38:10 2001]
33  *
34  *---------------------------------------------------------------------------
35  *
36  * BEWARE: HIGHLY EXPERIMENTAL!
37  * ---------------------------
38  * 
39  * This program is used in conjunction with a isdnd.rc entry similar to
40  *
41  *  regexpr = "ULPPP.*call active"   # look for matches in log messages
42  *  regprog = i4brunppp              # execute program when match is found
43  *
44  * this one. It _must_ be put into /etc/isdn!
45  * When an active call is detected, isdnd fires off i4brunppp, which attaches
46  * the rbch device used to stdin/stdout and then runs ppp which is given the
47  * "-direct" command and the string "inc_rbchX" (where X is the i4brbch unit
48  * number) as arguments.
49  *
50  *---------------------------------------------------------------------------*/
51
52 #include <stdio.h>
53 #include <errno.h>
54 #include <unistd.h>
55 #include <fcntl.h>
56 #include <syslog.h>
57 #include <errno.h>
58 #include <string.h>
59 #include <time.h>
60 #include <ctype.h>
61
62 #include <machine/i4b_ioctl.h>
63 #include <machine/i4b_rbch_ioctl.h>
64
65 #define I4BDEVICE       "/dev/i4b"      
66
67 #define PPPPROG         "/usr/sbin/ppp"
68 #define PPPNAME         "ppp"
69 #define PPPARG1         "-direct"
70 #define PPPLABEL        "inc_"
71
72 #define VERIFYSTRING    "call active"
73 #define DEVSTRING       "rbch"
74
75 #define PPPDEBUG
76
77 /*---------------------------------------------------------------------------*
78  *      program entry
79  *---------------------------------------------------------------------------*/
80 int
81 main(int argc, char **argv)
82 {
83         char buffer[256];
84         int rbch_fd;
85         char *p = "DeadPointer";
86         int found;
87         int i;
88         
89 #ifdef PPPDEBUG
90         FILE *dfp;
91         time_t tim;
92         register struct tm *tp;
93 #endif
94         
95         /* open syslog */
96         
97         (void)openlog("i4brunppp", LOG_PID|LOG_CONS|LOG_NDELAY, LOG_USER);
98
99 #ifdef PPPDEBUG
100
101         /* open debug log */
102         
103         if((dfp = fopen("/tmp/i4brunppp-debug.log", "a")) == NULL)
104         {
105                 syslog(LOG_INFO, "cannot open logfile: %s", strerror(errno));
106                 exit(1);
107         }
108
109         tim = time(NULL);
110         tp = localtime(&tim);
111         strftime(buffer, 40, I4B_TIME_FORMAT, tp);
112         fprintf(dfp, "\n=================== %s ===================\n", buffer);
113
114         for(i=0; i < argc; i++)
115                 fprintf(dfp, "\t%s\n", argv[i]);
116 #endif
117
118         /* check if this is the right message */
119         
120         found = 0;
121         
122         for(i=0; i < argc; i++)
123         {
124                 if((strstr(argv[i], VERIFYSTRING)) != NULL)
125                 {
126                         found = 1;
127                         break;
128                 }
129         }
130
131         if(found == 0)
132         {
133 #ifdef PPPDEBUG
134                 fprintf(dfp, "did not found [%s], exit\n", VERIFYSTRING);
135 #endif
136                 exit(0);
137         }
138                 
139         found = 0;
140
141         /* check if we got a good device name */
142         
143         for(; i < argc; i++)
144         {
145                 if((p = strstr(argv[i], DEVSTRING)) != NULL)
146                 {
147                         found = 1;
148                         break;
149                 }
150         }
151
152         if(found == 0)
153         {
154 #ifdef PPPDEBUG
155                 fprintf(dfp, "did not found [%s], exit\n", DEVSTRING);
156 #endif
157                 exit(0);
158         }
159
160         /* everything ok, now prepare for running ppp */        
161
162         /* close all file descriptors */
163         
164         i = getdtablesize();
165
166         for(;i >= 0; i--)
167            if (i != 2)
168                 close(i);
169
170         /* fiddle a terminating zero after the rbch unit number */
171         
172         p += strlen(DEVSTRING);
173
174         if(isdigit(*p) && isdigit(*(p+1)))
175                 *(p+2) = '\0';
176         else
177                 *(p+1) = '\0';
178
179         /* construct /dev/i4brbchX device name */
180         
181         sprintf(buffer, "%s%s%s", I4BDEVICE, DEVSTRING, p);
182
183         /* open the rbch device as fd 0 = stdin */
184         
185         rbch_fd = open(buffer, O_RDWR);
186
187         if(rbch_fd != 0)
188         {
189                 if(rbch_fd < 0)         
190                         syslog(LOG_INFO, "cannot open %s: %s", buffer, strerror(errno));
191                 else
192                         syslog(LOG_INFO, "cannot open %s as fd 0 (is %d): %s", buffer, rbch_fd, strerror(errno));
193                 exit(1);
194         }
195
196         /* dup rbch device fd as fd 1 = stdout */
197         
198         if((i = dup(rbch_fd)) != 1)
199         {
200                 if(i < 0)               
201                         syslog(LOG_INFO, "cannot dup rbch_fd: %s", strerror(errno));
202                 else
203                         syslog(LOG_INFO, "cannot dup rbch as fd 1 (is %d): %s", i, strerror(errno));
204                 exit(1);
205         }
206
207         /* construct the label for ppp's ppp.conf file */
208         
209         sprintf(buffer, "%s%s%s", PPPLABEL, DEVSTRING, p);
210
211         syslog(LOG_INFO, "executing: %s %s %s %s", PPPPROG, PPPNAME, PPPARG1, buffer);
212
213         /* execute ppp */
214         
215         if((execl(PPPPROG, PPPNAME, PPPARG1, buffer, NULL)) == -1)
216         {
217                 syslog(LOG_INFO, "cannot exec: %s", strerror(errno));
218                 exit(1);
219         }
220         syslog(LOG_INFO, "finished: %s %s %s %s", PPPPROG, PPPNAME, PPPARG1, buffer);
221         return(0);
222 }
223
224 /* EOF */