2 * Copyright (c) 1997, 2001 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 * $FreeBSD: src/usr.sbin/i4b/isdnd/rc_config.c,v 1.6.2.3 2002/04/24 18:50:07 joerg Exp $
31 * $DragonFly: src/usr.sbin/i4b/isdnd/rc_config.c,v 1.5 2008/04/20 13:44:26 swildner Exp $
33 * last edit-date: [Fri Jul 20 19:16:27 2001]
35 *---------------------------------------------------------------------------*/
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
42 #include <sys/ioctl.h>
51 extern int entrycount
;
52 extern int controllercount
;
59 static void set_config_defaults(void);
60 static void check_config(void);
61 static void print_config(void);
62 static void parse_valid(int entrycount
, char *dt
);
64 static int nregexpr
= 0;
65 static int nregprog
= 0;
67 /*---------------------------------------------------------------------------*
68 * called from main to read and process config file
69 *---------------------------------------------------------------------------*/
71 configure(char *filename
, int reread
)
73 extern void reset_scanner(FILE *inputfile
);
75 set_config_defaults();
77 yyin
= fopen(filename
, "r");
86 dolog(LL_ERR
, "cannot fopen file [%s]", filename
);
92 monitor_fixup_rights();
94 check_config(); /* validation and consistency check */
100 if(config_error_flag
)
102 dolog(LL_ERR
, "there were %d error(s) in the configuration file, terminating!", config_error_flag
);
110 /*---------------------------------------------------------------------------*
112 *---------------------------------------------------------------------------*/
114 yyerror(const char *msg
)
116 dolog(LL_ERR
, "configuration error: %s at line %d, token \"%s\"", msg
, lineno
+1, yytext
);
120 /*---------------------------------------------------------------------------*
121 * fill all config entries with default values
122 *---------------------------------------------------------------------------*/
124 set_config_defaults(void)
126 cfg_entry_t
*cep
= &cfg_entry_tab
[0]; /* ptr to config entry */
129 /* system section cleanup */
131 nregprog
= nregexpr
= 0;
133 rt_prio
= RTPRIO_NOTUSED
;
138 /* clean regular expression table */
140 for(i
=0; i
< MAX_RE
; i
++)
143 free(rarr
[i
].re_expr
);
144 rarr
[i
].re_expr
= NULL
;
147 free(rarr
[i
].re_prog
);
148 rarr
[i
].re_prog
= NULL
;
153 strcpy(rotatesuffix
, "");
156 * controller table cleanup, beware: has already
157 * been setup in main, init_controller() !
160 for(i
=0; i
< ncontroller
; i
++)
162 isdn_ctrl_tab
[i
].protocol
= PROTOCOL_DSS1
;
163 isdn_ctrl_tab
[i
].firmware
= NULL
;
166 /* entry section cleanup */
168 for(i
=0; i
< CFG_ENTRY_MAX
; i
++, cep
++)
170 bzero(cep
, sizeof(cfg_entry_t
));
172 /* ====== filled in at startup configuration, then static */
174 sprintf(cep
->name
, "ENTRY%d", i
);
176 cep
->isdncontroller
= INVALID
;
177 cep
->isdnchannel
= CHAN_ANY
;
179 cep
->usrdevicename
= INVALID
;
180 cep
->usrdeviceunit
= INVALID
;
182 cep
->remote_numbers_handling
= RNH_LAST
;
184 cep
->dialin_reaction
= REACT_IGNORE
;
186 cep
->b1protocol
= BPROT_NONE
;
188 cep
->unitlength
= UNITLENGTH_DEFAULT
;
190 cep
->earlyhangup
= EARLYHANGUP_DEFAULT
;
192 cep
->ratetype
= INVALID_RATE
;
194 cep
->unitlengthsrc
= ULSRC_NONE
;
196 cep
->answerprog
= ANSWERPROG_DEF
;
198 cep
->callbackwait
= CALLBACKWAIT_MIN
;
200 cep
->calledbackwait
= CALLEDBACKWAIT_MIN
;
202 cep
->dialretries
= DIALRETRIES_DEF
;
204 cep
->recoverytime
= RECOVERYTIME_MIN
;
206 cep
->dialouttype
= DIALOUT_NORMAL
;
208 cep
->inout
= DIR_INOUT
;
210 cep
->ppp_expect_auth
= AUTH_UNDEF
;
212 cep
->ppp_send_auth
= AUTH_UNDEF
;
214 cep
->ppp_auth_flags
= AUTH_RECHALLENGE
| AUTH_REQUIRED
;
216 /* ======== filled in after start, then dynamic */
218 cep
->cdid
= CDID_UNUSED
;
220 cep
->state
= ST_IDLE
;
222 cep
->aoc_valid
= AOC_INVALID
;
226 /*---------------------------------------------------------------------------*
227 * internaly set values for ommitted controler sectin
228 *---------------------------------------------------------------------------*/
230 cfg_set_controller_default(void)
233 DBGL(DL_RCCF
, (dolog(LL_DBG
, "[defaults, no controller section] controller %d: protocol = dss1", controllercount
)));
234 isdn_ctrl_tab
[controllercount
].protocol
= PROTOCOL_DSS1
;
237 #define PPP_PAP 0xc023
238 #define PPP_CHAP 0xc223
241 set_isppp_auth(int entry
)
243 cfg_entry_t
*cep
= &cfg_entry_tab
[entry
]; /* ptr to config entry */
250 if(cep
->usrdevicename
!= BDRV_ISPPP
)
253 if(cep
->ppp_expect_auth
== AUTH_UNDEF
254 && cep
->ppp_send_auth
== AUTH_UNDEF
)
257 if(cep
->ppp_expect_auth
== AUTH_NONE
258 || cep
->ppp_send_auth
== AUTH_NONE
)
261 if ((cep
->ppp_expect_auth
== AUTH_CHAP
262 || cep
->ppp_expect_auth
== AUTH_PAP
)
263 && cep
->ppp_expect_name
[0] != 0
264 && cep
->ppp_expect_password
[0] != 0)
267 if ((cep
->ppp_send_auth
== AUTH_CHAP
|| cep
->ppp_send_auth
== AUTH_PAP
)
268 && cep
->ppp_send_name
[0] != 0
269 && cep
->ppp_send_password
[0] != 0)
275 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "isp%d", cep
->usrdeviceunit
);
277 /* use a random AF to create the socket */
278 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
279 dolog(LL_ERR
, "ERROR opening control socket at line %d!", lineno
);
283 spr
.cmd
= (int)SPPPIOGDEFS
;
284 ifr
.ifr_data
= (caddr_t
)&spr
;
286 if (ioctl(s
, SIOCGIFGENERIC
, &ifr
) == -1) {
287 dolog(LL_ERR
, "ERROR fetching active PPP authentication info for %s at line %d!", ifr
.ifr_name
, lineno
);
292 if (cep
->ppp_expect_auth
!= AUTH_UNDEF
)
294 if(cep
->ppp_expect_auth
== AUTH_NONE
)
296 spr
.defs
.hisauth
.proto
= 0;
298 else if ((cep
->ppp_expect_auth
== AUTH_CHAP
299 || cep
->ppp_expect_auth
== AUTH_PAP
)
300 && cep
->ppp_expect_name
[0] != 0
301 && cep
->ppp_expect_password
[0] != 0)
303 spr
.defs
.hisauth
.proto
= cep
->ppp_expect_auth
== AUTH_PAP
? PPP_PAP
: PPP_CHAP
;
304 strncpy(spr
.defs
.hisauth
.name
, cep
->ppp_expect_name
, AUTHNAMELEN
);
305 strncpy(spr
.defs
.hisauth
.secret
, cep
->ppp_expect_password
, AUTHKEYLEN
);
308 if (cep
->ppp_send_auth
!= AUTH_UNDEF
)
310 if(cep
->ppp_send_auth
== AUTH_NONE
)
312 spr
.defs
.myauth
.proto
= 0;
314 else if ((cep
->ppp_send_auth
== AUTH_CHAP
315 || cep
->ppp_send_auth
== AUTH_PAP
)
316 && cep
->ppp_send_name
[0] != 0
317 && cep
->ppp_send_password
[0] != 0)
319 spr
.defs
.myauth
.proto
= cep
->ppp_send_auth
== AUTH_PAP
? PPP_PAP
: PPP_CHAP
;
320 strncpy(spr
.defs
.myauth
.name
, cep
->ppp_send_name
, AUTHNAMELEN
);
321 strncpy(spr
.defs
.myauth
.secret
, cep
->ppp_send_password
, AUTHKEYLEN
);
323 if(cep
->ppp_auth_flags
& AUTH_REQUIRED
)
324 spr
.defs
.hisauth
.flags
&= ~AUTHFLAG_NOCALLOUT
;
326 spr
.defs
.hisauth
.flags
|= AUTHFLAG_NOCALLOUT
;
328 if(cep
->ppp_auth_flags
& AUTH_RECHALLENGE
)
329 spr
.defs
.hisauth
.flags
&= ~AUTHFLAG_NORECHALLENGE
;
331 spr
.defs
.hisauth
.flags
|= AUTHFLAG_NORECHALLENGE
;
335 spr
.cmd
= (int)SPPPIOSDEFS
;
337 if (ioctl(s
, SIOCSIFGENERIC
, &ifr
) == -1) {
338 dolog(LL_ERR
, "ERROR setting new PPP authentication parameters for %s at line %d!", ifr
.ifr_name
, lineno
);
344 /*---------------------------------------------------------------------------*
345 * extract values from config and fill table
346 *---------------------------------------------------------------------------*/
348 cfg_setval(int keyword
)
355 acct_all
= yylval
.booln
;
356 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: acctall = %d", yylval
.booln
)));
360 strcpy(acctfile
, yylval
.str
);
361 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: acctfile = %s", yylval
.str
)));
365 if(yylval
.num
< MINALERT
)
367 yylval
.num
= MINALERT
;
368 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: alert < %d, min = %d", entrycount
, MINALERT
, yylval
.num
)));
370 else if(yylval
.num
> MAXALERT
)
372 yylval
.num
= MAXALERT
;
373 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: alert > %d, min = %d", entrycount
, MAXALERT
, yylval
.num
)));
376 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: alert = %d", entrycount
, yylval
.num
)));
377 cfg_entry_tab
[entrycount
].alert
= yylval
.num
;
381 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: aliasing = %d", yylval
.booln
)));
382 aliasing
= yylval
.booln
;
386 strcpy(aliasfile
, yylval
.str
);
387 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: aliasfile = %s", yylval
.str
)));
391 if((cfg_entry_tab
[entrycount
].answerprog
= malloc(strlen(yylval
.str
)+1)) == NULL
)
393 dolog(LL_ERR
, "entry %d: answerstring, malloc failed!", entrycount
);
396 strcpy(cfg_entry_tab
[entrycount
].answerprog
, yylval
.str
);
397 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: answerprog = %s", entrycount
, yylval
.str
)));
401 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: b1protocol = %s", entrycount
, yylval
.str
)));
402 if(!(strcmp(yylval
.str
, "raw")))
403 cfg_entry_tab
[entrycount
].b1protocol
= BPROT_NONE
;
404 else if(!(strcmp(yylval
.str
, "hdlc")))
405 cfg_entry_tab
[entrycount
].b1protocol
= BPROT_RHDLC
;
408 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"b1protocol\" at line %d!", lineno
);
414 do_bell
= yylval
.booln
;
415 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: beepconnect = %d", yylval
.booln
)));
418 case BUDGETCALLBACKPERIOD
:
419 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-callbackperiod = %d", entrycount
, yylval
.num
)));
420 cfg_entry_tab
[entrycount
].budget_callbackperiod
= yylval
.num
;
423 case BUDGETCALLBACKNCALLS
:
424 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-callbackncalls = %d", entrycount
, yylval
.num
)));
425 cfg_entry_tab
[entrycount
].budget_callbackncalls
= yylval
.num
;
428 case BUDGETCALLOUTPERIOD
:
429 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-calloutperiod = %d", entrycount
, yylval
.num
)));
430 cfg_entry_tab
[entrycount
].budget_calloutperiod
= yylval
.num
;
433 case BUDGETCALLOUTNCALLS
:
434 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-calloutncalls = %d", entrycount
, yylval
.num
)));
435 cfg_entry_tab
[entrycount
].budget_calloutncalls
= yylval
.num
;
438 case BUDGETCALLBACKSFILEROTATE
:
439 cfg_entry_tab
[entrycount
].budget_callbacksfile_rotate
= yylval
.booln
;
440 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-callbacksfile-rotate = %d", entrycount
, yylval
.booln
)));
443 case BUDGETCALLBACKSFILE
:
448 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-callbacksfile = %s", entrycount
, yylval
.str
)));
449 fp
= fopen(yylval
.str
, "r");
452 if((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) != 3)
454 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: initializing budget-callbacksfile %s", entrycount
, yylval
.str
)));
456 fp
= fopen(yylval
.str
, "w");
458 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
464 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: creating budget-callbacksfile %s", entrycount
, yylval
.str
)));
465 fp
= fopen(yylval
.str
, "w");
467 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
471 fp
= fopen(yylval
.str
, "r");
474 if((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) == 3)
476 if((cfg_entry_tab
[entrycount
].budget_callbacks_file
= malloc(strlen(yylval
.str
)+1)) == NULL
)
478 dolog(LL_ERR
, "entry %d: budget-callbacksfile, malloc failed!", entrycount
);
481 strcpy(cfg_entry_tab
[entrycount
].budget_callbacks_file
, yylval
.str
);
482 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: using callbacksfile %s", entrycount
, yylval
.str
)));
489 case BUDGETCALLOUTSFILEROTATE
:
490 cfg_entry_tab
[entrycount
].budget_calloutsfile_rotate
= yylval
.booln
;
491 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-calloutsfile-rotate = %d", entrycount
, yylval
.booln
)));
494 case BUDGETCALLOUTSFILE
:
499 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: budget-calloutsfile = %s", entrycount
, yylval
.str
)));
500 fp
= fopen(yylval
.str
, "r");
503 if((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) != 3)
505 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: initializing budget-calloutsfile %s", entrycount
, yylval
.str
)));
507 fp
= fopen(yylval
.str
, "w");
509 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
515 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: creating budget-calloutsfile %s", entrycount
, yylval
.str
)));
516 fp
= fopen(yylval
.str
, "w");
518 fprintf(fp
, "%d %d %d", (int)time(NULL
), (int)time(NULL
), 0);
522 fp
= fopen(yylval
.str
, "r");
525 if((fscanf(fp
, "%d %d %d", (int *)&s
, (int *)&l
, &n
)) == 3)
527 if((cfg_entry_tab
[entrycount
].budget_callouts_file
= malloc(strlen(yylval
.str
)+1)) == NULL
)
529 dolog(LL_ERR
, "entry %d: budget-calloutsfile, malloc failed!", entrycount
);
532 strcpy(cfg_entry_tab
[entrycount
].budget_callouts_file
, yylval
.str
);
533 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: using calloutsfile %s", entrycount
, yylval
.str
)));
541 if(yylval
.num
< CALLBACKWAIT_MIN
)
543 yylval
.num
= CALLBACKWAIT_MIN
;
544 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: callbackwait < %d, min = %d", entrycount
, CALLBACKWAIT_MIN
, yylval
.num
)));
547 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: callbackwait = %d", entrycount
, yylval
.num
)));
548 cfg_entry_tab
[entrycount
].callbackwait
= yylval
.num
;
552 if(yylval
.num
< CALLEDBACKWAIT_MIN
)
554 yylval
.num
= CALLEDBACKWAIT_MIN
;
555 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: calledbackwait < %d, min = %d", entrycount
, CALLEDBACKWAIT_MIN
, yylval
.num
)));
558 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: calledbackwait = %d", entrycount
, yylval
.num
)));
559 cfg_entry_tab
[entrycount
].calledbackwait
= yylval
.num
;
564 * clone = <entryname>
565 * Loads the entry from the named, existing one.
566 * Fields such as name and usrdeviceunit should
567 * always be specified after clone as they must be
570 * NOTE: all malloc()'d fields must be dup()'d here,
571 * we can't have multiple references to same storage.
573 for (i
= 0; i
< entrycount
; i
++)
574 if (!strcmp(cfg_entry_tab
[i
].name
, yylval
.str
))
576 if (i
== entrycount
) {
577 dolog(LL_ERR
, "entry %d: clone, unknown entry %s!", entrycount
, yylval
.str
);
581 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: clone = %s", entrycount
, yylval
.str
)));
583 memcpy(&cfg_entry_tab
[entrycount
], &cfg_entry_tab
[i
],
584 sizeof(cfg_entry_tab
[0]));
586 if (cfg_entry_tab
[entrycount
].answerprog
)
587 cfg_entry_tab
[entrycount
].answerprog
= strdup(cfg_entry_tab
[entrycount
].answerprog
);
588 if (cfg_entry_tab
[entrycount
].budget_callbacks_file
)
589 cfg_entry_tab
[entrycount
].budget_callbacks_file
= strdup(cfg_entry_tab
[entrycount
].budget_callbacks_file
);
590 if (cfg_entry_tab
[entrycount
].budget_callouts_file
)
591 cfg_entry_tab
[entrycount
].budget_callouts_file
= strdup(cfg_entry_tab
[entrycount
].budget_callouts_file
);
592 if (cfg_entry_tab
[entrycount
].connectprog
)
593 cfg_entry_tab
[entrycount
].connectprog
= strdup(cfg_entry_tab
[entrycount
].connectprog
);
594 if (cfg_entry_tab
[entrycount
].disconnectprog
)
595 cfg_entry_tab
[entrycount
].disconnectprog
= strdup(cfg_entry_tab
[entrycount
].disconnectprog
);
599 if((cfg_entry_tab
[entrycount
].connectprog
= malloc(strlen(yylval
.str
)+1)) == NULL
)
601 dolog(LL_ERR
, "entry %d: connectprog, malloc failed!", entrycount
);
604 strcpy(cfg_entry_tab
[entrycount
].connectprog
, yylval
.str
);
605 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: connectprog = %s", entrycount
, yylval
.str
)));
609 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: dialouttype = %s", entrycount
, yylval
.str
)));
610 if(!(strcmp(yylval
.str
, "normal")))
611 cfg_entry_tab
[entrycount
].dialouttype
= DIALOUT_NORMAL
;
612 else if(!(strcmp(yylval
.str
, "calledback")))
613 cfg_entry_tab
[entrycount
].dialouttype
= DIALOUT_CALLEDBACK
;
616 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"dialout-type\" at line %d!", lineno
);
622 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: dialretries = %d", entrycount
, yylval
.num
)));
623 cfg_entry_tab
[entrycount
].dialretries
= yylval
.num
;
627 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: dialrandincr = %d", entrycount
, yylval
.booln
)));
628 cfg_entry_tab
[entrycount
].dialrandincr
= yylval
.booln
;
632 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: direction = %s", entrycount
, yylval
.str
)));
634 if(!(strcmp(yylval
.str
, "inout")))
635 cfg_entry_tab
[entrycount
].inout
= DIR_INOUT
;
636 else if(!(strcmp(yylval
.str
, "in")))
637 cfg_entry_tab
[entrycount
].inout
= DIR_INONLY
;
638 else if(!(strcmp(yylval
.str
, "out")))
639 cfg_entry_tab
[entrycount
].inout
= DIR_OUTONLY
;
642 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"direction\" at line %d!", lineno
);
648 if((cfg_entry_tab
[entrycount
].disconnectprog
= malloc(strlen(yylval
.str
)+1)) == NULL
)
650 dolog(LL_ERR
, "entry %d: disconnectprog, malloc failed!", entrycount
);
653 strcpy(cfg_entry_tab
[entrycount
].disconnectprog
, yylval
.str
);
654 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: disconnectprog = %s", entrycount
, yylval
.str
)));
658 if(yylval
.num
> DOWN_TRIES_MAX
)
659 yylval
.num
= DOWN_TRIES_MAX
;
660 else if(yylval
.num
< DOWN_TRIES_MIN
)
661 yylval
.num
= DOWN_TRIES_MIN
;
663 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: downtries = %d", entrycount
, yylval
.num
)));
664 cfg_entry_tab
[entrycount
].downtries
= yylval
.num
;
668 if(yylval
.num
> DOWN_TIME_MAX
)
669 yylval
.num
= DOWN_TIME_MAX
;
670 else if(yylval
.num
< DOWN_TIME_MIN
)
671 yylval
.num
= DOWN_TIME_MIN
;
673 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: downtime = %d", entrycount
, yylval
.num
)));
674 cfg_entry_tab
[entrycount
].downtime
= yylval
.num
;
678 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: earlyhangup = %d", entrycount
, yylval
.num
)));
679 cfg_entry_tab
[entrycount
].earlyhangup
= yylval
.num
;
683 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: extcallattr = %d", yylval
.booln
)));
684 extcallattr
= yylval
.booln
;
688 DBGL(DL_RCCF
, (dolog(LL_DBG
, "controller %d: firmware = %s", controllercount
, yylval
.str
)));
689 isdn_ctrl_tab
[controllercount
].firmware
= strdup(yylval
.str
);
693 strcpy(holidayfile
, yylval
.str
);
694 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: holidayfile = %s", yylval
.str
)));
698 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: idle-algorithm-outgoing = %s", entrycount
, yylval
.str
)));
700 if(!(strcmp(yylval
.str
, "fix-unit-size")))
702 cfg_entry_tab
[entrycount
].shorthold_algorithm
= SHA_FIXU
;
704 else if(!(strcmp(yylval
.str
, "var-unit-size")))
706 cfg_entry_tab
[entrycount
].shorthold_algorithm
= SHA_VARU
;
710 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"idle-algorithm-outgoing\" at line %d!", lineno
);
716 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: idle_time_in = %d", entrycount
, yylval
.num
)));
717 cfg_entry_tab
[entrycount
].idle_time_in
= yylval
.num
;
721 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: idle_time_out = %d", entrycount
, yylval
.num
)));
722 cfg_entry_tab
[entrycount
].idle_time_out
= yylval
.num
;
726 cfg_entry_tab
[entrycount
].isdncontroller
= yylval
.num
;
727 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: isdncontroller = %d", entrycount
, yylval
.num
)));
731 if (yylval
.num
== 0 || yylval
.num
== -1)
733 cfg_entry_tab
[entrycount
].isdnchannel
= CHAN_ANY
;
734 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: isdnchannel = any", entrycount
)));
736 else if (yylval
.num
> MAX_BCHAN
)
738 dolog(LL_DBG
, "entry %d: isdnchannel value out of range", entrycount
);
743 cfg_entry_tab
[entrycount
].isdnchannel
= yylval
.num
-1;
744 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: isdnchannel = B%d", entrycount
, yylval
.num
)));
749 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: isdntime = %d", yylval
.booln
)));
750 isdntime
= yylval
.booln
;
754 cfg_entry_tab
[entrycount
].isdntxdelin
= yylval
.num
;
755 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: isdntxdel-incoming = %d", entrycount
, yylval
.num
)));
759 cfg_entry_tab
[entrycount
].isdntxdelout
= yylval
.num
;
760 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: isdntxdel-outgoing = %d", entrycount
, yylval
.num
)));
763 case LOCAL_PHONE_DIALOUT
:
764 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: local_phone_dialout = %s", entrycount
, yylval
.str
)));
765 strcpy(cfg_entry_tab
[entrycount
].local_phone_dialout
, yylval
.str
);
768 case LOCAL_PHONE_INCOMING
:
769 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: local_phone_incoming = %s", entrycount
, yylval
.str
)));
770 strcpy(cfg_entry_tab
[entrycount
].local_phone_incoming
, yylval
.str
);
774 strcpy(mailer
, yylval
.str
);
775 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: mailer = %s", yylval
.str
)));
779 strcpy(mailto
, yylval
.str
);
780 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: mailto = %s", yylval
.str
)));
784 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: maxconnecttime = %d", entrycount
, yylval
.num
)));
785 cfg_entry_tab
[entrycount
].maxconnecttime
= yylval
.num
;
789 monitorport
= yylval
.num
;
790 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: monitorport = %d", yylval
.num
)));
794 if (yylval
.booln
&& inhibit_monitor
)
797 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: monitor-enable overridden by command line flag")));
801 do_monitor
= yylval
.booln
;
802 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: monitor-enable = %d", yylval
.booln
)));
807 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: name = %s", entrycount
, yylval
.str
)));
808 strcpy(cfg_entry_tab
[entrycount
].name
, yylval
.str
);
811 case PPP_AUTH_RECHALLENGE
:
812 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-auth-rechallenge = %d", entrycount
, yylval
.booln
)));
814 cfg_entry_tab
[entrycount
].ppp_auth_flags
|= AUTH_RECHALLENGE
;
816 cfg_entry_tab
[entrycount
].ppp_auth_flags
&= ~AUTH_RECHALLENGE
;
817 set_isppp_auth(entrycount
);
820 case PPP_AUTH_PARANOID
:
821 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-auth-paranoid = %d", entrycount
, yylval
.booln
)));
823 cfg_entry_tab
[entrycount
].ppp_auth_flags
|= AUTH_REQUIRED
;
825 cfg_entry_tab
[entrycount
].ppp_auth_flags
&= ~AUTH_REQUIRED
;
826 set_isppp_auth(entrycount
);
829 case PPP_EXPECT_AUTH
:
830 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-expect-auth = %s", entrycount
, yylval
.str
)));
831 if(!(strcmp(yylval
.str
, "none")))
832 cfg_entry_tab
[entrycount
].ppp_expect_auth
= AUTH_NONE
;
833 else if(!(strcmp(yylval
.str
, "pap")))
834 cfg_entry_tab
[entrycount
].ppp_expect_auth
= AUTH_PAP
;
835 else if(!(strcmp(yylval
.str
, "chap")))
836 cfg_entry_tab
[entrycount
].ppp_expect_auth
= AUTH_CHAP
;
839 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"ppp-expect-auth\" at line %d!", lineno
);
843 set_isppp_auth(entrycount
);
846 case PPP_EXPECT_NAME
:
847 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-expect-name = %s", entrycount
, yylval
.str
)));
848 strncpy(cfg_entry_tab
[entrycount
].ppp_expect_name
, yylval
.str
, sizeof(cfg_entry_tab
[entrycount
].ppp_expect_name
) -1);
849 set_isppp_auth(entrycount
);
852 case PPP_EXPECT_PASSWORD
:
853 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-expect-password = %s", entrycount
, yylval
.str
)));
854 strncpy(cfg_entry_tab
[entrycount
].ppp_expect_password
, yylval
.str
, sizeof(cfg_entry_tab
[entrycount
].ppp_expect_password
) -1);
855 set_isppp_auth(entrycount
);
859 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-send-auth = %s", entrycount
, yylval
.str
)));
860 if(!(strcmp(yylval
.str
, "none")))
861 cfg_entry_tab
[entrycount
].ppp_send_auth
= AUTH_NONE
;
862 else if(!(strcmp(yylval
.str
, "pap")))
863 cfg_entry_tab
[entrycount
].ppp_send_auth
= AUTH_PAP
;
864 else if(!(strcmp(yylval
.str
, "chap")))
865 cfg_entry_tab
[entrycount
].ppp_send_auth
= AUTH_CHAP
;
868 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"ppp-send-auth\" at line %d!", lineno
);
872 set_isppp_auth(entrycount
);
876 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-send-name = %s", entrycount
, yylval
.str
)));
877 strncpy(cfg_entry_tab
[entrycount
].ppp_send_name
, yylval
.str
, sizeof(cfg_entry_tab
[entrycount
].ppp_send_name
) -1);
878 set_isppp_auth(entrycount
);
881 case PPP_SEND_PASSWORD
:
882 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ppp-send-password = %s", entrycount
, yylval
.str
)));
883 strncpy(cfg_entry_tab
[entrycount
].ppp_send_password
, yylval
.str
, sizeof(cfg_entry_tab
[entrycount
].ppp_send_password
) -1);
884 set_isppp_auth(entrycount
);
888 DBGL(DL_RCCF
, (dolog(LL_DBG
, "controller %d: protocol = %s", controllercount
, yylval
.str
)));
889 if(!(strcmp(yylval
.str
, "dss1")))
890 isdn_ctrl_tab
[controllercount
].protocol
= PROTOCOL_DSS1
;
891 else if(!(strcmp(yylval
.str
, "d64s")))
892 isdn_ctrl_tab
[controllercount
].protocol
= PROTOCOL_D64S
;
895 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"protocol\" at line %d!", lineno
);
901 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: dialin_reaction = %s", entrycount
, yylval
.str
)));
902 if(!(strcmp(yylval
.str
, "accept")))
903 cfg_entry_tab
[entrycount
].dialin_reaction
= REACT_ACCEPT
;
904 else if(!(strcmp(yylval
.str
, "reject")))
905 cfg_entry_tab
[entrycount
].dialin_reaction
= REACT_REJECT
;
906 else if(!(strcmp(yylval
.str
, "ignore")))
907 cfg_entry_tab
[entrycount
].dialin_reaction
= REACT_IGNORE
;
908 else if(!(strcmp(yylval
.str
, "answer")))
909 cfg_entry_tab
[entrycount
].dialin_reaction
= REACT_ANSWER
;
910 else if(!(strcmp(yylval
.str
, "callback")))
911 cfg_entry_tab
[entrycount
].dialin_reaction
= REACT_CALLBACK
;
914 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"dialin_reaction\" at line %d!", lineno
);
919 case REMOTE_PHONE_DIALOUT
:
920 if(cfg_entry_tab
[entrycount
].remote_numbers_count
>= MAXRNUMBERS
)
922 dolog(LL_ERR
, "ERROR parsing config file: too many remote numbers at line %d!", lineno
);
927 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: remote_phone_dialout #%d = %s",
928 entrycount
, cfg_entry_tab
[entrycount
].remote_numbers_count
, yylval
.str
)));
930 strcpy(cfg_entry_tab
[entrycount
].remote_numbers
[cfg_entry_tab
[entrycount
].remote_numbers_count
].number
, yylval
.str
);
931 cfg_entry_tab
[entrycount
].remote_numbers
[cfg_entry_tab
[entrycount
].remote_numbers_count
].flag
= 0;
933 cfg_entry_tab
[entrycount
].remote_numbers_count
++;
937 case REMOTE_NUMBERS_HANDLING
:
938 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: remdial_handling = %s", entrycount
, yylval
.str
)));
939 if(!(strcmp(yylval
.str
, "next")))
940 cfg_entry_tab
[entrycount
].remote_numbers_handling
= RNH_NEXT
;
941 else if(!(strcmp(yylval
.str
, "last")))
942 cfg_entry_tab
[entrycount
].remote_numbers_handling
= RNH_LAST
;
943 else if(!(strcmp(yylval
.str
, "first")))
944 cfg_entry_tab
[entrycount
].remote_numbers_handling
= RNH_FIRST
;
947 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"remdial_handling\" at line %d!", lineno
);
952 case REMOTE_PHONE_INCOMING
:
955 n
= cfg_entry_tab
[entrycount
].incoming_numbers_count
;
956 if (n
>= MAX_INCOMING
)
958 dolog(LL_ERR
, "ERROR parsing config file: too many \"remote_phone_incoming\" entries at line %d!", lineno
);
962 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: remote_phone_incoming #%d = %s", entrycount
, n
, yylval
.str
)));
963 strcpy(cfg_entry_tab
[entrycount
].remote_phone_incoming
[n
].number
, yylval
.str
);
964 cfg_entry_tab
[entrycount
].incoming_numbers_count
++;
969 strcpy(ratesfile
, yylval
.str
);
970 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: ratesfile = %s", yylval
.str
)));
974 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: ratetype = %d", entrycount
, yylval
.num
)));
975 cfg_entry_tab
[entrycount
].ratetype
= yylval
.num
;
979 if(yylval
.num
< RECOVERYTIME_MIN
)
981 yylval
.num
= RECOVERYTIME_MIN
;
982 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: recoverytime < %d, min = %d", entrycount
, RECOVERYTIME_MIN
, yylval
.num
)));
985 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: recoverytime = %d", entrycount
, yylval
.num
)));
986 cfg_entry_tab
[entrycount
].recoverytime
= yylval
.num
;
990 if(nregexpr
>= MAX_RE
)
992 dolog(LL_ERR
, "system: regexpr #%d >= MAX_RE", nregexpr
);
997 if((i
= regcomp(&(rarr
[nregexpr
].re
), yylval
.str
, REG_EXTENDED
|REG_NOSUB
)) != 0)
1000 regerror(i
, &(rarr
[nregexpr
].re
), buf
, sizeof(buf
));
1001 dolog(LL_ERR
, "system: regcomp error for %s: [%s]", yylval
.str
, buf
);
1002 config_error_flag
++;
1007 if((rarr
[nregexpr
].re_expr
= malloc(strlen(yylval
.str
)+1)) == NULL
)
1009 dolog(LL_ERR
, "system: regexpr malloc error error for %s", yylval
.str
);
1010 config_error_flag
++;
1013 strcpy(rarr
[nregexpr
].re_expr
, yylval
.str
);
1015 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: regexpr %s stored into slot %d", yylval
.str
, nregexpr
)));
1017 if(rarr
[nregexpr
].re_prog
!= NULL
)
1018 rarr
[nregexpr
].re_flg
= 1;
1026 if(nregprog
>= MAX_RE
)
1028 dolog(LL_ERR
, "system: regprog #%d >= MAX_RE", nregprog
);
1029 config_error_flag
++;
1032 if((rarr
[nregprog
].re_prog
= malloc(strlen(yylval
.str
)+1)) == NULL
)
1034 dolog(LL_ERR
, "system: regprog malloc error error for %s", yylval
.str
);
1035 config_error_flag
++;
1038 strcpy(rarr
[nregprog
].re_prog
, yylval
.str
);
1040 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: regprog %s stored into slot %d", yylval
.str
, nregprog
)));
1042 if(rarr
[nregprog
].re_expr
!= NULL
)
1043 rarr
[nregprog
].re_flg
= 1;
1049 strcpy(rotatesuffix
, yylval
.str
);
1050 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: rotatesuffix = %s", yylval
.str
)));
1055 rt_prio
= yylval
.num
;
1056 if(rt_prio
< RTP_PRIO_MIN
|| rt_prio
> RTP_PRIO_MAX
)
1058 config_error_flag
++;
1059 dolog(LL_ERR
, "system: error, rtprio (%d) out of range!", yylval
.num
);
1063 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: rtprio = %d", yylval
.num
)));
1066 rt_prio
= RTPRIO_NOTUSED
;
1071 strcpy(tinainitprog
, yylval
.str
);
1072 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: tinainitprog = %s", yylval
.str
)));
1076 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: unitlength = %d", entrycount
, yylval
.num
)));
1077 cfg_entry_tab
[entrycount
].unitlength
= yylval
.num
;
1081 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: unitlengthsrc = %s", entrycount
, yylval
.str
)));
1082 if(!(strcmp(yylval
.str
, "none")))
1083 cfg_entry_tab
[entrycount
].unitlengthsrc
= ULSRC_NONE
;
1084 else if(!(strcmp(yylval
.str
, "cmdl")))
1085 cfg_entry_tab
[entrycount
].unitlengthsrc
= ULSRC_CMDL
;
1086 else if(!(strcmp(yylval
.str
, "conf")))
1087 cfg_entry_tab
[entrycount
].unitlengthsrc
= ULSRC_CONF
;
1088 else if(!(strcmp(yylval
.str
, "rate")))
1089 cfg_entry_tab
[entrycount
].unitlengthsrc
= ULSRC_RATE
;
1090 else if(!(strcmp(yylval
.str
, "aocd")))
1091 cfg_entry_tab
[entrycount
].unitlengthsrc
= ULSRC_DYN
;
1094 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"unitlengthsrc\" at line %d!", lineno
);
1095 config_error_flag
++;
1100 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: usrdevicename = %s", entrycount
, yylval
.str
)));
1101 if(!strcmp(yylval
.str
, "rbch"))
1102 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_RBCH
;
1103 else if(!strcmp(yylval
.str
, "tel"))
1104 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_TEL
;
1105 else if(!strcmp(yylval
.str
, "ipr"))
1106 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_IPR
;
1107 else if(!strcmp(yylval
.str
, "isp"))
1108 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_ISPPP
;
1110 else if(!strcmp(yylval
.str
, "ibc"))
1111 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_IBC
;
1113 else if(!strcmp(yylval
.str
, "ing"))
1114 cfg_entry_tab
[entrycount
].usrdevicename
= BDRV_ING
;
1117 dolog(LL_ERR
, "ERROR parsing config file: unknown parameter for keyword \"usrdevicename\" at line %d!", lineno
);
1118 config_error_flag
++;
1123 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: usrdeviceunit = %d", entrycount
, yylval
.num
)));
1124 cfg_entry_tab
[entrycount
].usrdeviceunit
= yylval
.num
;
1128 useacctfile
= yylval
.booln
;
1129 DBGL(DL_RCCF
, (dolog(LL_DBG
, "system: useacctfile = %d", yylval
.booln
)));
1133 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: usedown = %d", entrycount
, yylval
.booln
)));
1134 cfg_entry_tab
[entrycount
].usedown
= yylval
.booln
;
1138 DBGL(DL_RCCF
, (dolog(LL_DBG
, "entry %d: valid = %s", entrycount
, yylval
.str
)));
1139 parse_valid(entrycount
, yylval
.str
);
1143 dolog(LL_ERR
, "ERROR parsing config file: unknown keyword at line %d!", lineno
);
1144 config_error_flag
++;
1149 /*---------------------------------------------------------------------------*
1150 * parse a date/time range
1151 *---------------------------------------------------------------------------*/
1153 parse_valid(int entrycount
, char *dt
)
1155 /* a valid string consists of some days of week separated by
1156 * commas, where 0=sunday, 1=monday .. 6=saturday and a special
1157 * value of 7 which is a holiday from the holiday file.
1158 * after the days comes an optional (!) time range in the form
1159 * aa:bb-cc:dd, this format is fixed to be parsable by sscanf.
1160 * Valid specifications looks like this:
1161 * 1,2,3,4,5,09:00-18:00 Monday-Friday 9-18h
1162 * 1,2,3,4,5,18:00-09:00 Monday-Friday 18-9h
1163 * 6 Saturday (whole day)
1164 * 0,7 Sunday and Holidays
1176 if( ( ((*dt
>= '0') && (*dt
<= '9')) && (*(dt
+1) == ':') ) ||
1177 ( ((*dt
>= '0') && (*dt
<= '2')) && ((*(dt
+1) >= '0') && (*(dt
+1) <= '9')) && (*(dt
+2) == ':') ) )
1179 /* dt points to time spec */
1180 ret
= sscanf(dt
, "%d:%d-%d:%d", &fromhr
, &frommin
, &tohr
, &tomin
);
1183 dolog(LL_ERR
, "ERROR parsing config file: timespec [%s] error at line %d!", *dt
, lineno
);
1184 config_error_flag
++;
1188 if(fromhr
< 0 || fromhr
> 24 || tohr
< 0 || tohr
> 24 ||
1189 frommin
< 0 || frommin
> 59 || tomin
< 0 || tomin
> 59)
1191 dolog(LL_ERR
, "ERROR parsing config file: invalid time [%s] at line %d!", *dt
, lineno
);
1192 config_error_flag
++;
1197 else if ((*dt
>= '0') && (*dt
<= '7'))
1199 /* dt points to day spec */
1200 day
|= 1 << (*dt
- '0');
1204 else if (*dt
== ',')
1206 /* dt points to delimiter */
1210 else if (*dt
== '\0')
1212 /* dt points to end of string */
1217 /* dt points to illegal character */
1218 dolog(LL_ERR
, "ERROR parsing config file: illegal character [%c=0x%x] in date/time spec at line %d!", *dt
, *dt
, lineno
);
1219 config_error_flag
++;
1223 cfg_entry_tab
[entrycount
].day
= day
;
1224 cfg_entry_tab
[entrycount
].fromhr
= fromhr
;
1225 cfg_entry_tab
[entrycount
].frommin
= frommin
;
1226 cfg_entry_tab
[entrycount
].tohr
= tohr
;
1227 cfg_entry_tab
[entrycount
].tomin
= tomin
;
1230 /*---------------------------------------------------------------------------*
1231 * configuration validation and consistency check
1232 *---------------------------------------------------------------------------*/
1236 cfg_entry_t
*cep
= &cfg_entry_tab
[0]; /* ptr to config entry */
1240 /* regular expression table */
1242 for(i
=0; i
< MAX_RE
; i
++)
1244 if((rarr
[i
].re_expr
!= NULL
) && (rarr
[i
].re_prog
== NULL
))
1246 dolog(LL_ERR
, "check_config: regular expression %d without program!", i
);
1249 if((rarr
[i
].re_prog
!= NULL
) && (rarr
[i
].re_expr
== NULL
))
1251 dolog(LL_ERR
, "check_config: regular expression program %d without expression!", i
);
1256 /* entry sections */
1258 for(i
=0; i
<= entrycount
; i
++, cep
++)
1260 /* isdn controller number */
1262 if((cep
->isdncontroller
< -1) || (cep
->isdncontroller
> (ncontroller
-1)))
1264 dolog(LL_ERR
, "check_config: WARNING, isdncontroller out of range in entry %d!", i
);
1267 /* numbers used for dialout */
1269 if((cep
->inout
!= DIR_INONLY
) && (cep
->dialin_reaction
!= REACT_ANSWER
))
1271 if(cep
->remote_numbers_count
== 0)
1273 dolog(LL_ERR
, "check_config: remote-phone-dialout not set in entry %d!", i
);
1276 if(strlen(cep
->local_phone_dialout
) == 0)
1278 dolog(LL_ERR
, "check_config: local-phone-dialout not set in entry %d!", i
);
1283 /* numbers used for incoming calls */
1285 if(cep
->inout
!= DIR_OUTONLY
)
1287 if(strlen(cep
->local_phone_incoming
) == 0)
1289 dolog(LL_ERR
, "check_config: local-phone-incoming not set in entry %d!", i
);
1292 if(cep
->incoming_numbers_count
== 0)
1294 dolog(LL_ERR
, "check_config: remote-phone-incoming not set in entry %d!", i
);
1299 if((cep
->dialin_reaction
== REACT_ANSWER
) && (cep
->b1protocol
!= BPROT_NONE
))
1301 dolog(LL_ERR
, "check_config: b1protocol not raw for telephony in entry %d!", i
);
1305 if((cep
->ppp_send_auth
== AUTH_PAP
) || (cep
->ppp_send_auth
== AUTH_CHAP
))
1307 if(cep
->ppp_send_name
[0] == 0)
1309 dolog(LL_ERR
, "check_config: no remote authentification name in entry %d!", i
);
1312 if(cep
->ppp_send_password
[0] == 0)
1314 dolog(LL_ERR
, "check_config: no remote authentification password in entry %d!", i
);
1318 if((cep
->ppp_expect_auth
== AUTH_PAP
) || (cep
->ppp_expect_auth
== AUTH_CHAP
))
1320 if(cep
->ppp_expect_name
[0] == 0)
1322 dolog(LL_ERR
, "check_config: no local authentification name in entry %d!", i
);
1325 if(cep
->ppp_expect_password
[0] == 0)
1327 dolog(LL_ERR
, "check_config: no local authentification secret in entry %d!", i
);
1334 dolog(LL_ERR
, "check_config: %d error(s) in configuration file, exit!", error
);
1339 /*---------------------------------------------------------------------------*
1340 * print the configuration
1341 *---------------------------------------------------------------------------*/
1345 #define PFILE stdout
1347 #ifdef I4B_EXTERNAL_MONITOR
1348 extern struct monitor_rights
* monitor_next_rights(const struct monitor_rights
*r
);
1349 struct monitor_rights
*m_rights
;
1351 cfg_entry_t
*cep
= &cfg_entry_tab
[0]; /* ptr to config entry */
1357 strcpy(mytime
, ctime(&clock
));
1358 mytime
[strlen(mytime
)-1] = '\0';
1360 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1361 fprintf(PFILE
, "# system section (generated %s)\n", mytime
);
1362 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1363 fprintf(PFILE
, "system\n");
1364 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");
1365 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");
1366 fprintf(PFILE
, "acctfile = %s\t\t# accounting information file\n", acctfile
);
1367 fprintf(PFILE
, "ratesfile = %s\t\t# charging rates database file\n", ratesfile
);
1370 if(rt_prio
== RTPRIO_NOTUSED
)
1371 fprintf(PFILE
, "# rtprio is unused\n");
1373 fprintf(PFILE
, "rtprio = %d\t\t\t\t# isdnd runs at realtime priority\n", rt_prio
);
1376 /* regular expression table */
1378 for(i
=0; i
< MAX_RE
; i
++)
1380 if(rarr
[i
].re_expr
!= NULL
)
1382 fprintf(PFILE
, "regexpr = \"%s\"\t\t# scan logfile for this expression\n", rarr
[i
].re_expr
);
1384 if(rarr
[i
].re_prog
!= NULL
)
1386 fprintf(PFILE
, "regprog = %s\t\t# program to run when expression is matched\n", rarr
[i
].re_prog
);
1390 #ifdef I4B_EXTERNAL_MONITOR
1392 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");
1393 fprintf(PFILE
, "monitor-port = %d\t\t\t\t# TCP/IP port number used for remote monitoring\n", monitorport
);
1395 m_rights
= monitor_next_rights(NULL
);
1396 if(m_rights
!= NULL
)
1398 char *s
= "error\n";
1401 for ( ; m_rights
!= NULL
; m_rights
= monitor_next_rights(m_rights
))
1405 fprintf(PFILE
, "monitor = \"%s\"\t\t# local socket name for monitoring\n", m_rights
->name
);
1410 ia
.s_addr
= ntohl(m_rights
->net
);
1412 switch(m_rights
->mask
)
1514 fprintf(PFILE
, "monitor = \"%s/%s\"\t\t# host (net/mask) allowed to connect for monitoring\n", inet_ntoa(ia
), s
);
1518 if((m_rights
->rights
) & I4B_CA_COMMAND_FULL
)
1519 strcat(b
, "fullcmd,");
1520 if((m_rights
->rights
) & I4B_CA_COMMAND_RESTRICTED
)
1521 strcat(b
, "restrictedcmd,");
1522 if((m_rights
->rights
) & I4B_CA_EVNT_CHANSTATE
)
1523 strcat(b
, "channelstate,");
1524 if((m_rights
->rights
) & I4B_CA_EVNT_CALLIN
)
1525 strcat(b
, "callin,");
1526 if((m_rights
->rights
) & I4B_CA_EVNT_CALLOUT
)
1527 strcat(b
, "callout,");
1528 if((m_rights
->rights
) & I4B_CA_EVNT_I4B
)
1529 strcat(b
, "logevents,");
1531 if(b
[strlen(b
)-1] == ',')
1532 b
[strlen(b
)-1] = '\0';
1534 fprintf(PFILE
, "monitor-access = %s\t\t# monitor access rights\n", b
);
1539 /* entry sections */
1541 for(i
=0; i
<= entrycount
; i
++, cep
++)
1543 fprintf(PFILE
, "\n");
1544 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1545 fprintf(PFILE
, "# entry section %d\n", i
);
1546 fprintf(PFILE
, "#---------------------------------------------------------------------------\n");
1547 fprintf(PFILE
, "entry\n");
1549 fprintf(PFILE
, "name = %s\t\t# name for this entry section\n", cep
->name
);
1551 fprintf(PFILE
, "isdncontroller = %d\t\t# ISDN card number used for this entry\n", cep
->isdncontroller
);
1552 fprintf(PFILE
, "isdnchannel = ");
1553 switch(cep
->isdnchannel
)
1556 fprintf(PFILE
, "-1\t\t# any ISDN B-channel may be used\n");
1559 fprintf(PFILE
, "%d\t\t# only ISDN B-channel %d may be used\n", cep
->isdnchannel
+1, cep
->isdnchannel
+1);
1563 fprintf(PFILE
, "usrdevicename = %s\t\t# name of userland ISDN B-channel device\n", bdrivername(cep
->usrdevicename
));
1564 fprintf(PFILE
, "usrdeviceunit = %d\t\t# unit number of userland ISDN B-channel device\n", cep
->usrdeviceunit
);
1566 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");
1568 if(!(cep
->usrdevicename
== BDRV_TEL
))
1570 fprintf(PFILE
, "direction = ");
1574 fprintf(PFILE
, "in\t\t# only incoming connections allowed\n");
1577 fprintf(PFILE
, "out\t\t# only outgoing connections allowed\n");
1580 fprintf(PFILE
, "inout\t\t# incoming and outgoing connections allowed\n");
1585 if(!((cep
->usrdevicename
== BDRV_TEL
) || (cep
->inout
== DIR_INONLY
)))
1587 if(cep
->remote_numbers_count
> 1)
1589 for(j
=0; j
<cep
->remote_numbers_count
; j
++)
1590 fprintf(PFILE
, "remote-phone-dialout = %s\t\t# telephone number %d for dialing out to remote\n", cep
->remote_numbers
[j
].number
, j
+1);
1592 fprintf(PFILE
, "remdial-handling = ");
1594 switch(cep
->remote_numbers_handling
)
1597 fprintf(PFILE
, "next\t\t# use next number after last successful for new dial\n");
1600 fprintf(PFILE
, "last\t\t# use last successful number for new dial\n");
1603 fprintf(PFILE
, "first\t\t# always start with first number for new dial\n");
1609 fprintf(PFILE
, "remote-phone-dialout = %s\t\t# telephone number for dialing out to remote\n", cep
->remote_numbers
[0].number
);
1612 fprintf(PFILE
, "local-phone-dialout = %s\t\t# show this number to remote when dialling out\n", cep
->local_phone_dialout
);
1613 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");
1616 if(!(cep
->inout
== DIR_OUTONLY
))
1620 fprintf(PFILE
, "local-phone-incoming = %s\t\t# incoming calls must match this (mine) telephone number\n", cep
->local_phone_incoming
);
1621 for (n
= 0; n
< cep
->incoming_numbers_count
; n
++)
1622 fprintf(PFILE
, "remote-phone-incoming = %s\t\t# this is a valid remote number to call me\n",
1623 cep
->remote_phone_incoming
[n
].number
);
1625 fprintf(PFILE
, "dialin-reaction = ");
1626 switch(cep
->dialin_reaction
)
1629 fprintf(PFILE
, "accept\t\t# i accept a call from remote and connect\n");
1632 fprintf(PFILE
, "reject\t\t# i reject the call from remote\n");
1635 fprintf(PFILE
, "ignore\t\t# i ignore the call from remote\n");
1638 fprintf(PFILE
, "answer\t\t# i will start telephone answering when remote calls in\n");
1640 case REACT_CALLBACK
:
1641 fprintf(PFILE
, "callback\t\t# when remote calls in, i will hangup and call back\n");
1646 if(cep
->usrdevicename
== BDRV_ISPPP
)
1649 switch(cep
->ppp_expect_auth
)
1666 fprintf(PFILE
, "ppp-expect-auth = %s\t\t# the auth protocol we expect to receive on dial-in (none,pap,chap)\n", s
);
1667 if(cep
->ppp_expect_auth
!= AUTH_NONE
)
1669 fprintf(PFILE
, "ppp-expect-name = %s\t\t# the user name allowed in\n", cep
->ppp_expect_name
);
1670 fprintf(PFILE
, "ppp-expect-password = %s\t\t# the key expected from the other side\n", cep
->ppp_expect_password
);
1671 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");
1674 switch(cep
->ppp_send_auth
)
1691 fprintf(PFILE
, "ppp-send-auth = %s\t\t# the auth protocol we use when dialing out (none,pap,chap)\n", s
);
1692 if(cep
->ppp_send_auth
!= AUTH_NONE
)
1694 fprintf(PFILE
, "ppp-send-name = %s\t\t# our PPP account used for dial-out\n", cep
->ppp_send_name
);
1695 fprintf(PFILE
, "ppp-send-password = %s\t\t# the key sent to the other side\n", cep
->ppp_send_password
);
1698 if(cep
->ppp_send_auth
== AUTH_CHAP
||
1699 cep
->ppp_expect_auth
== AUTH_CHAP
) {
1700 fprintf(PFILE
, "ppp-auth-rechallenge = %s\t\t# rechallenge CHAP connections once in a while\n", cep
->ppp_auth_flags
& AUTH_RECHALLENGE
? "yes" : "no");
1704 if(!((cep
->inout
== DIR_INONLY
) || (cep
->usrdevicename
== BDRV_TEL
)))
1707 fprintf(PFILE
, "idletime-outgoing = %d\t\t# outgoing call idle timeout\n", cep
->idle_time_out
);
1709 switch( cep
->shorthold_algorithm
)
1712 s
= "fix-unit-size";
1715 s
= "var-unit-size";
1722 fprintf(PFILE
, "idle-algorithm-outgoing = %s\t\t# outgoing call idle algorithm\n", s
);
1725 if(!(cep
->inout
== DIR_OUTONLY
))
1726 fprintf(PFILE
, "idletime-incoming = %d\t\t# incoming call idle timeout\n", cep
->idle_time_in
);
1728 if(!(cep
->usrdevicename
== BDRV_TEL
))
1730 fprintf(PFILE
, "unitlengthsrc = ");
1731 switch(cep
->unitlengthsrc
)
1734 fprintf(PFILE
, "none\t\t# no unit length specified, using default\n");
1737 fprintf(PFILE
, "cmdl\t\t# using unit length specified on commandline\n");
1740 fprintf(PFILE
, "conf\t\t# using unitlength specified by unitlength-keyword\n");
1741 fprintf(PFILE
, "unitlength = %d\t\t# fixed unitlength\n", cep
->unitlength
);
1744 fprintf(PFILE
, "rate\t\t# using unitlength specified in rate database\n");
1745 fprintf(PFILE
, "ratetype = %d\t\t# type of rate from rate database\n", cep
->ratetype
);
1748 fprintf(PFILE
, "aocd\t\t# using dynamically calculated unitlength based on AOCD subscription\n");
1749 fprintf(PFILE
, "ratetype = %d\t\t# type of rate from rate database\n", cep
->ratetype
);
1753 fprintf(PFILE
, "earlyhangup = %d\t\t# early hangup safety time\n", cep
->earlyhangup
);
1757 if(cep
->usrdevicename
== BDRV_TEL
)
1759 fprintf(PFILE
, "answerprog = %s\t\t# program used to answer incoming telephone calls\n", cep
->answerprog
);
1760 fprintf(PFILE
, "alert = %d\t\t# number of seconds to wait before accepting a call\n", cep
->alert
);
1763 if(!(cep
->usrdevicename
== BDRV_TEL
))
1765 if(cep
->dialin_reaction
== REACT_CALLBACK
)
1766 fprintf(PFILE
, "callbackwait = %d\t\t# i am waiting this time before calling back remote\n", cep
->callbackwait
);
1768 if(cep
->dialouttype
== DIALOUT_CALLEDBACK
)
1769 fprintf(PFILE
, "calledbackwait = %d\t\t# i am waiting this time for a call back from remote\n", cep
->calledbackwait
);
1771 if(!(cep
->inout
== DIR_INONLY
))
1773 fprintf(PFILE
, "dialretries = %d\t\t# number of dialing retries\n", cep
->dialretries
);
1774 fprintf(PFILE
, "recoverytime = %d\t\t# time to wait between dialling retries\n", cep
->recoverytime
);
1775 fprintf(PFILE
, "dialrandincr = %s\t\t# use random dialing time addon\n", cep
->dialrandincr
? "on" : "off");
1777 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");
1780 fprintf(PFILE
, "downtries = %d\t\t# number of dialretries failures before switching off\n", cep
->downtries
);
1781 fprintf(PFILE
, "downtime = %d\t\t# time device is switched off\n", cep
->downtime
);
1786 fprintf(PFILE
, "\n");