2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 *---------------------------------------------------------------------------
27 * i4b daemon - config file processing
28 * -----------------------------------
30 * $Id: rc_config.c,v 1.25 2009/04/16 05:56:32 lukem Exp $
34 * last edit-date: [Sat Jan 6 12:57:36 2001]
36 *---------------------------------------------------------------------------*/
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
43 #include <sys/callout.h>
44 #include <sys/ioctl.h>
56 extern int yyparse(void);
58 static void set_config_defaults(void);
59 static void check_config(void);
60 static void print_config(void);
61 static void parse_valid(char *dt
);
62 static int lookup_l4_driver(const char *name
);
63 void init_currrent_cfg_state(void);
64 static void set_isppp_auth(struct cfg_entry
*);
65 static void set_autoupdown(struct cfg_entry
*);
66 void flush_config(void);
68 static int nregexpr
= 0;
69 static int nregprog
= 0;
70 static struct cfg_entry
* current_cfe
= NULL
;
71 struct isdn_ctrl_state
* cur_ctrl
= NULL
;
73 /*---------------------------------------------------------------------------*
74 * called from main to read and process config file
75 *---------------------------------------------------------------------------*/
77 configure(const char *filename
, int reread
)
79 extern void reset_scanner(FILE *inputfile
);
81 set_config_defaults();
83 yyin
= fopen(filename
, "r");
93 logit(LL_ERR
, "cannot fopen file [%s]", filename
);
99 monitor_fixup_rights();
101 check_config(); /* validation and consistency check */
107 if (config_error_flag
)
109 logit(LL_ERR
, "there were %d error(s) in the configuration file, terminating!", config_error_flag
);
117 /*---------------------------------------------------------------------------*
119 *---------------------------------------------------------------------------*/
121 yyerror(const char *msg
)
123 logit(LL_ERR
, "configuration error: %s at line %d, token \"%s\"", msg
, lineno
+1, yytext
);
128 * Prepare a new default entry
131 init_currrent_cfg_state()
133 if (current_cfe
!= NULL
) {
134 add_cfg_entry(current_cfe
);
136 current_cfe
= malloc(sizeof(struct cfg_entry
));
137 memset(current_cfe
, 0, sizeof(struct cfg_entry
));
139 current_cfe
->isdncontroller
= INVALID
;
140 current_cfe
->isdnchannel
= CHAN_ANY
;
141 current_cfe
->usrdevice
= INVALID
;
142 current_cfe
->usrdeviceunit
= INVALID
;
143 current_cfe
->remote_numbers_handling
= RNH_LAST
;
144 current_cfe
->dialin_reaction
= REACT_IGNORE
;
145 current_cfe
->b1protocol
= BPROT_NONE
;
146 current_cfe
->unitlength
= UNITLENGTH_DEFAULT
;
147 current_cfe
->earlyhangup
= EARLYHANGUP_DEFAULT
;
148 current_cfe
->ratetype
= INVALID_RATE
;
149 current_cfe
->unitlengthsrc
= ULSRC_NONE
;
150 current_cfe
->answerprog
= ANSWERPROG_DEF
;
151 current_cfe
->callbackwait
= CALLBACKWAIT_MIN
;
152 current_cfe
->calledbackwait
= CALLEDBACKWAIT_MIN
;
153 current_cfe
->dialretries
= DIALRETRIES_DEF
;
154 current_cfe
->recoverytime
= RECOVERYTIME_MIN
;
155 current_cfe
->dialouttype
= DIALOUT_NORMAL
;
156 current_cfe
->inout
= DIR_INOUT
;
157 current_cfe
->ppp_expect_auth
= AUTH_UNDEF
;
158 current_cfe
->ppp_send_auth
= AUTH_UNDEF
;
159 current_cfe
->ppp_auth_flags
= AUTH_RECHALLENGE
| AUTH_REQUIRED
;
160 current_cfe
->cdid
= CDID_UNUSED
;
161 current_cfe
->state
= ST_IDLE
;
162 current_cfe
->aoc_valid
= AOC_INVALID
;
163 current_cfe
->autoupdown
= AUTOUPDOWN_YES
;
166 /*---------------------------------------------------------------------------*
167 * fill all config entries with default values
168 *---------------------------------------------------------------------------*/
170 set_config_defaults(void)
174 /* system section cleanup */
176 nregprog
= nregexpr
= 0;
178 rt_prio
= RTPRIO_NOTUSED
;
183 /* clean regular expression table */
185 for (i
=0; i
< MAX_RE
; i
++)
188 free(rarr
[i
].re_expr
);
189 rarr
[i
].re_expr
= NULL
;
192 free(rarr
[i
].re_prog
);
193 rarr
[i
].re_prog
= NULL
;
198 strlcpy(rotatesuffix
, "", sizeof(rotatesuffix
));
202 set_autoupdown(struct cfg_entry
*cep
)
204 struct ifaddrs
*res
= NULL
, *p
;
208 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
209 memset(&ifr
, 0, sizeof ifr
);
210 snprintf(ifr
.ifr_name
, sizeof ifr
.ifr_name
, "%s%d", cep
->usrdevicename
, cep
->usrdeviceunit
);
211 r
= ioctl(s
, SIOCGIFFLAGS
, &ifr
);
214 * See if this interface has got any valid addresses - if not,
217 if (r
>= 0 && !(ifr
.ifr_flags
& IFF_UP
)) {
219 if (getifaddrs(&res
) == 0) {
220 for (p
= res
; p
; p
= p
->ifa_next
) {
221 if (p
->ifa_addr
== NULL
)
223 if (p
->ifa_addr
->sa_family
== AF_LINK
)
225 if (strcmp(p
->ifa_name
, ifr
.ifr_name
) != 0)
227 if (p
->ifa_addr
->sa_family
== AF_INET6
)
235 cnt
--; /* XXX - heuristic to adjust for INET6 local scope */
237 /* Ok, we have some addres - so UP the interface */
239 ifr
.ifr_flags
|= IFF_UP
;
240 r
= ioctl(s
, SIOCSIFFLAGS
, &ifr
);
242 cep
->autoupdown
|= AUTOUPDOWN_DONE
;
250 set_isppp_auth(struct cfg_entry
*cep
)
252 struct spppauthcfg spcfg
;
256 if (cep
->ppp_expect_auth
== AUTH_UNDEF
257 && cep
->ppp_send_auth
== AUTH_UNDEF
)
260 if (cep
->ppp_expect_auth
== AUTH_NONE
261 || cep
->ppp_send_auth
== AUTH_NONE
)
264 if ((cep
->ppp_expect_auth
== AUTH_CHAP
265 || cep
->ppp_expect_auth
== AUTH_PAP
)
266 && cep
->ppp_expect_name
!= NULL
267 && cep
->ppp_expect_password
!= NULL
)
270 if ((cep
->ppp_send_auth
== AUTH_CHAP
|| cep
->ppp_send_auth
== AUTH_PAP
)
271 && cep
->ppp_send_name
!= NULL
272 && cep
->ppp_send_password
!= NULL
)
278 memset(&spcfg
, 0, sizeof spcfg
);
279 snprintf(spcfg
.ifname
, sizeof(spcfg
.ifname
), "%s%d",
280 cep
->usrdevicename
, cep
->usrdeviceunit
);
282 /* use a random AF to create the socket */
283 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
284 logit(LL_ERR
, "ERROR opening control socket at line %d!", lineno
);
289 if (ioctl(s
, SPPPGETAUTHCFG
, &spcfg
) == -1) {
290 logit(LL_ERR
, "ERROR fetching active PPP authentication info for %s at line %d!", spcfg
.ifname
, lineno
);
295 if (cep
->ppp_expect_auth
!= AUTH_UNDEF
)
297 if (cep
->ppp_expect_auth
== AUTH_NONE
)
299 spcfg
.hisauth
= SPPP_AUTHPROTO_NONE
;
301 else if ((cep
->ppp_expect_auth
== AUTH_CHAP
302 || cep
->ppp_expect_auth
== AUTH_PAP
)
303 && cep
->ppp_expect_name
!= NULL
304 && cep
->ppp_expect_password
!= NULL
)
306 spcfg
.hisauth
= cep
->ppp_expect_auth
== AUTH_PAP
? SPPP_AUTHPROTO_PAP
: SPPP_AUTHPROTO_CHAP
;
307 spcfg
.hisname
= cep
->ppp_expect_name
;
308 spcfg
.hisname_length
= strlen(cep
->ppp_expect_name
)+1;
309 spcfg
.hissecret
= cep
->ppp_expect_password
;
310 spcfg
.hissecret_length
= strlen(cep
->ppp_expect_password
)+1;
313 if (cep
->ppp_send_auth
!= AUTH_UNDEF
)
315 if (cep
->ppp_send_auth
== AUTH_NONE
)
317 spcfg
.myauth
= SPPP_AUTHPROTO_NONE
;
319 else if ((cep
->ppp_send_auth
== AUTH_CHAP
320 || cep
->ppp_send_auth
== AUTH_PAP
)
321 && cep
->ppp_send_name
!= NULL
322 && cep
->ppp_send_password
!= NULL
)
324 spcfg
.myauth
= cep
->ppp_send_auth
== AUTH_PAP
? SPPP_AUTHPROTO_PAP
: SPPP_AUTHPROTO_CHAP
;
325 spcfg
.myname
= cep
->ppp_send_name
;
326 spcfg
.myname_length
= strlen(cep
->ppp_send_name
)+1;
327 spcfg
.mysecret
= cep
->ppp_send_password
;
328 spcfg
.mysecret_length
= strlen(cep
->ppp_send_password
)+1;
330 if (cep
->ppp_auth_flags
& AUTH_REQUIRED
)
331 spcfg
.hisauthflags
&= ~SPPP_AUTHFLAG_NOCALLOUT
;
333 spcfg
.hisauthflags
|= SPPP_AUTHFLAG_NOCALLOUT
;
335 if (cep
->ppp_auth_flags
& AUTH_RECHALLENGE
)
336 spcfg
.hisauthflags
&= ~SPPP_AUTHFLAG_NORECHALLENGE
;
338 spcfg
.hisauthflags
|= SPPP_AUTHFLAG_NORECHALLENGE
;
342 if (ioctl(s
, SPPPSETAUTHCFG
, &spcfg
) == -1) {
343 logit(LL_ERR
, "ERROR setting new PPP authentication parameters for %s at line %d!", spcfg
.ifname
, lineno
);
349 /*---------------------------------------------------------------------------*
350 * extract values from config and fill table
351 *---------------------------------------------------------------------------*/
353 cfg_setval(int keyword
)
360 acct_all
= yylval
.booln
;
361 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: acctall = %d", yylval
.booln
)));
365 strlcpy(acctfile
, yylval
.str
, sizeof(acctfile
));
366 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: acctfile = %s", yylval
.str
)));
370 if (yylval
.num
< MINALERT
)
372 yylval
.num
= MINALERT
;
373 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: alert < %d, min = %d", current_cfe
->name
, MINALERT
, yylval
.num
)));
375 else if (yylval
.num
> MAXALERT
)
377 yylval
.num
= MAXALERT
;
378 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: alert > %d, min = %d", current_cfe
->name
, MAXALERT
, yylval
.num
)));
381 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: alert = %d", current_cfe
->name
, yylval
.num
)));
382 current_cfe
->alert
= yylval
.num
;
386 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: aliasing = %d", yylval
.booln
)));
387 aliasing
= yylval
.booln
;
391 strlcpy(aliasfile
, yylval
.str
, sizeof(aliasfile
));
392 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: aliasfile = %s", yylval
.str
)));
396 if ((current_cfe
->answerprog
= strdup(yylval
.str
)) == NULL
)
398 logit(LL_ERR
, "entry %s: answerstring, malloc failed!", current_cfe
->name
);
401 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: answerprog = %s", current_cfe
->name
, yylval
.str
)));
405 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: b1protocol = %s", current_cfe
->name
, yylval
.str
)));
406 if (!(strcmp(yylval
.str
, "raw")))
407 current_cfe
->b1protocol
= BPROT_NONE
;
408 else if (!(strcmp(yylval
.str
, "hdlc")))
409 current_cfe
->b1protocol
= BPROT_RHDLC
;
412 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"b1protocol\" at line %d!", lineno
);
418 do_bell
= yylval
.booln
;
419 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: beepconnect = %d", yylval
.booln
)));
422 case BUDGETCALLBACKPERIOD
:
423 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-callbackperiod = %d", current_cfe
->name
, yylval
.num
)));
424 current_cfe
->budget_callbackperiod
= yylval
.num
;
427 case BUDGETCALLBACKNCALLS
:
428 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-callbackncalls = %d", current_cfe
->name
, yylval
.num
)));
429 current_cfe
->budget_callbackncalls
= yylval
.num
;
432 case BUDGETCALLOUTPERIOD
:
433 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-calloutperiod = %d", current_cfe
->name
, yylval
.num
)));
434 current_cfe
->budget_calloutperiod
= yylval
.num
;
437 case BUDGETCALLOUTNCALLS
:
438 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-calloutncalls = %d", current_cfe
->name
, yylval
.num
)));
439 current_cfe
->budget_calloutncalls
= yylval
.num
;
443 current_cfe
->autoupdown
= yylval
.booln
;
444 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: autoupdown = %d", current_cfe
->name
, yylval
.booln
)));
447 case BUDGETCALLBACKSFILEROTATE
:
448 current_cfe
->budget_callbacksfile_rotate
= yylval
.booln
;
449 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-callbacksfile-rotate = %d", current_cfe
->name
, yylval
.booln
)));
452 case BUDGETCALLBACKSFILE
:
457 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-callbacksfile = %s", yylval
.str
)));
458 fp
= fopen(yylval
.str
, "r");
461 if ((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) != 3)
463 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %d: initializing budget-callbacksfile %s", current_cfe
->name
, yylval
.str
)));
465 fp
= fopen(yylval
.str
, "w");
467 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
475 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: creating budget-callbacksfile %s", current_cfe
->name
, yylval
.str
)));
476 fp
= fopen(yylval
.str
, "w");
478 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
482 fp
= fopen(yylval
.str
, "r");
485 if ((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) == 3)
487 if ((current_cfe
->budget_callbacks_file
= strdup(yylval
.str
)) == NULL
)
489 logit(LL_ERR
, "entry %s: budget-callbacksfile, malloc failed!", current_cfe
->name
);
492 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: using callbacksfile %s", current_cfe
->name
, yylval
.str
)));
499 case BUDGETCALLOUTSFILEROTATE
:
500 current_cfe
->budget_calloutsfile_rotate
= yylval
.booln
;
501 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-calloutsfile-rotate = %d", current_cfe
->name
, yylval
.booln
)));
504 case BUDGETCALLOUTSFILE
:
509 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: budget-calloutsfile = %s", current_cfe
->name
, yylval
.str
)));
510 fp
= fopen(yylval
.str
, "r");
513 if ((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) != 3)
515 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: initializing budget-calloutsfile %s", current_cfe
->name
, yylval
.str
)));
517 fp
= fopen(yylval
.str
, "w");
519 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
525 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: creating budget-calloutsfile %s", current_cfe
->name
, yylval
.str
)));
526 fp
= fopen(yylval
.str
, "w");
528 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
532 fp
= fopen(yylval
.str
, "r");
535 if ((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) == 3)
537 if ((current_cfe
->budget_callouts_file
= strdup(yylval
.str
)) == NULL
)
539 logit(LL_ERR
, "entry %s: budget-calloutsfile, malloc failed!", current_cfe
->name
);
542 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: using calloutsfile %s", current_cfe
->name
, yylval
.str
)));
550 if (yylval
.num
< CALLBACKWAIT_MIN
)
552 yylval
.num
= CALLBACKWAIT_MIN
;
553 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: callbackwait < %d, min = %d", current_cfe
->name
, CALLBACKWAIT_MIN
, yylval
.num
)));
556 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: callbackwait = %d", current_cfe
->name
, yylval
.num
)));
557 current_cfe
->callbackwait
= yylval
.num
;
561 if (yylval
.num
< CALLEDBACKWAIT_MIN
)
563 yylval
.num
= CALLEDBACKWAIT_MIN
;
564 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: calledbackwait < %d, min = %d", current_cfe
->name
, CALLEDBACKWAIT_MIN
, yylval
.num
)));
567 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: calledbackwait = %d", current_cfe
->name
, yylval
.num
)));
568 current_cfe
->calledbackwait
= yylval
.num
;
572 if ((current_cfe
->connectprog
= strdup(yylval
.str
)) == NULL
)
574 logit(LL_ERR
, "entry %s: connectprog, malloc failed!", current_cfe
->name
);
577 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: connectprog = %s", current_cfe
->name
, yylval
.str
)));
581 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: dialouttype = %s", current_cfe
->name
, yylval
.str
)));
582 if (!(strcmp(yylval
.str
, "normal")))
583 current_cfe
->dialouttype
= DIALOUT_NORMAL
;
584 else if (!(strcmp(yylval
.str
, "calledback")))
585 current_cfe
->dialouttype
= DIALOUT_CALLEDBACK
;
588 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"dialout-type\" at line %d!", lineno
);
594 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: dialretries = %d", current_cfe
->name
, yylval
.num
)));
595 current_cfe
->dialretries
= yylval
.num
;
599 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: dialrandincr = %d", current_cfe
->name
, yylval
.booln
)));
600 current_cfe
->dialrandincr
= yylval
.booln
;
604 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: direction = %s", current_cfe
->name
, yylval
.str
)));
606 if (!(strcmp(yylval
.str
, "inout")))
607 current_cfe
->inout
= DIR_INOUT
;
608 else if (!(strcmp(yylval
.str
, "in")))
609 current_cfe
->inout
= DIR_INONLY
;
610 else if (!(strcmp(yylval
.str
, "out")))
611 current_cfe
->inout
= DIR_OUTONLY
;
614 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"direction\" at line %d!", lineno
);
620 if ((current_cfe
->disconnectprog
= strdup(yylval
.str
)) == NULL
)
622 logit(LL_ERR
, "entry %s: disconnectprog, malloc failed!", current_cfe
->name
);
625 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: disconnectprog = %s", current_cfe
->name
, yylval
.str
)));
629 if (yylval
.num
> DOWN_TRIES_MAX
)
630 yylval
.num
= DOWN_TRIES_MAX
;
631 else if (yylval
.num
< DOWN_TRIES_MIN
)
632 yylval
.num
= DOWN_TRIES_MIN
;
634 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: downtries = %d", current_cfe
->name
, yylval
.num
)));
635 current_cfe
->downtries
= yylval
.num
;
639 if (yylval
.num
> DOWN_TIME_MAX
)
640 yylval
.num
= DOWN_TIME_MAX
;
641 else if (yylval
.num
< DOWN_TIME_MIN
)
642 yylval
.num
= DOWN_TIME_MIN
;
644 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: downtime = %d", current_cfe
->name
, yylval
.num
)));
645 current_cfe
->downtime
= yylval
.num
;
649 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: earlyhangup = %d", current_cfe
->name
, yylval
.num
)));
650 current_cfe
->earlyhangup
= yylval
.num
;
654 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: extcallattr = %d", yylval
.booln
)));
655 extcallattr
= yylval
.booln
;
659 DBGL(DL_RCCF
, (logit(LL_DBG
, "controller %d: firmware = %s", cur_ctrl
->isdnif
, yylval
.str
)));
660 cur_ctrl
->firmware
= strdup(yylval
.str
);
664 strlcpy(holidayfile
, yylval
.str
, sizeof(holidayfile
));
665 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: holidayfile = %s", yylval
.str
)));
669 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: idle-algorithm-outgoing = %s", current_cfe
->name
, yylval
.str
)));
671 if (!(strcmp(yylval
.str
, "fix-unit-size")))
673 current_cfe
->shorthold_algorithm
= SHA_FIXU
;
675 else if (!(strcmp(yylval
.str
, "var-unit-size")))
677 current_cfe
->shorthold_algorithm
= SHA_VARU
;
681 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"idle-algorithm-outgoing\" at line %d!", lineno
);
687 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: idle_time_in = %d", current_cfe
->name
, yylval
.num
)));
688 current_cfe
->idle_time_in
= yylval
.num
;
692 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: idle_time_out = %d", current_cfe
->name
, yylval
.num
)));
693 current_cfe
->idle_time_out
= yylval
.num
;
697 current_cfe
->isdncontroller
= yylval
.num
;
698 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: isdncontroller = %d", current_cfe
->name
, yylval
.num
)));
702 if (yylval
.num
== 0 || yylval
.num
== -1) {
703 current_cfe
->isdnchannel
= CHAN_ANY
;
704 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: isdnchannel = any", current_cfe
->name
)));
705 } else if (yylval
.num
> MAX_BCHAN
) {
706 logit(LL_DBG
, "entry %s: isdnchannel value out of range", current_cfe
->name
);
709 current_cfe
->isdnchannel
= yylval
.num
- 1;
710 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: isdnchannel = %d", current_cfe
->name
, yylval
.num
)));
715 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: isdntime = %d", yylval
.booln
)));
716 isdntime
= yylval
.booln
;
720 current_cfe
->isdntxdelin
= yylval
.num
;
721 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: isdntxdel-incoming = %d", current_cfe
->name
, yylval
.num
)));
725 current_cfe
->isdntxdelout
= yylval
.num
;
726 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: isdntxdel-outgoing = %d", current_cfe
->name
, yylval
.num
)));
729 case LOCAL_PHONE_DIALOUT
:
730 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: local_phone_dialout = %s", current_cfe
->name
, yylval
.str
)));
731 strlcpy(current_cfe
->local_phone_dialout
, yylval
.str
,
732 sizeof(current_cfe
->local_phone_dialout
));
735 case LOCAL_PHONE_INCOMING
:
736 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: local_phone_incoming = %s", current_cfe
->name
, yylval
.str
)));
737 strlcpy(current_cfe
->local_phone_incoming
, yylval
.str
,
738 sizeof(current_cfe
->local_phone_incoming
));
742 strlcpy(mailer
, yylval
.str
, sizeof(mailer
));
743 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: mailer = %s", yylval
.str
)));
747 strlcpy(mailto
, yylval
.str
, sizeof(mailto
));
748 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: mailto = %s", yylval
.str
)));
752 monitorport
= yylval
.num
;
753 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: monitorport = %d", yylval
.num
)));
757 if (yylval
.booln
&& inhibit_monitor
)
760 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: monitor-enable overriden by command line flag")));
764 do_monitor
= yylval
.booln
;
765 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: monitor-enable = %d", yylval
.booln
)));
770 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: name = %s", current_cfe
->name
, yylval
.str
)));
771 strlcpy(current_cfe
->name
, yylval
.str
,
772 sizeof(current_cfe
->name
));
775 case PPP_AUTH_RECHALLENGE
:
776 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-auth-rechallenge = %d", current_cfe
->name
, yylval
.booln
)));
778 current_cfe
->ppp_auth_flags
|= AUTH_RECHALLENGE
;
780 current_cfe
->ppp_auth_flags
&= ~AUTH_RECHALLENGE
;
783 case PPP_AUTH_PARANOID
:
784 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-auth-paranoid = %d", current_cfe
->name
, yylval
.booln
)));
786 current_cfe
->ppp_auth_flags
|= AUTH_REQUIRED
;
788 current_cfe
->ppp_auth_flags
&= ~AUTH_REQUIRED
;
791 case PPP_EXPECT_AUTH
:
792 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-expect-auth = %s", current_cfe
->name
, yylval
.str
)));
793 if (!(strcmp(yylval
.str
, "none")))
794 current_cfe
->ppp_expect_auth
= AUTH_NONE
;
795 else if (!(strcmp(yylval
.str
, "pap")))
796 current_cfe
->ppp_expect_auth
= AUTH_PAP
;
797 else if (!(strcmp(yylval
.str
, "chap")))
798 current_cfe
->ppp_expect_auth
= AUTH_CHAP
;
801 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"ppp-expect-auth\" at line %d!", lineno
);
807 case PPP_EXPECT_NAME
:
808 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-expect-name = %s", current_cfe
->name
, yylval
.str
)));
809 if (current_cfe
->ppp_expect_name
)
810 free(current_cfe
->ppp_expect_name
);
811 current_cfe
->ppp_expect_name
= strdup(yylval
.str
);
814 case PPP_EXPECT_PASSWORD
:
815 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-expect-password = %s", current_cfe
->name
, yylval
.str
)));
816 if (current_cfe
->ppp_expect_password
)
817 free(current_cfe
->ppp_expect_password
);
818 current_cfe
->ppp_expect_password
= strdup(yylval
.str
);
822 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-send-auth = %s", current_cfe
->name
, yylval
.str
)));
823 if (!(strcmp(yylval
.str
, "none")))
824 current_cfe
->ppp_send_auth
= AUTH_NONE
;
825 else if (!(strcmp(yylval
.str
, "pap")))
826 current_cfe
->ppp_send_auth
= AUTH_PAP
;
827 else if (!(strcmp(yylval
.str
, "chap")))
828 current_cfe
->ppp_send_auth
= AUTH_CHAP
;
831 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"ppp-send-auth\" at line %d!", lineno
);
838 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-send-name = %s", current_cfe
->name
, yylval
.str
)));
839 if (current_cfe
->ppp_send_name
)
840 free(current_cfe
->ppp_send_name
);
841 current_cfe
->ppp_send_name
= strdup(yylval
.str
);
844 case PPP_SEND_PASSWORD
:
845 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ppp-send-password = %s", current_cfe
->name
, yylval
.str
)));
846 if (current_cfe
->ppp_send_password
)
847 free(current_cfe
->ppp_send_password
);
848 current_cfe
->ppp_send_password
= strdup(yylval
.str
);
852 DBGL(DL_RCCF
, (logit(LL_DBG
, "controller %d: protocol = %s", cur_ctrl
->isdnif
, yylval
.str
)));
853 if (!(strcmp(yylval
.str
, "dss1")))
854 cur_ctrl
->protocol
= PROTOCOL_DSS1
;
855 else if (!(strcmp(yylval
.str
, "d64s")))
856 cur_ctrl
->protocol
= PROTOCOL_D64S
;
859 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"protocol\" at line %d!", lineno
);
865 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: dialin_reaction = %s", current_cfe
->name
, yylval
.str
)));
866 if (!(strcmp(yylval
.str
, "accept")))
867 current_cfe
->dialin_reaction
= REACT_ACCEPT
;
868 else if (!(strcmp(yylval
.str
, "reject")))
869 current_cfe
->dialin_reaction
= REACT_REJECT
;
870 else if (!(strcmp(yylval
.str
, "ignore")))
871 current_cfe
->dialin_reaction
= REACT_IGNORE
;
872 else if (!(strcmp(yylval
.str
, "answer")))
873 current_cfe
->dialin_reaction
= REACT_ANSWER
;
874 else if (!(strcmp(yylval
.str
, "callback")))
875 current_cfe
->dialin_reaction
= REACT_CALLBACK
;
878 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"dialin_reaction\" at line %d!", lineno
);
883 case REMOTE_PHONE_DIALOUT
:
884 if (current_cfe
->remote_numbers_count
>= MAXRNUMBERS
)
886 logit(LL_ERR
, "ERROR parsing config file: too many remote numbers at line %d!", lineno
);
891 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: remote_phone_dialout #%d = %s",
892 current_cfe
->name
, current_cfe
->remote_numbers_count
, yylval
.str
)));
894 strlcpy(current_cfe
->remote_numbers
[current_cfe
->remote_numbers_count
].number
,
896 sizeof(current_cfe
->remote_numbers
[current_cfe
->remote_numbers_count
].number
));
897 current_cfe
->remote_numbers
[current_cfe
->remote_numbers_count
].flag
= 0;
899 current_cfe
->remote_numbers_count
++;
903 case REMOTE_NUMBERS_HANDLING
:
904 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: remdial_handling = %s", current_cfe
->name
, yylval
.str
)));
905 if (!(strcmp(yylval
.str
, "next")))
906 current_cfe
->remote_numbers_handling
= RNH_NEXT
;
907 else if (!(strcmp(yylval
.str
, "last")))
908 current_cfe
->remote_numbers_handling
= RNH_LAST
;
909 else if (!(strcmp(yylval
.str
, "first")))
910 current_cfe
->remote_numbers_handling
= RNH_FIRST
;
913 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"remdial_handling\" at line %d!", lineno
);
918 case REMOTE_PHONE_INCOMING
:
921 n
= current_cfe
->incoming_numbers_count
;
922 if (n
>= MAX_INCOMING
)
924 logit(LL_ERR
, "ERROR parsing config file: too many \"remote_phone_incoming\" entries at line %d!", lineno
);
928 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: remote_phone_incoming #%d = %s", current_cfe
->name
, n
, yylval
.str
)));
929 strlcpy(current_cfe
->remote_phone_incoming
[n
].number
,
931 sizeof(current_cfe
->remote_phone_incoming
[n
].number
));
932 current_cfe
->incoming_numbers_count
++;
937 strlcpy(ratesfile
, yylval
.str
, sizeof(ratesfile
));
938 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: ratesfile = %s", yylval
.str
)));
942 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: ratetype = %d", current_cfe
->name
, yylval
.num
)));
943 current_cfe
->ratetype
= yylval
.num
;
947 if (yylval
.num
< RECOVERYTIME_MIN
)
949 yylval
.num
= RECOVERYTIME_MIN
;
950 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: recoverytime < %d, min = %d", current_cfe
->name
, RECOVERYTIME_MIN
, yylval
.num
)));
953 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: recoverytime = %d", current_cfe
->name
, yylval
.num
)));
954 current_cfe
->recoverytime
= yylval
.num
;
958 if (nregexpr
>= MAX_RE
)
960 logit(LL_ERR
, "system: regexpr #%d >= MAX_RE", nregexpr
);
965 if ((i
= regcomp(&(rarr
[nregexpr
].re
), yylval
.str
, REG_EXTENDED
|REG_NOSUB
)) != 0)
968 regerror(i
, &(rarr
[nregexpr
].re
), buf
, sizeof(buf
));
969 logit(LL_ERR
, "system: regcomp error for %s: [%s]", yylval
.str
, buf
);
975 if ((rarr
[nregexpr
].re_expr
= strdup(yylval
.str
)) == NULL
)
977 logit(LL_ERR
, "system: regexpr malloc error error for %s", yylval
.str
);
982 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: regexpr %s stored into slot %d", yylval
.str
, nregexpr
)));
984 if (rarr
[nregexpr
].re_prog
!= NULL
)
985 rarr
[nregexpr
].re_flg
= 1;
993 if (nregprog
>= MAX_RE
)
995 logit(LL_ERR
, "system: regprog #%d >= MAX_RE", nregprog
);
999 if ((rarr
[nregprog
].re_prog
= strdup(yylval
.str
)) == NULL
)
1001 logit(LL_ERR
, "system: regprog malloc error error for %s", yylval
.str
);
1002 config_error_flag
++;
1006 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: regprog %s stored into slot %d", yylval
.str
, nregprog
)));
1008 if (rarr
[nregprog
].re_expr
!= NULL
)
1009 rarr
[nregprog
].re_flg
= 1;
1015 strlcpy(rotatesuffix
, yylval
.str
, sizeof(rotatesuffix
));
1016 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: rotatesuffix = %s", yylval
.str
)));
1021 rt_prio
= yylval
.num
;
1022 if (rt_prio
< RTP_PRIO_MIN
|| rt_prio
> RTP_PRIO_MAX
)
1024 config_error_flag
++;
1025 logit(LL_ERR
, "system: error, rtprio (%d) out of range!", yylval
.num
);
1029 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: rtprio = %d", yylval
.num
)));
1032 rt_prio
= RTPRIO_NOTUSED
;
1037 strlcpy(tinainitprog
, yylval
.str
, sizeof(tinainitprog
));
1038 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: tinainitprog = %s", yylval
.str
)));
1042 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: unitlength = %d", current_cfe
->name
, yylval
.num
)));
1043 current_cfe
->unitlength
= yylval
.num
;
1047 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: unitlengthsrc = %s", current_cfe
->name
, yylval
.str
)));
1048 if (!(strcmp(yylval
.str
, "none")))
1049 current_cfe
->unitlengthsrc
= ULSRC_NONE
;
1050 else if (!(strcmp(yylval
.str
, "cmdl")))
1051 current_cfe
->unitlengthsrc
= ULSRC_CMDL
;
1052 else if (!(strcmp(yylval
.str
, "conf")))
1053 current_cfe
->unitlengthsrc
= ULSRC_CONF
;
1054 else if (!(strcmp(yylval
.str
, "rate")))
1055 current_cfe
->unitlengthsrc
= ULSRC_RATE
;
1056 else if (!(strcmp(yylval
.str
, "aocd")))
1057 current_cfe
->unitlengthsrc
= ULSRC_DYN
;
1060 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"unitlengthsrc\" at line %d!", lineno
);
1061 config_error_flag
++;
1066 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: usrdevicename = %s", current_cfe
->name
, yylval
.str
)));
1067 strncpy(current_cfe
->usrdevicename
, yylval
.str
, sizeof(current_cfe
->usrdevicename
));
1068 current_cfe
->usrdevice
= lookup_l4_driver(yylval
.str
);
1069 if (current_cfe
->usrdevice
< 0)
1071 logit(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"usrdevicename\" at line %d!", lineno
);
1072 config_error_flag
++;
1077 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: usrdeviceunit = %d", current_cfe
->name
, yylval
.num
)));
1078 current_cfe
->usrdeviceunit
= yylval
.num
;
1082 useacctfile
= yylval
.booln
;
1083 DBGL(DL_RCCF
, (logit(LL_DBG
, "system: useacctfile = %d", yylval
.booln
)));
1087 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: usedown = %d", current_cfe
->name
, yylval
.booln
)));
1088 current_cfe
->usedown
= yylval
.booln
;
1092 DBGL(DL_RCCF
, (logit(LL_DBG
, "entry %s: valid = %s", current_cfe
->name
, yylval
.str
)));
1093 parse_valid(yylval
.str
);
1097 logit(LL_ERR
, "ERROR parsing config file: unknown keyword at line %d!", lineno
);
1098 config_error_flag
++;
1103 /*---------------------------------------------------------------------------*
1104 * parse a date/time range
1105 *---------------------------------------------------------------------------*/
1107 parse_valid(char *dt
)
1109 /* a valid string consists of some days of week separated by
1110 * commas, where 0=sunday, 1=monday .. 6=saturday and a special
1111 * value of 7 which is a holiday from the holiday file.
1112 * after the days comes an optional (!) time range in the form
1113 * aa:bb-cc:dd, this format is fixed to be parsable by sscanf.
1114 * Valid specifications looks like this:
1115 * 1,2,3,4,5,09:00-18:00 Monday-Friday 9-18h
1116 * 1,2,3,4,5,18:00-09:00 Monday-Friday 18-9h
1117 * 6 Saturday (whole day)
1118 * 0,7 Sunday and Holidays
1130 if ( ( ((*dt
>= '0') && (*dt
<= '9')) && (*(dt
+1) == ':') ) ||
1131 ( ((*dt
>= '0') && (*dt
<= '2')) && ((*(dt
+1) >= '0') && (*(dt
+1) <= '9')) && (*(dt
+2) == ':') ) )
1133 /* dt points to time spec */
1134 ret
= sscanf(dt
, "%d:%d-%d:%d", &fromhr
, &frommin
, &tohr
, &tomin
);
1137 logit(LL_ERR
, "ERROR parsing config file: timespec [%s] error at line %d!", *dt
, lineno
);
1138 config_error_flag
++;
1142 if (fromhr
< 0 || fromhr
> 24 || tohr
< 0 || tohr
> 24 ||
1143 frommin
< 0 || frommin
> 59 || tomin
< 0 || tomin
> 59)
1145 logit(LL_ERR
, "ERROR parsing config file: invalid time [%s] at line %d!", *dt
, lineno
);
1146 config_error_flag
++;
1151 else if ((*dt
>= '0') && (*dt
<= '7'))
1153 /* dt points to day spec */
1154 day
|= 1 << (*dt
- '0');
1158 else if (*dt
== ',')
1160 /* dt points to delimiter */
1164 else if (*dt
== '\0')
1166 /* dt points to end of string */
1171 /* dt points to illegal character */
1172 logit(LL_ERR
, "ERROR parsing config file: illegal character [%c=0x%x] in date/time spec at line %d!", *dt
, *dt
, lineno
);
1173 config_error_flag
++;
1177 current_cfe
->day
= day
;
1178 current_cfe
->fromhr
= fromhr
;
1179 current_cfe
->frommin
= frommin
;
1180 current_cfe
->tohr
= tohr
;
1181 current_cfe
->tomin
= tomin
;
1187 if (current_cfe
!= NULL
) {
1188 add_cfg_entry(current_cfe
);
1192 /*---------------------------------------------------------------------------*
1193 * configuration validation and consistency check
1194 *---------------------------------------------------------------------------*/
1198 struct cfg_entry
*cep
= NULL
;
1202 /* regular expression table */
1204 for (i
=0; i
< MAX_RE
; i
++)
1206 if ((rarr
[i
].re_expr
!= NULL
) && (rarr
[i
].re_prog
== NULL
))
1208 logit(LL_ERR
, "check_config: regular expression %d without program!", i
);
1211 if ((rarr
[i
].re_prog
!= NULL
) && (rarr
[i
].re_expr
== NULL
))
1213 logit(LL_ERR
, "check_config: regular expression program %d without expression!", i
);
1218 /* entry sections */
1220 for (cep
= get_first_cfg_entry(); cep
; cep
= NEXT_CFE(cep
)) {
1222 /* does this entry have a bchannel driver configured? */
1223 if (cep
->usrdevice
< 0) {
1224 logit(LL_ERR
, "check_config: usrdevicename not set in entry \"%s\"!",
1228 if (cep
->usrdeviceunit
< 0) {
1229 logit(LL_ERR
, "check_config: usrdeviceunit not set in entry \"%s\"!",
1234 /* numbers used for dialout */
1236 if ((cep
->inout
!= DIR_INONLY
) && (cep
->dialin_reaction
!= REACT_ANSWER
))
1238 if (cep
->remote_numbers_count
== 0)
1240 logit(LL_ERR
, "check_config: remote-phone-dialout not set in entry \"%s\"!",
1246 /* numbers used for incoming calls */
1248 if (cep
->inout
!= DIR_OUTONLY
)
1250 if (strlen(cep
->local_phone_incoming
) == 0)
1252 logit(LL_ERR
, "check_config: local-phone-incoming not set in entry \"%s\"!",
1256 if (cep
->incoming_numbers_count
== 0)
1258 logit(LL_ERR
, "check_config: remote-phone-incoming not set in entry \"%s\"!",
1264 if ((cep
->dialin_reaction
== REACT_ANSWER
) && (cep
->b1protocol
!= BPROT_NONE
))
1266 logit(LL_ERR
, "check_config: b1protocol not raw for telephony in entry \"%s\"!",
1271 if ((cep
->ppp_send_auth
== AUTH_PAP
) || (cep
->ppp_send_auth
== AUTH_CHAP
))
1273 if (cep
->ppp_send_name
== NULL
)
1275 logit(LL_ERR
, "check_config: no remote authentification name in entry \"%s\"!",
1279 if (cep
->ppp_send_password
== NULL
)
1281 logit(LL_ERR
, "check_config: no remote authentification password in entry \"%s\"!",
1286 if ((cep
->ppp_expect_auth
== AUTH_PAP
) || (cep
->ppp_expect_auth
== AUTH_CHAP
))
1288 if (cep
->ppp_expect_name
== NULL
)
1290 logit(LL_ERR
, "check_config: no local authentification name in entry \"%s\"!",
1294 if (cep
->ppp_expect_password
== NULL
)
1296 logit(LL_ERR
, "check_config: no local authentification secret in entry \"%s\"!",
1302 if (cep
->ppp_expect_auth
!= AUTH_UNDEF
1303 || cep
->ppp_send_auth
!= AUTH_UNDEF
)
1304 set_isppp_auth(cep
);
1307 * Only if AUTOUPDOWN_YES is the only bit set, otherwise
1308 * we already have handled this interface.
1310 if (cep
->autoupdown
== AUTOUPDOWN_YES
)
1311 set_autoupdown(cep
);
1314 logit(LL_ERR
, "check_config: %d error(s) in configuration file, exiting!",
1320 /*---------------------------------------------------------------------------*
1321 * print the configuration
1322 *---------------------------------------------------------------------------*/
1326 #define PFILE stdout
1328 #ifdef I4B_EXTERNAL_MONITOR
1329 extern struct monitor_rights
* monitor_next_rights(const struct monitor_rights
*r
);
1330 struct monitor_rights
*m_rights
;
1332 struct cfg_entry
*cep
= NULL
;
1338 strlcpy(mytime
, ctime(&now
), sizeof(mytime
));
1339 mytime
[strlen(mytime
)-1] = '\0';
1341 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1342 fprintf(PFILE
, "# system section (generated %s)\n", mytime
);
1343 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1344 fprintf(PFILE
, "system\n");
1345 fprintf(PFILE
, "useacctfile = %s\n", useacctfile
? "on\t\t\t\t# update accounting information file" : "off\t\t\t\t# don't update accounting information file");
1346 fprintf(PFILE
, "acctall = %s\n", acct_all
? "on\t\t\t\t# put all events into accounting file" : "off\t\t\t\t# put only charged events into accounting file");
1347 fprintf(PFILE
, "acctfile = %s\t\t# accounting information file\n", acctfile
);
1348 fprintf(PFILE
, "ratesfile = %s\t\t# charging rates database file\n", ratesfile
);
1351 if (rt_prio
== RTPRIO_NOTUSED
)
1352 fprintf(PFILE
, "# rtprio is unused\n");
1354 fprintf(PFILE
, "rtprio = %d\t\t\t\t# isdnd runs at realtime priority\n", rt_prio
);
1357 /* regular expression table */
1359 for (i
=0; i
< MAX_RE
; i
++)
1361 if (rarr
[i
].re_expr
!= NULL
)
1363 fprintf(PFILE
, "regexpr = \"%s\"\t\t# scan logfile for this expression\n", rarr
[i
].re_expr
);
1365 if (rarr
[i
].re_prog
!= NULL
)
1367 fprintf(PFILE
, "regprog = %s\t\t# program to run when expression is matched\n", rarr
[i
].re_prog
);
1371 #ifdef I4B_EXTERNAL_MONITOR
1373 fprintf(PFILE
, "monitor-allowed = %s\n", do_monitor
? "on\t\t\t\t# remote isdnd monitoring allowed" : "off\t\t\t\t# remote isdnd monitoring disabled");
1374 fprintf(PFILE
, "monitor-port = %d\t\t\t\t# TCP/IP port number used for remote monitoring\n", monitorport
);
1376 m_rights
= monitor_next_rights(NULL
);
1377 if (m_rights
!= NULL
)
1379 const char *s
= "error\n";
1382 for ( ; m_rights
!= NULL
; m_rights
= monitor_next_rights(m_rights
))
1384 if (m_rights
->local
)
1386 fprintf(PFILE
, "monitor = \"%s\"\t\t# local socket name for monitoring\n", m_rights
->name
);
1391 ia
.s_addr
= ntohl(m_rights
->net
);
1393 switch (m_rights
->mask
)
1495 fprintf(PFILE
, "monitor = \"%s/%s\"\t\t# host (net/mask) allowed to connect for monitoring\n", inet_ntoa(ia
), s
);
1499 if ((m_rights
->rights
) & I4B_CA_COMMAND_FULL
)
1500 strlcat(b
, "fullcmd,", sizeof(b
));
1501 if ((m_rights
->rights
) & I4B_CA_COMMAND_RESTRICTED
)
1502 strlcat(b
, "restrictedcmd,", sizeof(b
));
1503 if ((m_rights
->rights
) & I4B_CA_EVNT_CHANSTATE
)
1504 strlcat(b
, "channelstate,", sizeof(b
));
1505 if ((m_rights
->rights
) & I4B_CA_EVNT_CALLIN
)
1506 strlcat(b
, "callin,", sizeof(b
));
1507 if ((m_rights
->rights
) & I4B_CA_EVNT_CALLOUT
)
1508 strlcat(b
, "callout,", sizeof(b
));
1509 if ((m_rights
->rights
) & I4B_CA_EVNT_I4B
)
1510 strlcat(b
, "logevents,", sizeof(b
));
1512 if (strlen(b
) > 0 && b
[strlen(b
)-1] == ',')
1513 b
[strlen(b
)-1] = '\0';
1515 fprintf(PFILE
, "monitor-access = %s\t\t# monitor access rights\n", b
);
1520 /* entry sections */
1522 for (cep
= get_first_cfg_entry(); cep
; cep
= NEXT_CFE(cep
)) {
1523 fprintf(PFILE
, "\n");
1524 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1525 fprintf(PFILE
, "# entry section %d\n", i
);
1526 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1527 fprintf(PFILE
, "entry\n");
1529 fprintf(PFILE
, "name = %s\t\t# name for this entry section\n", cep
->name
);
1531 fprintf(PFILE
, "isdncontroller = %d\t\t# ISDN card number used for this entry\n", cep
->isdncontroller
);
1532 fprintf(PFILE
, "isdnchannel = ");
1533 switch (cep
->isdnchannel
)
1536 fprintf(PFILE
, "-1\t\t# any ISDN B-channel may be used\n");
1539 fprintf(PFILE
, "1\t\t# only ISDN B-channel %d may be used\n", cep
->isdnchannel
);
1543 fprintf(PFILE
, "usrdevicename = %s\t\t# name of userland ISDN B-channel device\n", cep
->usrdevicename
);
1544 fprintf(PFILE
, "usrdeviceunit = %d\t\t# unit number of userland ISDN B-channel device\n", cep
->usrdeviceunit
);
1546 fprintf(PFILE
, "b1protocol = %s\n", cep
->b1protocol
? "hdlc\t\t# B-channel layer 1 protocol is HDLC" : "raw\t\t# No B-channel layer 1 protocol used");
1548 fprintf(PFILE
, "direction = ");
1552 fprintf(PFILE
, "in\t\t# only incoming connections allowed\n");
1555 fprintf(PFILE
, "out\t\t# only outgoing connections allowed\n");
1558 fprintf(PFILE
, "inout\t\t# incoming and outgoing connections allowed\n");
1562 if (cep
->remote_numbers_count
> 1)
1564 for (j
= 0; j
< cep
->remote_numbers_count
; j
++)
1565 fprintf(PFILE
, "remote-phone-dialout = %s\t\t# telephone number %d for dialing out to remote\n", cep
->remote_numbers
[j
].number
, j
+1);
1567 fprintf(PFILE
, "remdial-handling = ");
1569 switch (cep
->remote_numbers_handling
)
1572 fprintf(PFILE
, "next\t\t# use next number after last successful for new dial\n");
1575 fprintf(PFILE
, "last\t\t# use last successful number for new dial\n");
1578 fprintf(PFILE
, "first\t\t# always start with first number for new dial\n");
1583 if (cep
->local_phone_dialout
[0])
1584 fprintf(PFILE
, "local-phone-dialout = %s\t\t# show this number to remote when dialling out\n",
1585 cep
->local_phone_dialout
);
1586 fprintf(PFILE
, "dialout-type = %s\n", cep
->dialouttype
? "calledback\t\t# i am called back by remote" : "normal\t\t# i am not called back by remote");
1589 if (!(cep
->inout
== DIR_OUTONLY
))
1593 fprintf(PFILE
, "local-phone-incoming = %s\t\t# incoming calls must match this (mine) telephone number\n", cep
->local_phone_incoming
);
1594 for (n
= 0; n
< cep
->incoming_numbers_count
; n
++)
1595 fprintf(PFILE
, "remote-phone-incoming = %s\t\t# this is a valid remote number to call me\n",
1596 cep
->remote_phone_incoming
[n
].number
);
1598 fprintf(PFILE
, "dialin-reaction = ");
1599 switch (cep
->dialin_reaction
)
1602 fprintf(PFILE
, "accept\t\t# i accept a call from remote and connect\n");
1605 fprintf(PFILE
, "reject\t\t# i reject the call from remote\n");
1608 fprintf(PFILE
, "ignore\t\t# i ignore the call from remote\n");
1611 fprintf(PFILE
, "answer\t\t# i will start telephone answering when remote calls in\n");
1613 case REACT_CALLBACK
:
1614 fprintf(PFILE
, "callback\t\t# when remote calls in, i will hangup and call back\n");
1621 switch (cep
->ppp_expect_auth
)
1638 fprintf(PFILE
, "ppp-expect-auth = %s\t\t# the auth protocol we expect to receive on dial-in (none,pap,chap)\n", s
);
1639 if (cep
->ppp_expect_auth
!= AUTH_NONE
)
1641 fprintf(PFILE
, "ppp-expect-name = %s\t\t# the user name allowed in\n", cep
->ppp_expect_name
);
1642 fprintf(PFILE
, "ppp-expect-password = %s\t\t# the key expected from the other side\n", cep
->ppp_expect_password
);
1643 fprintf(PFILE
, "ppp-auth-paranoid = %s\t\t# do we require remote to authenticate even if we dial out\n", cep
->ppp_auth_flags
& AUTH_REQUIRED
? "yes" : "no");
1646 switch (cep
->ppp_send_auth
)
1663 fprintf(PFILE
, "ppp-send-auth = %s\t\t# the auth protocol we use when dialing out (none,pap,chap)\n", s
);
1664 if (cep
->ppp_send_auth
!= AUTH_NONE
)
1666 fprintf(PFILE
, "ppp-send-name = %s\t\t# our PPP account used for dial-out\n", cep
->ppp_send_name
);
1667 fprintf(PFILE
, "ppp-send-password = %s\t\t# the key sent to the other side\n", cep
->ppp_send_password
);
1670 if (cep
->ppp_send_auth
== AUTH_CHAP
||
1671 cep
->ppp_expect_auth
== AUTH_CHAP
) {
1672 fprintf(PFILE
, "ppp-auth-rechallenge = %s\t\t# rechallenge CHAP connections once in a while\n", cep
->ppp_auth_flags
& AUTH_RECHALLENGE
? "yes" : "no");
1676 if (cep
->autoupdown
== AUTOUPDOWN_NO
)
1677 fprintf(PFILE
, "autoupdown = no\n");
1681 fprintf(PFILE
, "idletime-outgoing = %d\t\t# outgoing call idle timeout\n", cep
->idle_time_out
);
1683 switch ( cep
->shorthold_algorithm
)
1686 s
= "fix-unit-size";
1689 s
= "var-unit-size";
1696 fprintf(PFILE
, "idle-algorithm-outgoing = %s\t\t# outgoing call idle algorithm\n", s
);
1699 if (!(cep
->inout
== DIR_OUTONLY
))
1700 fprintf(PFILE
, "idletime-incoming = %d\t\t# incoming call idle timeout\n", cep
->idle_time_in
);
1703 fprintf(PFILE
, "unitlengthsrc = ");
1704 switch (cep
->unitlengthsrc
)
1707 fprintf(PFILE
, "none\t\t# no unit length specified, using default\n");
1710 fprintf(PFILE
, "cmdl\t\t# using unit length specified on commandline\n");
1713 fprintf(PFILE
, "conf\t\t# using unitlength specified by unitlength-keyword\n");
1714 fprintf(PFILE
, "unitlength = %d\t\t# fixed unitlength\n", cep
->unitlength
);
1717 fprintf(PFILE
, "rate\t\t# using unitlength specified in rate database\n");
1718 fprintf(PFILE
, "ratetype = %d\t\t# type of rate from rate database\n", cep
->ratetype
);
1721 fprintf(PFILE
, "aocd\t\t# using dynamically calculated unitlength based on AOCD subscription\n");
1722 fprintf(PFILE
, "ratetype = %d\t\t# type of rate from rate database\n", cep
->ratetype
);
1726 fprintf(PFILE
, "earlyhangup = %d\t\t# early hangup safety time\n", cep
->earlyhangup
);
1731 fprintf(PFILE
, "answerprog = %s\t\t# program used to answer incoming telephone calls\n", cep
->answerprog
);
1732 fprintf(PFILE
, "alert = %d\t\t# number of seconds to wait before accepting a call\n", cep
->alert
);
1736 if (cep
->dialin_reaction
== REACT_CALLBACK
)
1737 fprintf(PFILE
, "callbackwait = %d\t\t# i am waiting this time before calling back remote\n", cep
->callbackwait
);
1739 if (cep
->dialouttype
== DIALOUT_CALLEDBACK
)
1740 fprintf(PFILE
, "calledbackwait = %d\t\t# i am waiting this time for a call back from remote\n", cep
->calledbackwait
);
1742 if (!(cep
->inout
== DIR_INONLY
))
1744 fprintf(PFILE
, "dialretries = %d\t\t# number of dialing retries\n", cep
->dialretries
);
1745 fprintf(PFILE
, "recoverytime = %d\t\t# time to wait between dialling retries\n", cep
->recoverytime
);
1746 fprintf(PFILE
, "dialrandincr = %s\t\t# use random dialing time addon\n", cep
->dialrandincr
? "on" : "off");
1748 fprintf(PFILE
, "usedown = %s\n", cep
->usedown
? "on\t\t# ISDN device switched off on excessive dial failures" : "off\t\t# no device switchoff on excessive dial failures");
1751 fprintf(PFILE
, "downtries = %d\t\t# number of dialretries failures before switching off\n", cep
->downtries
);
1752 fprintf(PFILE
, "downtime = %d\t\t# time device is switched off\n", cep
->downtime
);
1756 fprintf(PFILE
, "\n");
1760 lookup_l4_driver(const char *name
)
1762 msg_l4driver_lookup_t query
;
1765 memset(&query
, 0, sizeof query
);
1766 strncpy(query
.name
, name
, sizeof query
.name
);
1767 e
= ioctl(isdnfd
, I4B_L4DRIVER_LOOKUP
, &query
);
1768 if (e
!= 0) return -1;
1769 return query
.driver_id
;