Added 'extern' flag to interface.conf.
[lcr.git] / route.c
1 /*****************************************************************************\ 
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** match processing of routing configuration                                 **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14
15 struct route_ruleset    *ruleset_first;         /* first entry */
16 struct route_ruleset    *ruleset_main;          /* pointer to main ruleset */
17
18 struct cond_defs cond_defs[] = {
19         { "extern",     MATCH_EXTERN,   COND_TYPE_NULL,
20           "extern", "Matches if call is from external port (no extension)."},
21         { "intern",     MATCH_INTERN,COND_TYPE_NULL,
22           "intern", "Matches if call is from an extension."},
23         { "port",       MATCH_PORT,     COND_TYPE_INTEGER,
24           "port=<number>[-<number>][,...]", "Matches if call is received from given port(s). NOT INTERFACE!"},
25         { "interface",  MATCH_INTERFACE,COND_TYPE_STRING,
26           "interface=<interface>[,...]", "Matches if call is received from given interface(s). NOT PORTS!"},
27         { "callerid",   MATCH_CALLERID, COND_TYPE_STRING,
28           "callerid=<digits>[-<digits>][,...]", "Matches if caller ID matches or begins with the given (range(s) of) prefixes(s)."},
29         { "callerid2",  MATCH_CALLERID2,COND_TYPE_STRING,
30           "callerid2=<digits>[-<digits>][,...]", "Matches the second caller ID (network provided)."},
31         { "extension",  MATCH_EXTENSION,COND_TYPE_STRING,
32           "extension=<digits>[-<digits>][,...]", "Matches if caller calls from given (range(s) of) extension(s)."},
33         { "dialing",    MATCH_DIALING,  COND_TYPE_STRING,
34           "dialing=<digits>[-<digits>][,...]", "Matches if caller has dialed the given (range(s) of) digits at least."},
35         { "enblock",    MATCH_ENBLOCK,  COND_TYPE_NULL,
36           "enblock", "Matches if caller dialed en block. (Dial the number before pick up.)"},
37         { "overlap",    MATCH_OVERLAP,  COND_TYPE_NULL,
38           "overlap", "Matches if caller dialed digit by digit. (Dial the number after pick up.)"},
39         { "anonymous",  MATCH_ANONYMOUS,COND_TYPE_NULL,
40           "anonymous", "Matches if caller uses restricted caller ID or if not available."},
41         { "visible",    MATCH_VISIBLE,  COND_TYPE_NULL,
42           "visible", "Matches if caller ID is presented and if available."},
43         { "unknown",    MATCH_UNKNOWN,  COND_TYPE_NULL,
44           "unknown", "Matches if no ID is available from caller."},
45         { "available",  MATCH_AVAILABLE,COND_TYPE_NULL,
46           "available", "Matches if ID is available from caller."},
47         { "fake",       MATCH_FAKE,     COND_TYPE_NULL,
48           "fake", "Matches if caller ID is not screened and may be faked by caller."},
49         { "real",       MATCH_REAL,     COND_TYPE_NULL,
50           "real", "Matches if caller ID is screend and so it is the real caller's ID."},
51         { "redirected", MATCH_REDIRECTED,COND_TYPE_NULL,
52           "redirected", "Matches if caller has been redirected."},
53         { "direct",     MATCH_DIRECT    ,COND_TYPE_NULL,
54           "direct", "Matches if caller did not come from an redirection."},
55         { "redirid",    MATCH_REDIRID   ,COND_TYPE_STRING,
56           "redirid=<digits>[-<digits>][,...]", "Matches if the caller has been redirected by the given (range(s) of) ID(s) or prefix(es))"},
57         { "time",       MATCH_TIME,     COND_TYPE_TIME,
58           "time=<minutes>[-<minutes>][,...]", "Matches if the caller calls within the given (range(s) of) time(s). (e.g. 0700-1900)"},
59         { "mday",       MATCH_MDAY,     COND_TYPE_MDAY,
60           "mday=<day>[-<day>][,...]", "Matches if the caller calls within the given (range(s) of) day(s) of the month. (1..31)"},
61         { "month",      MATCH_MONTH,    COND_TYPE_MONTH,
62           "month=<month>[-<month>][,...]", "Matches if the caller calls within the given (range(s) of) month(s). (1=January..12=December)"},
63         { "year",       MATCH_YEAR,     COND_TYPE_YEAR,
64           "year=<year>[-<year>][,...]", "Matches if the caller calls within the given (range(s) of) year(s). (1970..2106)"},
65         { "wday",       MATCH_WDAY,     COND_TYPE_WDAY,
66           "wday=<day>[-<day>][,...]", "Matches if the caller calls within the given (range(s) of) weekday(s). (1=Monday..7=Sunday)"},
67         { "capability", MATCH_CAPABILITY, COND_TYPE_CAPABILITY,
68           "capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones[,...]", "Matches the given bearer capability(s)."},
69         { "infolayer1", MATCH_INFOLAYER1, COND_TYPE_INTEGER,
70           "infolayer1=<value>[,...]", "Matches the given information layer 1. (2=u-Law, 3=a-law, see info layer 1 in bearer capability.)"},
71         { "hlc",        MATCH_HLC,      COND_TYPE_INTEGER,
72           "hlc=<value>[,...]", "Matches the high layer capability(s)."},
73         { "file",       MATCH_FILE,     COND_TYPE_STRING,
74           "file=<path>[,...]", "Mathes is the given file exists and if the first character is '1'."},
75         { "execute",    MATCH_EXECUTE,  COND_TYPE_STRING,
76           "execute=<command>[,...]","Matches if the return value of the given command is greater 0."},
77         { "default",    MATCH_DEFAULT,  COND_TYPE_NULL,
78           "default","Matches if no further dialing could match."},
79         { "timeout",    MATCH_TIMEOUT,  COND_TYPE_INTEGER,
80           "timeout=<seconds>","Matches if the ruleset was entered AFTER given seconds."},
81         { "free",       MATCH_FREE,     COND_TYPE_IFATTR,
82           "free=<interface>:<channel>","Matches if the given minimum of channels are free."},
83         { "notfree",    MATCH_NOTFREE,  COND_TYPE_IFATTR,
84           "notfree=<interface>:<channel>","Matches if NOT the given minimum of channels are free."},
85         { "blocked",    MATCH_DOWN,     COND_TYPE_STRING,
86           "blocked=<interfaces>[,...]","Matches if all of the given interfaces are blocked."},
87         { "idle",       MATCH_UP,       COND_TYPE_STRING,
88           "idle=<interface>[,...]","Matches if any of the given interfaces is idle."},
89         { "busy",       MATCH_BUSY,     COND_TYPE_STRING,
90           "busy=<extension>[,...]","Matches if any of the given extension is busy."},
91         { "notbusy",    MATCH_IDLE,     COND_TYPE_STRING,
92           "notbusy=<extension>[,...]","Matches if any of the given extension is not busy."},
93         { "remote",     MATCH_REMOTE,   COND_TYPE_STRING,
94           "remote=<application name>","Matches if remote application is running."},
95         { "notremote",  MATCH_NOTREMOTE,COND_TYPE_STRING,
96           "notremote=<application name>","Matches if remote application is not running."},
97         { NULL, 0, 0, NULL}
98 };
99
100 struct param_defs param_defs[] = {
101         { PARAM_PROCEEDING,
102           "proceeding", PARAM_TYPE_NULL,
103           "proceeding", "Will set the call into 'proceeding' state to prevent dial timeout."},
104         { PARAM_ALERTING,
105           "alerting",   PARAM_TYPE_NULL,
106           "alerting", "Will set the call into 'altering' state."},
107         { PARAM_CONNECT,
108           "connect",    PARAM_TYPE_NULL,
109           "connect", "Will complete the call before processing the action. Audio path for external calls will be established."},
110         { PARAM_EXTENSION,
111           "extension",  PARAM_TYPE_STRING,
112           "extension=<digits>", "Give extension name (digits) to relate this action to."},
113         { PARAM_EXTENSIONS,
114           "extensions", PARAM_TYPE_STRING,
115           "extensions=<extension>[,<extension>[,...]]", "One or more extensions may be given."},
116         { PARAM_PREFIX,
117           "prefix",     PARAM_TYPE_STRING,
118           "prefix=<digits>", "Add prefix in front of the dialed number."},
119         { PARAM_CAPA,
120           "capability", PARAM_TYPE_CAPABILITY,
121           "capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones", "Alter the service type of the call."},
122         { PARAM_BMODE,
123           "bmode",      PARAM_TYPE_BMODE,
124           "bmode=transparent|hdlc", "Alter the bchannel mode of the call. Use hdlc for data calls."},
125         { PARAM_INFO1,
126           "infolayer1", PARAM_TYPE_INTEGER,
127           "infolayer1=<value>", "Alter the layer 1 information of a call. Use 3 for ALAW or 2 for uLAW."},
128         { PARAM_HLC,
129           "hlc",        PARAM_TYPE_INTEGER,
130           "hlc=<value>", "Alter the HLC identification. Use 1 for telephony or omit."},
131         { PARAM_EXTHLC,
132           "exthlc",     PARAM_TYPE_INTEGER,
133           "exthlc=<value>", "Alter extended HLC value. (Mainenance only, don't use it.)"},
134         { PARAM_PRESENT,
135           "present",    PARAM_TYPE_YESNO,
136           "present=yes|no", "Allow or restrict caller ID regardless what the caller wants."},
137         { PARAM_DIVERSION,
138           "diversion",  PARAM_TYPE_DIVERSION,
139           "diversion=cfu|cfnr|cfb|cfp", "Set diversion type."},
140         { PARAM_DEST,
141           "dest",       PARAM_TYPE_DESTIN,
142           "dest=<string>", "Destination number to divert to. Use 'vbox' to divert to vbox. (cfu,cfnr,cfb only)"},
143         { PARAM_SELECT,
144           "select",     PARAM_TYPE_NULL,
145           "select", "Lets the caller select the history of calls using keys '1'/'3' or '*'/'#'."},
146         { PARAM_DELAY,
147           "delay",      PARAM_TYPE_INTEGER,
148           "delay=<seconds>", "Number of seconds to delay."},
149         { PARAM_LIMIT,
150           "limit",      PARAM_TYPE_INTEGER,
151           "limit=<retries>", "Number of maximum retries."},
152         { PARAM_HOST,
153           "host",       PARAM_TYPE_STRING,
154           "host=<string>", "Name of remote VoIP host."},
155         { PARAM_PORT,
156           "port",       PARAM_TYPE_STRING,
157           "port=<value>", "Alternate port to use if 'host' is given."},
158         { PARAM_INTERFACES,
159           "interfaces", PARAM_TYPE_STRING,
160           "interfaces=<interface>[,<interface>[,...]]", "Give one or a list of Interfaces to select a free channel from."},
161         { PARAM_ADDRESS,
162           "address",    PARAM_TYPE_STRING,
163           "address=<string>", "Complete VoIP address. ( [user@]host[:port] )"},
164         { PARAM_SAMPLE,
165           "sample",     PARAM_TYPE_STRING,
166           "sample=<file prefix>", "Filename of sample (current tone's dir) or full path to sample. ('.wav'/'.wave'/'.isdn' is added automatically."},
167         { PARAM_ANNOUNCEMENT,
168           "announcement",PARAM_TYPE_STRING,
169           "announcement=<file prefix>", "Filename of announcement (inside vbox recording dir) or full path to sample. ('.wav'/'.wave'/'.isdn' is added automatically."},
170         { PARAM_RULESET,
171           "ruleset",    PARAM_TYPE_STRING,
172           "ruleset=<name>", "Ruleset to go to."},
173         { PARAM_CAUSE,
174           "cause",      PARAM_TYPE_INTEGER,
175           "cause=<cause value>", "Cause value when disconnecting. (21=reject 1=unassigned 63=service not available)"},
176         { PARAM_LOCATION,
177           "location",   PARAM_TYPE_INTEGER,
178           "location=<location value>", "Location of cause value when disconnecting. (0=user 1=private network sering local user)"},
179         { PARAM_DISPLAY,
180           "display",    PARAM_TYPE_STRING,
181           "display=<text>", "Message to display on the caller's telephone. (internal only)"},
182         { PARAM_PORTS,
183           "ports",      PARAM_TYPE_INTEGER,
184           "ports=<port>[,<port>[,...]]", "ISDN port[s] to use."},
185         { PARAM_TPRESET,
186           "tpreset",    PARAM_TYPE_INTEGER,
187           "tpreset=<seconds>", "Preset of countdown timer."},
188         { PARAM_FILE,
189           "file",       PARAM_TYPE_STRING,
190           "file=<full path>", "Full path to file name."},
191         { PARAM_CONTENT,
192           "content",    PARAM_TYPE_STRING,
193           "content=<string>", "Content to write into file."},
194         { PARAM_APPEND,
195           "append",     PARAM_TYPE_NULL,
196           "append", "Will append to given file, rather than overwriting it."},
197         { PARAM_EXECUTE,
198           "execute",    PARAM_TYPE_STRING,
199           "execute=<full path>", "Full path to script/command name. (Dialed digits are the argument 1.)"},
200         { PARAM_PARAM,
201           "param",      PARAM_TYPE_STRING,
202           "param=<string>", "Optionally this parameter can be inserted as argument 1, others are shifted."},
203         { PARAM_TYPE,
204           "type",       PARAM_TYPE_TYPE,
205           "type=unknown|subscriber|national|international", "Type of number to dial, default is 'unknown'."},
206         { PARAM_COMPLETE,
207           "complete",   PARAM_TYPE_NULL,
208           "complete", "Indicates complete number as given by prefix. Proceeding of long distance calls may be faster."},
209         { PARAM_CALLERID,
210           "callerid",   PARAM_TYPE_STRING,
211           "callerid=<digits>", "Change caller ID to given string."},
212         { PARAM_CALLERIDTYPE,
213           "calleridtype",PARAM_TYPE_CALLERIDTYPE,
214           "calleridtype=[unknown|subscriber|national|international]", "Type of caller ID. For normal MSN use 'unknown'"},
215         { PARAM_CALLTO,
216           "callto",     PARAM_TYPE_STRING,
217           "callto=<digits>", "Where to call back. By default the caller ID is used."},
218         { PARAM_ROOM,
219           "room",       PARAM_TYPE_INTEGER,
220           "room=<digits>", "Conference room number, must be greater 0, as in real life."},
221         { PARAM_JINGLE,
222           "jingle",     PARAM_TYPE_NULL,
223           "jingle", "Conference members will hear a jingle if a member joins."},
224         { PARAM_TIMEOUT,
225           "timeout",    PARAM_TYPE_INTEGER,
226           "timeout=<seconds>", "Timeout before continue with next action."},
227         { PARAM_NOPASSWORD,
228           "nopassword", PARAM_TYPE_NULL,
229           "nopassword", "Don't ask for password. Be sure to authenticate right via real caller ID."},
230         { PARAM_STRIP,
231           "strip",      PARAM_TYPE_NULL,
232           "strip", "Remove digits that were required to match this rule."},
233         { PARAM_APPLICATION,
234           "application",PARAM_TYPE_STRING,
235           "application=<name>", "Name of remote application to make call to."},
236         { PARAM_CONTEXT,
237           "context",    PARAM_TYPE_STRING,
238           "context=<context>", "Give context parameter to the remote application."},
239         { PARAM_EXTEN,
240           "exten",      PARAM_TYPE_STRING,
241           "exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
242         { PARAM_ON,
243           "on", PARAM_TYPE_STRING,
244           "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
245         { 0, NULL, 0, NULL, NULL}
246 };
247
248 struct action_defs action_defs[] = {
249         { ACTION_EXTERNAL,
250           "extern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
251           PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
252           "Call is routed to extern number as dialed."},
253         { ACTION_INTERNAL,
254           "intern",     &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call,
255           PARAM_CONNECT | PARAM_EXTENSION | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_TIMEOUT,
256           "Call is routed to intern extension as given by the dialed number or specified by option."},
257         { ACTION_OUTDIAL,
258           "outdial",    &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
259           PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
260           "Same as 'extern'"},
261         { ACTION_REMOTE,
262           "remote",     &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
263           PARAM_CONNECT | PARAM_APPLICATION | PARAM_CONTEXT | PARAM_EXTEN | PARAM_TIMEOUT,
264           "Call is routed to Remote application, like Asterisk."},
265         { ACTION_VBOX_RECORD,
266           "vbox-record",&EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_vbox_record, &EndpointAppPBX::action_hangup_call,
267           PARAM_CONNECT | PARAM_EXTENSION | PARAM_ANNOUNCEMENT | PARAM_TIMEOUT,
268           "Caller is routed to the voice box of given extension."},
269         { ACTION_PARTYLINE,
270           "partyline",&EndpointAppPBX::action_init_partyline, NULL, &EndpointAppPBX::action_hangup_call,
271           PARAM_ROOM | PARAM_JINGLE,
272           "Caller is participating the conference with the given room number."},
273         { ACTION_LOGIN,
274           "login",      NULL, &EndpointAppPBX::action_dialing_login, NULL,
275           PARAM_CONNECT | PARAM_EXTENSION | PARAM_NOPASSWORD,
276           "Log into the given extension. Password required."},
277         { ACTION_CALLERID,
278           "callerid",   &EndpointAppPBX::action_init_change_callerid, &EndpointAppPBX::action_dialing_callerid, NULL,
279           PARAM_CONNECT | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_PRESENT,
280           "Caller changes the caller ID for all calls."},
281         { ACTION_CALLERIDNEXT,
282           "calleridnext",&EndpointAppPBX::action_init_change_callerid, &EndpointAppPBX::action_dialing_calleridnext, NULL,
283           PARAM_CONNECT | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_PRESENT,
284           "Caller changes the caller ID for the next call."},
285         { ACTION_FORWARD,
286           "forward",    &EndpointAppPBX::action_init_change_forward, &EndpointAppPBX::action_dialing_forward, NULL,
287           PARAM_CONNECT | PARAM_DIVERSION | PARAM_DEST | PARAM_DELAY,
288           "Caller changes the diversion of given type to the given destination or voice box."},
289         { ACTION_REDIAL,
290           "redial",     &EndpointAppPBX::action_init_redial_reply, &EndpointAppPBX::action_dialing_redial, NULL,
291           PARAM_CONNECT | PARAM_SELECT,
292           "Caller redials. (last outgoing call(s))"},
293         { ACTION_REPLY,
294           "reply",      &EndpointAppPBX::action_init_redial_reply, &EndpointAppPBX::action_dialing_reply, NULL,
295           PARAM_CONNECT | PARAM_SELECT,
296           "Caller replies. (last incoming call(s))"},
297         { ACTION_POWERDIAL,
298           "powerdial",  NULL, &EndpointAppPBX::action_dialing_powerdial, NULL,
299           PARAM_CONNECT | PARAM_DELAY | PARAM_LIMIT | PARAM_TIMEOUT,
300           "Caller redials using powerdialing."},
301         { ACTION_CALLBACK,
302           "callback",   NULL, &EndpointAppPBX::action_dialing_callback, &EndpointAppPBX::action_hangup_callback,
303           PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT | PARAM_EXTENSION | PARAM_DELAY | PARAM_CALLTO | PARAM_PREFIX,
304           "Caller will use the callback service. After disconnecting, the callback is triggered."},
305         { ACTION_ABBREV,
306           "abbrev",     NULL, &EndpointAppPBX::action_dialing_abbrev, NULL,
307           PARAM_CONNECT,
308           "Caller dials abbreviation."},
309         { ACTION_TEST,
310           "test",       NULL, &EndpointAppPBX::action_dialing_test, NULL,
311           PARAM_CONNECT | PARAM_PREFIX | PARAM_TIMEOUT,
312           "Caller dials test mode."},
313         { ACTION_PLAY,
314           "play",       &EndpointAppPBX::action_init_play, NULL, NULL,
315           PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT | PARAM_SAMPLE | PARAM_TIMEOUT,
316           "Plays the given sample."},
317         { ACTION_VBOX_PLAY,
318           "vbox-play",  &EndpointAppPBX::action_init_vbox_play, &EndpointAppPBX::action_dialing_vbox_play, NULL,
319           PARAM_EXTENSION,
320           "Caller listens to her voice box or to given extension."},
321         { ACTION_CALCULATOR,
322           "calculator", NULL, &EndpointAppPBX::action_dialing_calculator, NULL,
323           PARAM_CONNECT,
324           "Caller calls the calculator."},
325         { ACTION_TIMER,
326           "timer",      NULL, &EndpointAppPBX::action_dialing_timer, NULL,
327           PARAM_CONNECT | PARAM_TPRESET | PARAM_TIMEOUT,
328           NULL},
329 //        "Caller calls the timer."},
330         { ACTION_GOTO,
331           "goto",       NULL, &EndpointAppPBX::action_dialing_goto, NULL,
332           PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT | PARAM_RULESET | PARAM_STRIP | PARAM_SAMPLE,
333           "Jump to given ruleset and optionally play sample. Dialed digits are not flushed."},
334         { ACTION_MENU,
335           "menu",       NULL, &EndpointAppPBX::action_dialing_menu, NULL,
336           PARAM_CONNECT | PARAM_RULESET | PARAM_SAMPLE,
337           "Same as 'goto', but flushes all digits dialed so far."},
338         { ACTION_DISCONNECT,
339           "disconnect", NULL, &EndpointAppPBX::action_dialing_disconnect, NULL,
340           PARAM_CONNECT | PARAM_CAUSE | PARAM_LOCATION | PARAM_SAMPLE | PARAM_DISPLAY,
341           "Caller gets disconnected optionally with given cause and given sample and given display text."},
342         { ACTION_DEFLECT,
343           "deflect",    NULL, &EndpointAppPBX::action_dialing_deflect, NULL,
344           PARAM_DEST,
345           NULL},
346 //        "External call is deflected to the given destination within the telephone network."},
347         { ACTION_SETFORWARD,
348           "setforward", NULL, &EndpointAppPBX::action_dialing_setforward, NULL,
349           PARAM_CONNECT | PARAM_DIVERSION | PARAM_DEST | PARAM_PORT,
350           NULL},
351 //        "The call forward is set within the telephone network of the external line."},
352         { ACTION_EXECUTE,
353           "execute",    &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
354           PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON,
355           "Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
356         { ACTION_FILE,
357           "file",       NULL, NULL, &EndpointAppPBX::action_hangup_file,
358           PARAM_CONNECT | PARAM_FILE | PARAM_CONTENT | PARAM_APPEND,
359           "Writes givent content to given file. If content is not given, the dialed digits are written."},
360         { ACTION_PICK,
361           "pick",       &EndpointAppPBX::action_init_pick, NULL, NULL,
362           PARAM_EXTENSIONS,
363           "Pick up a call that is ringing on any phone. Extensions may be given to limit the picking ability."},
364         { ACTION_PASSWORD,
365           "password",   NULL, &EndpointAppPBX::action_dialing_password, NULL,
366           0,
367           NULL},
368         { ACTION_PASSWORD_WRITE,
369           "password_wr",NULL, &EndpointAppPBX::action_dialing_password_wr, NULL,
370           0,
371           NULL},
372         { ACTION_NOTHING,
373           "nothing",    NULL, NULL, NULL,
374           PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT | PARAM_TIMEOUT,
375           "does nothing. Usefull to wait for calls to be released completely, by giving timeout value."},
376         { ACTION_EFI,
377           "efi",        &EndpointAppPBX::action_init_efi, NULL, NULL,
378           PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT,
379           "Elektronische Fernsprecher Identifikation - announces caller ID."},
380         { -1,
381           NULL, NULL, NULL, NULL, 0, NULL}
382 };
383
384
385 /* display documentation of rules */
386
387 void doc_rules(const char *name)
388 {
389         int i, j;
390
391         if (name) {
392                 i = 0;
393                 while(action_defs[i].name) {
394                         if (!strcasecmp(action_defs[i].name, name))
395                                 break;
396                         i++;
397                 }
398                 if (!action_defs[i].name) {
399                         fprintf(stderr, "Given action '%s' unknown.\n", name);
400                         return;
401                 }
402                 name = action_defs[i].name;
403         }
404
405         printf("Syntax overview:\n");
406         printf("----------------\n\n");
407         printf("[ruleset]\n");
408         printf("<condition> ...   : <action> [parameter ...]   [timeout=X : <action> ...]\n");
409         printf("...\n");
410         printf("Please refer to the documentation for description on rule format.\n\n");
411
412         if (!name) {
413                 printf("Available conditions to match:\n");
414                 printf("------------------------------\n\n");
415                 i = 0;
416                 while(cond_defs[i].name) {
417                         printf("Usage: %s\n", cond_defs[i].doc);
418                         printf("%s\n\n", cond_defs[i].help);
419                         i++;
420                 }
421
422                 printf("Available actions with their parameters:\n");
423                 printf("----------------------------------------\n\n");
424         } else {
425                 printf("Detailes parameter description of action:\n");
426                 printf("-----------------------------------------\n\n");
427         }
428         i = 0;
429         while(action_defs[i].name) {
430                 if (name && !!strcmp(action_defs[i].name,name)) { /* not selected */
431                         i++;
432                         continue;
433                 }
434                 if (!action_defs[i].help) { /* not internal actions */
435                         i++;
436                         continue;
437                 }
438                 printf("Usage: %s", action_defs[i].name);
439                 j = 0;
440                 while(j < 64) {
441                         if ((1LL<<j) & action_defs[i].params)
442                                 printf(" [%s]", param_defs[j].doc);
443                         j++;
444                 }
445                 printf("\n%s\n\n", action_defs[i].help);
446                 if (name) { /* only show parameter help for specific action */
447                         j = 0;
448                         while(j < 64) {
449                                 if ((1LL<<j) & action_defs[i].params)
450                                         printf("%s:\n\t%s\n", param_defs[j].doc, param_defs[j].help);
451                                 j++;
452                         }
453                         printf("\n");
454                 }
455                 i++;
456         }
457 }
458
459 void ruleset_free(struct route_ruleset *ruleset_start)
460 {
461         struct route_ruleset *ruleset;
462         struct route_rule *rule;
463         struct route_cond *cond;
464         struct route_action *action;
465         struct route_param *param;
466
467         while(ruleset_start) {
468                 ruleset = ruleset_start;
469                 ruleset_start = ruleset->next;
470                 while(ruleset->rule_first) {
471                         rule = ruleset->rule_first;
472                         ruleset->rule_first = rule->next;
473                         while(rule->cond_first) {
474                                 cond = rule->cond_first;
475                                 if (cond->string_value) {
476                                         FREE(cond->string_value, 0);
477                                         rmemuse--;
478                                 }
479                                 if (cond->string_value_to) {
480                                         FREE(cond->string_value_to, 0);
481                                         rmemuse--;
482                                 }
483                                 rule->cond_first = cond->next;
484                                 FREE(cond, sizeof(struct route_cond));
485                                 rmemuse--;
486                         }
487                         while(rule->action_first) {
488                                 action = rule->action_first;
489                                 rule->action_first = action->next;
490                                 while(action->param_first) {
491                                         param = action->param_first;
492                                         action->param_first = param->next;
493                                         if (param->string_value) {
494                                                 FREE(param->string_value, 0);
495                                                 rmemuse--;
496                                         }
497                                         FREE(param, sizeof(struct route_param));
498                                         rmemuse--;
499                                 }
500                                 FREE(action, sizeof(struct route_action));
501                                 rmemuse--;
502                         }
503                         FREE(rule, sizeof(struct route_rule));
504                         rmemuse--;
505                 }
506                 FREE(ruleset, sizeof(struct route_ruleset));
507                 rmemuse--;
508         }
509 }
510
511 void ruleset_debug(struct route_ruleset *ruleset_start)
512 {
513         struct route_ruleset    *ruleset;
514         struct route_rule       *rule;
515         struct route_cond       *cond;
516         struct route_action     *action;
517         struct route_param      *param;
518         int                     first;
519
520         ruleset = ruleset_start;
521         while(ruleset) {
522                 printf("Ruleset: '%s'\n", ruleset->name);
523                 rule = ruleset->rule_first;
524                 while(rule) {
525                         /* CONDITION */
526                         first = 1;
527                         cond = rule->cond_first;
528                         while(cond) {
529                                 if (first)
530                                         printf("    Condition:");
531                                 else
532                                         printf("    and       ");
533                                 first = 0;
534                                 printf(" %s", cond_defs[cond->index].name);
535                                 if (cond->value_type != VALUE_TYPE_NULL)
536                                         printf(" = ");
537                                 next_cond_value:
538                                 switch(cond->value_type) {
539                                         case VALUE_TYPE_NULL:
540                                         break;
541
542                                         case VALUE_TYPE_INTEGER:
543                                         printf("%d", cond->integer_value);
544                                         break;
545
546                                         case VALUE_TYPE_INTEGER_RANGE:
547                                         printf("%d-%d", cond->integer_value, cond->integer_value_to);
548                                         break;
549
550                                         case VALUE_TYPE_STRING:
551                                         printf("'%s'", cond->string_value);
552                                         break;
553
554                                         case VALUE_TYPE_STRING_RANGE:
555                                         printf("'%s'-'%s'", cond->string_value, cond->string_value_to);
556                                         break;
557
558                                         default:
559                                         printf("Software error: VALUE_TYPE_* %d not known in function '%s' line=%d", cond->value_type, __FUNCTION__, __LINE__);
560                                 }
561                                 if (cond->value_extension && cond->next) {
562                                         cond = cond->next;
563                                         printf(" or ");
564                                         goto next_cond_value;
565                                 }
566
567                                 cond = cond->next;
568                                 printf("\n");
569                         }
570
571                         /* ACTION */
572                         action = rule->action_first;
573                         while(action) {
574                                 printf("    Action: %s\n", action_defs[action->index].name);
575                                 /* PARAM */
576                                 first = 1;
577                                 param = action->param_first;
578                                 while(param) {
579                                         if (first)
580                                                 printf("    Param:");
581                                         else
582                                                 printf("          ");
583                                         first = 0;
584                                         printf(" %s", param_defs[param->index].name);
585                                         if (param->value_type != VALUE_TYPE_NULL)
586                                                 printf(" = ");
587                                         switch(param->value_type) {
588                                                 case VALUE_TYPE_NULL:
589                                                 break;
590
591                                                 case VALUE_TYPE_INTEGER:
592                                                 if (param_defs[param->index].type == PARAM_TYPE_CALLERIDTYPE) {
593                                                         switch(param->integer_value) {
594                                                                 case INFO_NTYPE_UNKNOWN:
595                                                                 printf("unknown");
596                                                                 break;
597                                                                 case INFO_NTYPE_SUBSCRIBER:
598                                                                 printf("subscriber");
599                                                                 break;
600                                                                 case INFO_NTYPE_NATIONAL:
601                                                                 printf("national");
602                                                                 break;
603                                                                 case INFO_NTYPE_INTERNATIONAL:
604                                                                 printf("international");
605                                                                 break;
606                                                                 default:
607                                                                 printf("unknown(%d)", param->integer_value);
608                                                         }
609                                                         break;
610                                                 }
611                                                 if (param_defs[param->index].type == PARAM_TYPE_CAPABILITY) {
612                                                         switch(param->integer_value) {
613                                                                 case INFO_BC_SPEECH:
614                                                                 printf("speech");
615                                                                 break;
616                                                                 case INFO_BC_AUDIO:
617                                                                 printf("audio");
618                                                                 break;
619                                                                 case INFO_BC_VIDEO:
620                                                                 printf("video");
621                                                                 break;
622                                                                 case INFO_BC_DATARESTRICTED:
623                                                                 printf("digital-restricted");
624                                                                 break;
625                                                                 case INFO_BC_DATAUNRESTRICTED:
626                                                                 printf("digital-unrestricted");
627                                                                 break;
628                                                                 case INFO_BC_DATAUNRESTRICTED_TONES:
629                                                                 printf("digital-unrestricted-tones");
630                                                                 break;
631                                                                 default:
632                                                                 printf("unknown(%d)", param->integer_value);
633                                                         }
634                                                         break;
635                                                 }
636                                                 if (param_defs[param->index].type == PARAM_TYPE_DIVERSION) {
637                                                         switch(param->integer_value) {
638                                                                 case INFO_DIVERSION_CFU:
639                                                                 printf("cfu");
640                                                                 break;
641                                                                 case INFO_DIVERSION_CFNR:
642                                                                 printf("cfnr");
643                                                                 break;
644                                                                 case INFO_DIVERSION_CFB:
645                                                                 printf("cfb");
646                                                                 break;
647                                                                 case INFO_DIVERSION_CFP:
648                                                                 printf("cfp");
649                                                                 break;
650                                                                 default:
651                                                                 printf("unknown(%d)", param->integer_value);
652                                                         }
653                                                         break;
654                                                 }
655                                                 if (param_defs[param->index].type == PARAM_TYPE_TYPE) {
656                                                         switch(param->integer_value) {
657                                                                 case INFO_NTYPE_UNKNOWN:
658                                                                 printf("unknown");
659                                                                 break;
660                                                                 case INFO_NTYPE_SUBSCRIBER:
661                                                                 printf("subscriber");
662                                                                 break;
663                                                                 case INFO_NTYPE_NATIONAL:
664                                                                 printf("national");
665                                                                 break;
666                                                                 case INFO_NTYPE_INTERNATIONAL:
667                                                                 printf("international");
668                                                                 break;
669                                                                 default:
670                                                                 printf("unknown(%d)", param->integer_value);
671                                                         }
672                                                         break;
673                                                 }
674                                                 if (param_defs[param->index].type == PARAM_TYPE_YESNO) {
675                                                         switch(param->integer_value) {
676                                                                 case 1:
677                                                                 printf("yes");
678                                                                 break;
679                                                                 case 0:
680                                                                 printf("no");
681                                                                 break;
682                                                                 default:
683                                                                 printf("unknown(%d)", param->integer_value);
684                                                         }
685                                                         break;
686                                                 }
687                                                 if (param_defs[param->index].type == PARAM_TYPE_NULL) {
688                                                         break;
689                                                 }
690                                                 printf("%d", param->integer_value);
691                                                 break;
692
693                                                 case VALUE_TYPE_STRING:
694                                                 printf("'%s'", param->string_value);
695                                                 break;
696
697                                                 default:
698                                                 printf("Software error: VALUE_TYPE_* %d not known in function '%s' line=%d", param->value_type, __FUNCTION__, __LINE__);
699                                         }
700                                         param = param->next;
701                                         printf("\n");
702                                 }
703                                 /* TIMEOUT */
704                                 if (action->timeout)
705                                         printf("    Timeout: %d\n", action->timeout);
706                                 action = action->next;
707                         }
708                         printf("\n");
709                         rule = rule->next;
710                 }
711                 printf("\n");
712                 ruleset = ruleset->next;
713         }
714 }
715
716
717 /*
718  * parse ruleset
719  */
720 static char *read_string(char *p, char *key, int key_size, const char *special)
721 {
722         key[0] = 0;
723
724         if (*p == '\"') {
725                 p++;
726                 /* quote */
727                 while(*p) {
728                         if (*p == '\"') {
729                                 p++;
730                                 *key = '\0';
731                                 return(p);
732                         }
733                         if (*p == '\\') {
734                                 p++;
735                                 if (*p == '\0') {
736                                         break;
737                                 }
738                         }
739                         if (--key_size == 0) {
740                                 UPRINT(key, "\001String too long.");
741                                 return(p);
742                         }
743                         *key++ = *p++;
744                 }
745                 UPRINT(key, "\001Unexpected end of line inside quotes.");
746                 return(p);
747         }
748
749         /* no quote */
750         while(*p) {
751                 if (strchr(special, *p)) {
752                         *key = '\0';
753                         return(p);
754                 }
755                 if (*p == '\\') {
756                         p++;
757                         if (*p == '\0') {
758                                 UPRINT(key, "\001Unexpected end of line.");
759                                 return(p);
760                         }
761                 }
762                 if (--key_size == 0) {
763                         UPRINT(key, "\001String too long.");
764                         return(p);
765                 }
766                 *key++ = *p++;
767         }
768         *key = '\0';
769         return(p);
770 }
771 char ruleset_error[256];
772 struct route_ruleset *ruleset_parse(void)
773 {
774 //      char                    from[128];
775 //      char                    to[128];
776         int                     i;
777         unsigned long long      j;
778 //      int                     a,
779 //                              b;
780         #define                 MAXNESTING 8
781         FILE                    *fp[MAXNESTING];
782         char                    filename[MAXNESTING][256];
783         int                     line[MAXNESTING];
784         int                     nesting = -1;
785         char                    buffer[1024],
786                                 key[1024],
787                                 key_to[1024],
788                                 pointer[1024+1],
789                                 *p;
790         int                     expecting = 1; /* 1 = expecting ruleset */
791         int                     index,
792                                 value_type,
793                                 integer,
794                                 integer_to; /* condition index, .. */
795         struct route_ruleset    *ruleset_start = NULL, *ruleset;
796         struct route_ruleset    **ruleset_pointer = &ruleset_start;
797         struct route_rule       *rule;
798         struct route_rule       **rule_pointer = NULL;
799         struct route_cond       *cond;
800         struct route_cond       **cond_pointer = NULL;
801         struct route_action     *action;
802         struct route_action     **action_pointer = NULL;
803         struct route_param      *param;
804         struct route_param      **param_pointer = NULL;
805         char                    failure[256];
806         unsigned long long      allowed_params;
807
808         /* check the integrity of IDs for ACTION_* and PARAM_* */
809         i = 0;
810         while(action_defs[i].name) {
811                 if (action_defs[i].id != i) {
812                         PERROR("Software Error action '%s' must have id of %d, but has %d.\n",
813                                 action_defs[i].name, i, action_defs[i].id);
814                         goto openerror;
815                 }
816                 i++;
817         }
818         i = 0; j = 1;
819         while(param_defs[i].name) {
820                 if (param_defs[i].id != j) {
821                         PERROR("Software Error param '%s' must have id of 0x%llx, but has 0x%llx.\n",
822                                 param_defs[i].name, j, param_defs[i].id);
823                         goto openerror;
824                 }
825                 i++;
826                 j<<=1;
827         }
828
829         SPRINT(filename[0], "%s/routing.conf", CONFIG_DATA);
830
831         if (!(fp[0]=fopen(filename[0],"r")))
832         {
833                 PERROR("Cannot open %s\n",filename[0]);
834                 goto openerror;
835         }
836         nesting++;
837         fduse++;
838
839         go_leaf:
840         line[nesting]=0;
841         go_root:
842         while((fgets(buffer,sizeof(buffer),fp[nesting])))
843         {
844                 line[nesting]++;
845                 buffer[sizeof(buffer)-1]=0;
846                 if (buffer[0]) buffer[strlen(buffer)-1]=0;
847                 p = buffer;
848
849                 /* remove tabs */
850                 while(*p) {
851                         if (*p < 32)
852                                 *p = 32;
853                         p++;
854                 } 
855                 p = buffer;
856
857                 /* skip spaces, if any */
858                 while(*p == 32)
859                 {
860                         if (*p == 0)
861                                 break;
862                         p++;
863                 }
864
865                 /* skip comments */
866                 if (*p == '#') {
867                         p++;
868                         /* don't skip "define" */
869                         if (!!strncmp(p, "define", 6))
870                                 continue;
871                         p+=6;
872                         if (*p != 32)
873                                 continue;
874                         /* skip spaces */
875                         while(*p == 32) {
876                                 if (*p == 0)
877                                         break;
878                                 p++;
879                         }
880                         p++;
881                         p = read_string(p, key, sizeof(key), " ");
882                         if (key[0] == 1) { /* error */
883                                 SPRINT(failure, "Parsing Filename failed: %s", key+1);
884                                 goto parse_error;
885                         }
886                         if (nesting == MAXNESTING-1) {
887                                 SPRINT(failure, "'include' is nesting too deep.\n");
888                                 goto parse_error;
889                         }
890                         if (key[0] == '/')
891                                 SCPY(filename[nesting+1], key);
892                         else
893                                 SPRINT(filename[nesting+1], "%s/%s", CONFIG_DATA, key);
894                         if (!(fp[nesting+1]=fopen(filename[nesting+1],"r"))) {
895                                 PERROR("Cannot open %s\n", filename[nesting+1]);
896                                 goto parse_error;
897                         }
898                         fduse++;
899                         nesting++;
900                         goto go_leaf;
901                 }
902                 if (*p == '/') if (p[1] == '/')
903                         continue;
904
905                 /* skip empty lines */
906                 if (*p == 0)
907                         continue;
908
909                 /* expecting ruleset */
910                 if (expecting) {
911                         new_ruleset:
912                         /* expecting [ */
913                         if (*p != '[') {
914                                 SPRINT(failure, "Expecting ruleset name starting with '['.");
915                                 goto parse_error;
916                         }
917                         p++;
918
919                         /* reading ruleset name text */
920                         i = 0;
921                         while(*p>' ' && *p<127 && *p!=']') {
922                                 if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
923                                 key[i++] = *p++;
924                                 if (i == sizeof(key)) i--; /* limit */
925                         }
926                         key[i] = 0;
927                         if (key[0] == '\0') {
928                                 SPRINT(failure, "Missing ruleset name after '['.");
929                                 goto parse_error;
930                         }
931
932                         /* expecting ] and nothing more */
933                         if (*p != ']') {
934                                 SPRINT(failure, "Expecting ']' after ruleset name.");
935                                 goto parse_error;
936                         }
937                         p++;
938                         if (*p != 0) {
939                                 SPRINT(failure, "Unexpected character after ruleset name.");
940                                 goto parse_error;
941                         }
942
943                         /* check for duplicate rulesets */
944                         ruleset = ruleset_start;
945                         while(ruleset) {
946                                 if (!strcmp(ruleset->name, key)) {
947                                         SPRINT(failure, "Duplicate ruleset '%s', already defined in file '%s' line %d.", key, ruleset->file, ruleset->line);
948                                         goto parse_error;
949                                 }
950                                 ruleset = ruleset->next;
951                         }
952
953                         /* create ruleset */
954                         ruleset = (struct route_ruleset *)MALLOC(sizeof(struct route_ruleset));
955                         rmemuse++;
956                         *ruleset_pointer = ruleset;
957                         ruleset_pointer = &(ruleset->next);
958                         SCPY(ruleset->name, key);
959                         SCPY(ruleset->file, filename[nesting]);
960                         ruleset->line = line[nesting];
961                         rule_pointer = &(ruleset->rule_first);
962                         expecting = 0;
963                         continue;
964                 }
965
966                 /* for new ruleset [ */
967                 if (*p == '[') {
968                         goto new_ruleset;
969                 }
970
971                 /* Alloc memory for rule */
972                 rule = (struct route_rule *)MALLOC(sizeof(struct route_rule));
973                 rmemuse++;
974                 *rule_pointer = rule;
975                 rule_pointer = &(rule->next);
976                 cond_pointer = &(rule->cond_first);
977                 action_pointer = &(rule->action_first);
978                 SCPY(rule->file, filename[nesting]);
979                 rule->line = line[nesting];
980
981                 /* loop CONDITIONS */
982                 while(*p!=':' && *p!='\0') {
983                         /* read item text */
984                         i = 0;
985                         while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9')) {
986                                 if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
987                                 key[i++] = *p++;
988                                 if (i == sizeof(key)) i--; /* limit */
989                         }
990                         key[i] = 0;
991                         if (key[0] == '\0') {
992                                 SPRINT(failure, "Expecting condition item name or ':' for end of condition list.");
993                                 goto parse_error;
994                         }
995                         if (*p!=' ' && *p!='=') {
996                                 SPRINT(failure, "Illegal character '%c' after condition name '%s'. Expecting '=' for equation or ' ' to seperate condition items.", *p, key);
997                                 goto parse_error;
998                         }
999
1000                         /* check if condition exists */
1001                         index = 0;
1002                         while(cond_defs[index].name) {
1003                                 if (!strcmp(cond_defs[index].name, key))
1004                                         break;
1005                                 index++;
1006                         }
1007                         if (cond_defs[index].name == NULL) {
1008                                 SPRINT(failure, "Unknown condition item name '%s'.", key);
1009                                 goto parse_error;
1010                         }
1011
1012                         /* items without values must not have any parameter */
1013                         if (cond_defs[index].type == COND_TYPE_NULL) {
1014                                 if (*p == '=') {
1015                                         SPRINT(failure, "Condition item '%s' must not have any value. Don't use '=' for this type of condition.", key);
1016                                         goto parse_error;
1017                                 }
1018                                 if (*p != ' ') {
1019                                         SPRINT(failure, "Condition item '%s' must not have any value. Expecting ' ' or tab after item name.", key);
1020                                         goto parse_error;
1021                                 }
1022 //                              p++;
1023                         } else {
1024                                 if (*p == ' ') {
1025                                         SPRINT(failure, "Condition item '%s' must have at least one value, '=' expected, and not a space.", key);
1026                                         goto parse_error;
1027                                 }
1028                                 if (*p != '=') {
1029                                         SPRINT(failure, "Condition item '%s' must have at least one value, '=' expected.", key);
1030                                         goto parse_error;
1031                                 }
1032                                 p++;
1033                         }
1034
1035                         /* check for duplicate condition */
1036                         cond = rule->cond_first;
1037                         while(cond) {
1038                                 if (cond->index == index) {
1039                                         SPRINT(failure, "Duplicate condition '%s', use ',' to give multiple values.", key);
1040                                         goto parse_error;
1041                                 }
1042                                 cond = cond->next;
1043                         }
1044
1045                         nextcondvalue:
1046                         /* Alloc memory for item */
1047                         cond = (struct route_cond *)MALLOC(sizeof(struct route_cond));
1048                         rmemuse++;
1049                         *cond_pointer = cond;
1050                         cond_pointer = &(cond->next);
1051                         cond->index = index;
1052                         cond->match = cond_defs[index].match;
1053                         switch(cond_defs[index].type) {
1054                                 case COND_TYPE_NULL:
1055                                 if (*p=='=') {
1056                                         SPRINT(failure, "Expecting no value.");
1057                                         goto parse_error;
1058                                 }
1059                                 value_type = VALUE_TYPE_NULL;
1060                                 break;
1061
1062                                 /* parse all integer values/ranges */
1063                                 case COND_TYPE_INTEGER:
1064                                 case COND_TYPE_TIME:
1065                                 case COND_TYPE_MDAY:
1066                                 case COND_TYPE_MONTH:
1067                                 case COND_TYPE_WDAY:
1068                                 case COND_TYPE_YEAR:
1069                                 integer = integer_to = 0;
1070                                 if (*p==',' || *p==' ' || *p=='\0') {
1071                                         SPRINT(failure, "Missing integer value.");
1072                                         goto parse_error;
1073                                 }
1074                                 while(*p>='0' && *p<='9') {
1075                                         integer = integer*10 + *p-'0';
1076                                         p++;
1077                                 }
1078                                 value_type = VALUE_TYPE_INTEGER;
1079                                 if (*p == '-') {
1080                                         p++;
1081                                         if (*p==',' || *p==' ' || *p=='\0') {
1082                                                 SPRINT(failure, "Missing integer value.");
1083                                                 goto parse_error;
1084                                         }
1085                                         while(*p>='0' && *p<='9') {
1086                                                 integer_to = integer_to*10 + *p-'0';
1087                                                 p++;
1088                                         }
1089                                         value_type = VALUE_TYPE_INTEGER_RANGE;
1090                                 }
1091                                 if (cond_defs[index].type == COND_TYPE_TIME) {
1092                                         // Simon: i store the time as decimal, later i compare it correctly:
1093                                         // hours * 100 + minutes
1094                                         if (integer == 2400)
1095                                                 integer = 0;
1096                                         if (integer >= 2400) {
1097                                                 timeoutofrange1:
1098                                                 SPRINT(failure, "Given time '%d' not in range 0000..2359 (or 2400 for 0000)", integer);
1099                                                 goto parse_error;
1100                                         }
1101                                         if (integer%100 >= 60)
1102                                                 goto timeoutofrange1;
1103                                         if (value_type == VALUE_TYPE_INTEGER)
1104                                                 goto integer_done;
1105                                         if (integer_to == 2400)
1106                                                 integer_to = 0;
1107                                         if (integer_to >= 2400) {
1108                                                 timeoutofrange2:
1109                                                 SPRINT(failure, "Given time '%d' not in range 0000..2359 (or 2400 for 0000)", integer_to);
1110                                                 goto parse_error;
1111                                         }
1112                                         if (integer_to%100 >= 60)
1113                                                 goto timeoutofrange2;
1114                                 }
1115                                 if (cond_defs[index].type == COND_TYPE_MDAY) {
1116                                         if (integer<1 || integer>31) {
1117                                                 SPRINT(failure, "Given day-of-month '%d' not in range 1..31", integer);
1118                                                 goto parse_error;
1119                                         } 
1120                                         if (value_type == VALUE_TYPE_INTEGER)
1121                                                 goto integer_done;
1122                                         if (integer_to<1 || integer_to>31) {
1123                                                 SPRINT(failure, "Given day-of-month '%d' not in range 1..31", integer_to);
1124                                                 goto parse_error;
1125                                         } 
1126                                 }
1127                                 if (cond_defs[index].type == COND_TYPE_WDAY) {
1128                                         if (integer<1 || integer>7) {
1129                                                 SPRINT(failure, "Given day-of-week '%d' not in range 1..7", integer);
1130                                                 goto parse_error;
1131                                         } 
1132                                         if (value_type == VALUE_TYPE_INTEGER)
1133                                                 goto integer_done;
1134                                         if (integer_to<1 || integer_to>7) {
1135                                                 SPRINT(failure, "Given day-of-week '%d' not in range 1..7", integer_to);
1136                                                 goto parse_error;
1137                                         } 
1138                                 }
1139                                 if (cond_defs[index].type == COND_TYPE_MONTH) {
1140                                         if (integer<1 || integer>12) {
1141                                                 SPRINT(failure, "Given month '%d' not in range 1..12", integer);
1142                                                 goto parse_error;
1143                                         } 
1144                                         if (value_type == VALUE_TYPE_INTEGER)
1145                                                 goto integer_done;
1146                                         if (integer_to<1 || integer_to>12) {
1147                                                 SPRINT(failure, "Given month '%d' not in range 1..12", integer_to);
1148                                                 goto parse_error;
1149                                         } 
1150                                 }
1151                                 if (cond_defs[index].type == COND_TYPE_YEAR) {
1152                                         if (integer<1970 || integer>2106) {
1153                                                 SPRINT(failure, "Given year '%d' not in range 1970..2106", integer);
1154                                                 goto parse_error;
1155                                         } 
1156                                         if (value_type == VALUE_TYPE_INTEGER)
1157                                                 goto integer_done;
1158                                         if (integer_to<1970 || integer_to>2106) {
1159                                                 SPRINT(failure, "Given year '%d' not in range 1970..2106", integer_to);
1160                                                 goto parse_error;
1161                                         } 
1162                                 }
1163                                 integer_done:
1164                                 cond->integer_value = integer;
1165                                 cond->integer_value_to = integer_to;
1166                                 cond->value_type = value_type;
1167                                 break;
1168
1169                                 /* parse all string values/ranges */
1170                                 case COND_TYPE_STRING:
1171                                 key[0] = key_to[0] = '\0';
1172                                 if (*p==',' || *p==' ' || *p=='\0') {
1173                                         SPRINT(failure, "Missing string value, use \"\" for empty string.");
1174                                         goto parse_error;
1175                                 }
1176                                 p = read_string(p, key, sizeof(key), "-, ");
1177                                 if (key[0] == 1) { /* error */
1178                                         SPRINT(failure, "Parsing String failed: %s", key+1);
1179                                         goto parse_error;
1180                                 }
1181                                 value_type = VALUE_TYPE_STRING;
1182                                 if (*p == '-') {
1183                                         p++;
1184                                         if (*p==',' || *p==' ' || *p=='\0') {
1185                                                 SPRINT(failure, "Missing string value, use \"\" for empty string.");
1186                                                 goto parse_error;
1187                                         }
1188                                         p = read_string(p, key_to, sizeof(key_to), "-, ");
1189                                         if (key_to[0] == 1) { /* error */
1190                                                 SPRINT(failure, "Parsing string failed: %s", key_to+1);
1191                                                 goto parse_error;
1192                                         }
1193                                         value_type = VALUE_TYPE_STRING_RANGE;
1194                                         if (strlen(key) != strlen(key_to)) {
1195                                                 SPRINT(failure, "Given range of strings \"%s\"-\"%s\" have unequal length.", key, key_to);
1196                                                 goto parse_error;
1197                                         }
1198                                         if (key[0] == '\0') {
1199                                                 SPRINT(failure, "Given range has no length.");
1200                                                 goto parse_error;
1201                                         }
1202                                 }
1203                                 alloc_string:
1204                                 cond->string_value = (char *)MALLOC(strlen(key)+1);
1205                                 rmemuse++;
1206                                 UCPY(cond->string_value, key);
1207                                 if (value_type == VALUE_TYPE_STRING_RANGE) {
1208                                         cond->string_value_to = (char *)MALLOC(strlen(key_to)+1);
1209                                         rmemuse++;
1210                                         UCPY(cond->string_value_to, key_to);
1211                                         cond->comp_string = strcmp(key, key_to);
1212                                 }
1213                                 cond->value_type = value_type;
1214                                 break;
1215
1216                                 /* parse service value */
1217                                 case COND_TYPE_CAPABILITY:
1218                                 if (!strncasecmp("speech", p, 6))
1219                                         cond->integer_value = INFO_BC_SPEECH;
1220                                 else if (!strncasecmp("audio", p, 5))
1221                                         cond->integer_value = INFO_BC_AUDIO;
1222                                 else if (!strncasecmp("video", p, 5))
1223                                         cond->integer_value = INFO_BC_VIDEO;
1224                                 else if (!strncasecmp("digital-restricted", p, 18))
1225                                         cond->integer_value = INFO_BC_DATARESTRICTED;
1226                                 else if (!strncasecmp("digital-unrestricted", p, 20))
1227                                         cond->integer_value = INFO_BC_DATAUNRESTRICTED;
1228                                 else if (!strncasecmp("digital-unrestricted-tones", p, 26))
1229                                         cond->integer_value = INFO_BC_DATAUNRESTRICTED_TONES;
1230                                 else {
1231                                         SPRINT(failure, "Given service type is invalid or misspelled.");
1232                                         goto parse_error;
1233                                 }
1234                                 cond->value_type = VALUE_TYPE_INTEGER;
1235                                 break;
1236
1237                                 /* parse bmode value */
1238                                 case COND_TYPE_BMODE:
1239                                 if (!strncasecmp("transparent", p, 11))
1240                                         cond->integer_value = INFO_BMODE_CIRCUIT;
1241                                 else if (!strncasecmp("hdlc", p, 4))
1242                                         cond->integer_value = INFO_BMODE_PACKET;
1243                                 else {
1244                                         SPRINT(failure, "Given bchannel mode is invalid or misspelled.");
1245                                         goto parse_error;
1246                                 }
1247                                 cond->value_type = VALUE_TYPE_INTEGER;
1248                                 break;
1249
1250                                 /* parse interface attribute <if>:<value> */
1251                                 case COND_TYPE_IFATTR:
1252                                 key[0] = key_to[0] = '\0';
1253                                 if (*p==':' || *p==',' || *p==' ' || *p=='\0') {
1254                                         SPRINT(failure, "Missing interface name.");
1255                                         goto parse_error;
1256                                 }
1257                                 p = read_string(p, key, sizeof(key), ":-, ");
1258                                 if (key[0] == 1) { /* error */
1259                                         SPRINT(failure, "Parsing interface failed: %s", key+1);
1260                                         goto parse_error;
1261                                 }
1262                                 if (*p != ':') {
1263                                         SPRINT(failure, "Expeciting kolon to seperate value behind interface name.");
1264                                         goto parse_error;
1265                                 }
1266                                 SCCAT(key, *p++);
1267                                 while(*p>='0' && *p<='9') {
1268                                         SCCAT(key, *p++);
1269                                 }
1270                                 if (*p!=',' && *p!=' ' && *p!='\0') {
1271                                         SPRINT(failure, "Invalid characters behind value.");
1272                                         goto parse_error;
1273                                 }
1274                                 value_type = VALUE_TYPE_STRING;
1275                                 goto alloc_string;
1276                                 break;
1277
1278                                 default:
1279                                 SPRINT(failure, "Software error: COND_TYPE_* %d not parsed in function '%s'", cond_defs[index].type, __FUNCTION__);
1280                                 goto parse_error;
1281                         }
1282                         /* if we have another value for that item, we attach it */
1283                         if (*p == ',') {
1284                                 p++;
1285                                 /* next item */
1286                                 cond->value_extension = 1;
1287                                 goto nextcondvalue;
1288                         }
1289                         /* to seperate the items, a space is required */
1290                         if (*p != ' ') {
1291                                 SPRINT(failure, "Character '%c' not expected here. Use ',' to seperate multiple possible values.", *p);
1292                                 goto parse_error;
1293                         }
1294                         /* skip spaces */
1295                         while(*p == 32)
1296                         {
1297                                 if (*p == 0)
1298                                         break;
1299                                 p++;
1300                         }
1301                 }
1302
1303                 /* we are done with CONDITIONS, so we expect the ACTION */
1304                 if (*p != ':') {
1305                         SPRINT(failure, "Expecting ':' after condition item(s).");
1306                         goto parse_error;
1307                 }
1308                 p++;
1309
1310                 nextaction:
1311                 /* skip spaces, if any */
1312                 while(*p == 32)
1313                 {
1314                         if (*p == 0)
1315                                 break;
1316                         p++;
1317                 }
1318
1319                 /* read action name */
1320                 i = 0;
1321                 while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || *p == '-') {
1322                         if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
1323                         key[i++] = *p++;
1324                         if (i == sizeof(key)) i--; /* limit */
1325                 }
1326                 key[i] = 0;
1327                 if (key[0] == '\0') {
1328                         SPRINT(failure, "Expecting action name.");
1329                         goto parse_error;
1330                 }
1331
1332                 /* check if item exists */
1333                 index = 0;
1334                 while(action_defs[index].name) {
1335                         if (!action_defs[index].help) { /* not internal actions */
1336                                 index++;
1337                                 continue;
1338                         }
1339                         if (!strcmp(action_defs[index].name, key))
1340                                 break;
1341                         index++;
1342                 }
1343                 if (action_defs[index].name == NULL) {
1344                         SPRINT(failure, "Unknown action name '%s'.", key);
1345                         goto parse_error;
1346                 }
1347                 allowed_params = action_defs[index].params;
1348
1349                 /* alloc memory for action */
1350                 action = (struct route_action *)MALLOC(sizeof(struct route_action));
1351                 rmemuse++;
1352                 *action_pointer = action;
1353                 action_pointer = &(action->next);
1354                 param_pointer = &(action->param_first);
1355                 action->index = index;
1356                 action->line = line[nesting];
1357
1358                 /* skip spaces after param name */
1359                 while(*p == 32)
1360                 {
1361                         if (*p == 0)
1362                                 break;
1363                         p++;
1364                 }
1365
1366                 /* loop PARAMS */
1367                 while(*p != 0) {
1368                         /* read param text */
1369                         i = 0;
1370                         while((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9')) {
1371                                 if (*p>='A' && *p<='Z') *p = *p-'A'+'a'; /* lower case */
1372                                 key[i++] = *p++;
1373                                 if (i == sizeof(key)) i--; /* limit */
1374                         }
1375                         key[i] = 0;
1376                         if (key[0] == '\0') {
1377                                 SPRINT(failure, "Expecting parameter name.");
1378                                 goto parse_error;
1379                         }
1380
1381                         /* check if item exists */
1382                         index = 0;
1383                         while(param_defs[index].name) {
1384                                 if (!strcmp(param_defs[index].name, key))
1385                                         break;
1386                                 index++;
1387                         }
1388                         if (param_defs[index].name == NULL) {
1389                                 SPRINT(failure, "Unknown param name '%s'.", key);
1390                                 goto parse_error;
1391                         }
1392
1393                         /* check if item is allowed for the action */
1394                         if (!(param_defs[index].id & allowed_params)) {
1395                                 SPRINT(failure, "Param name '%s' exists, but not for this action.", key);
1396                                 goto parse_error;
1397                         }
1398
1399                         /* params without values must not have any parameter */
1400                         if (param_defs[index].type == PARAM_TYPE_NULL) {
1401                                 if (*p!=' ' && *p!='\0') {
1402                                         SPRINT(failure, "Parameter '%s' must not have any value.", key);
1403                                         goto parse_error;
1404                                 }
1405                         } else {
1406                                 if (*p == ' ') {
1407                                         SPRINT(failure, "Parameter '%s' must have at least one value, '=' expected and not a space.", key);
1408                                         goto parse_error;
1409                                 }
1410                                 if (*p != '=') {
1411                                         SPRINT(failure, "Parameter '%s' must have at least one value, '=' expected.", key);
1412                                         goto parse_error;
1413                                 }
1414                                 p++;
1415                         }
1416
1417                         /* special timeout value */
1418                         if (!strcmp("timeout", key)) {
1419                                 if (action->timeout) {
1420                                         SPRINT(failure, "Duplicate timeout value.");
1421                                         goto parse_error;
1422                                 }
1423                                 if (*p==',' || *p==' ' || *p=='\0') {
1424                                         SPRINT(failure, "Missing integer value.");
1425                                         goto parse_error;
1426                                 }
1427                                 integer = 0;
1428                                 while(*p>='0' && *p<='9') {
1429                                         integer = integer*10 + *p-'0';
1430                                         p++;
1431                                 }
1432                                 if (integer < 1) {
1433                                         SPRINT(failure, "Expecting timeout value greater 0.");
1434                                         goto parse_error;
1435                                 }
1436                                 if (*p!=' ' && *p!='\0') {
1437                                         SPRINT(failure, "Character '%c' not expected here. Use ' ' to seperate parameters.", *p);
1438                                         goto parse_error;
1439                                 }
1440                                 /* skip spaces */
1441                                 while(*p == 32) {
1442                                         if (*p == 0)
1443                                                 break;
1444                                         p++;
1445                                 }
1446                                 action->timeout = integer;
1447                                 /* check for next ACTION */
1448                                 if (*p == ':') {
1449                                         p++;
1450                                         goto nextaction;
1451                                 }
1452                                 continue;
1453                         }
1454
1455                         /* check for duplicate parameters */
1456                         param = action->param_first;
1457                         while(param) {
1458                                 if (param->index == index) {
1459                                         SPRINT(failure, "Duplicate parameter '%s', use ',' to give multiple values.", key);
1460                                         goto parse_error;
1461                                 }
1462                                 param = param->next;
1463                         }
1464
1465                         nextparamvalue:
1466                         /* Alloc memory for param */
1467                         param = (struct route_param *)MALLOC(sizeof(struct route_param));
1468                         rmemuse++;
1469                         *param_pointer = param;
1470                         param_pointer = &(param->next);
1471                         param->index = index;
1472                         param->id = param_defs[index].id;
1473
1474                         switch(param_defs[index].type) {
1475                                 /* parse null value */
1476                                 case PARAM_TYPE_NULL:
1477                                 param->value_type = VALUE_TYPE_NULL;
1478                                 break;
1479
1480                                 /* parse integer value */
1481                                 case PARAM_TYPE_INTEGER:
1482                                 integer = 0;
1483                                 if (*p==',' || *p==' ' || *p=='\0') {
1484                                         SPRINT(failure, "Missing integer value.");
1485                                         goto parse_error;
1486                                 }
1487                                 while(*p>='0' && *p<='9') {
1488                                         integer = integer*10 + *p-'0';
1489                                         p++;
1490                                 }
1491                                 param->integer_value = integer;
1492                                 param->value_type = VALUE_TYPE_INTEGER;
1493                                 break;
1494
1495 #if 0
1496                                 /* parse ports value */
1497                                 case PARAM_TYPE_PORTS:
1498                                 key[0] = '\0';
1499                                 if (*p==',' || *p==' ' || *p=='\0') {
1500                                         SPRINT(failure, "Missing port number, omit parameter or give port number.");
1501                                         goto parse_error;
1502                                 }
1503                                 i = 0;
1504                                 nextport:
1505                                 integer = 0;
1506                                 while(*p>='0' && *p<='9') {
1507                                         if (i < (int)sizeof(key)-1) {
1508                                                 key[i] = *p;
1509                                                 key[i++] = '\0';
1510                                         }
1511                                         integer = integer*10 + *p-'0';
1512                                         p++;
1513                                 }
1514                                 if (integer > 255) {
1515                                         SPRINT(failure, "Port number too high.");
1516                                         goto parse_error;
1517                                 }
1518                                 if (*p==',') {
1519                                         if (i < (int)sizeof(key)-1) {
1520                                                 key[i] = *p;
1521                                                 key[i++] = '\0';
1522                                         }
1523                                         p++;
1524                                         goto nextport;
1525                                 }
1526                                 goto mallocstring;
1527 #endif
1528
1529                                 /* parse string value */
1530                                 case PARAM_TYPE_STRING:
1531                                 case PARAM_TYPE_CALLERIDTYPE:
1532                                 case PARAM_TYPE_CAPABILITY:
1533                                 case PARAM_TYPE_BMODE:
1534                                 case PARAM_TYPE_DIVERSION:
1535                                 case PARAM_TYPE_DESTIN:
1536                                 case PARAM_TYPE_TYPE:
1537                                 case PARAM_TYPE_YESNO:
1538                                 case PARAM_TYPE_ON:
1539                                 key[0] = '\0';
1540                                 if (*p==',' || *p==' ' || *p=='\0') {
1541                                         SPRINT(failure, "Missing string value, use \"\" for empty string.");
1542                                         goto parse_error;
1543                                 }
1544                                 p = read_string(p, key, sizeof(key), " ");
1545                                 if (key[0] == 1) { /* error */
1546                                         SPRINT(failure, "Parsing string failed: %s", key+1);
1547                                         goto parse_error;
1548                                 }
1549                                 if (param_defs[index].type == PARAM_TYPE_CALLERIDTYPE) {
1550                                         param->value_type = VALUE_TYPE_INTEGER;
1551                                         if (!strcasecmp(key, "unknown")) {
1552                                                 param->integer_value = INFO_NTYPE_UNKNOWN;
1553                                                 break;
1554                                         }
1555                                         if (!strcasecmp(key, "subscriber")) {
1556                                                 param->integer_value = INFO_NTYPE_SUBSCRIBER;
1557                                                 break;
1558                                         }
1559                                         if (!strcasecmp(key, "national")) {
1560                                                 param->integer_value = INFO_NTYPE_NATIONAL;
1561                                                 break;
1562                                         }
1563                                         if (!strcasecmp(key, "international")) {
1564                                                 param->integer_value = INFO_NTYPE_INTERNATIONAL;
1565                                                 break;
1566                                         }
1567                                         SPRINT(failure, "Caller ID type '%s' unknown.", key);
1568                                         goto parse_error;
1569                                 }
1570                                 if (param_defs[index].type == PARAM_TYPE_ON) {
1571                                         param->value_type = VALUE_TYPE_INTEGER;
1572                                         if (!strcasecmp(key, "init")) {
1573                                                 param->integer_value = INFO_ON_INIT;
1574                                                 break;
1575                                         }
1576                                         if (!strcasecmp(key, "hangup")) {
1577                                                 param->integer_value = INFO_ON_HANGUP;
1578                                                 break;
1579                                         }
1580                                         SPRINT(failure, "Execute on '%s' unknown.", key);
1581                                         goto parse_error;
1582                                 }
1583                                 if (param_defs[index].type == PARAM_TYPE_CAPABILITY) {
1584                                         param->value_type = VALUE_TYPE_INTEGER;
1585                                         if (!strcasecmp(key, "speech")) {
1586                                                 param->integer_value = INFO_BC_SPEECH;
1587                                                 break;
1588                                         }
1589                                         if (!strcasecmp(key, "audio")) {
1590                                                 param->integer_value = INFO_BC_AUDIO;
1591                                                 break;
1592                                         }
1593                                         if (!strcasecmp(key, "video")) {
1594                                                 param->integer_value = INFO_BC_VIDEO;
1595                                                 break;
1596                                         }
1597                                         if (!strcasecmp(key, "digital-restricted")) {
1598                                                 param->integer_value = INFO_BC_DATARESTRICTED;
1599                                                 break;
1600                                         }
1601                                         if (!strcasecmp(key, "digital-unrestricted")) {
1602                                                 param->integer_value = INFO_BC_DATAUNRESTRICTED;
1603                                                 break;
1604                                         }
1605                                         if (!strcasecmp(key, "digital-unrestricted-tones")) {
1606                                                 param->integer_value = INFO_BC_DATAUNRESTRICTED_TONES;
1607                                                 break;
1608                                         }
1609                                         SPRINT(failure, "Service type '%s' unknown.", key);
1610                                         goto parse_error;
1611                                 }
1612                                 if (param_defs[index].type == PARAM_TYPE_BMODE) {
1613                                         param->value_type = VALUE_TYPE_INTEGER;
1614                                         if (!strcasecmp(key, "transparent")) {
1615                                                 param->integer_value = INFO_BMODE_CIRCUIT;
1616                                                 break;
1617                                         }
1618                                         if (!strcasecmp(key, "hdlc")) {
1619                                                 param->integer_value = INFO_BMODE_PACKET;
1620                                                 break;
1621                                         }
1622                                         SPRINT(failure, "Bchannel mode '%s' unknown.", key);
1623                                         goto parse_error;
1624                                 }
1625                                 if (param_defs[index].type == PARAM_TYPE_DIVERSION) {
1626                                         param->value_type = VALUE_TYPE_INTEGER;
1627                                         if (!strcasecmp(key, "cfu")) {
1628                                                 param->integer_value = INFO_DIVERSION_CFU;
1629                                                 break;
1630                                         }
1631                                         if (!strcasecmp(key, "cfb")) {
1632                                                 param->integer_value = INFO_DIVERSION_CFB;
1633                                                 break;
1634                                         }
1635                                         if (!strcasecmp(key, "cfnr")) {
1636                                                 param->integer_value = INFO_DIVERSION_CFNR;
1637                                                 break;
1638                                         }
1639                                         if (!strcasecmp(key, "cfp")) {
1640                                                 param->integer_value = INFO_DIVERSION_CFP;
1641                                                 break;
1642                                         }
1643                                         SPRINT(failure, "Diversion type '%s' unknown.", key);
1644                                         goto parse_error;
1645                                 }
1646                                 if (param_defs[index].type == PARAM_TYPE_TYPE) {
1647                                         param->value_type = VALUE_TYPE_INTEGER;
1648                                         if (!strcasecmp(key, "unknown")) {
1649                                                 param->integer_value = INFO_NTYPE_UNKNOWN;
1650                                                 break;
1651                                         }
1652                                         if (!strcasecmp(key, "subscriber")) {
1653                                                 param->integer_value = INFO_NTYPE_SUBSCRIBER;
1654                                                 break;
1655                                         }
1656                                         if (!strcasecmp(key, "national")) {
1657                                                 param->integer_value = INFO_NTYPE_NATIONAL;
1658                                                 break;
1659                                         }
1660                                         if (!strcasecmp(key, "international")) {
1661                                                 param->integer_value = INFO_NTYPE_INTERNATIONAL;
1662                                                 break;
1663                                         }
1664                                         SPRINT(failure, "Number type '%s' unknown.", key);
1665                                         goto parse_error;
1666                                 }
1667                                 if (param_defs[index].type == PARAM_TYPE_YESNO) {
1668                                         param->value_type = VALUE_TYPE_INTEGER;
1669                                         if (!strcasecmp(key, "yes")) {
1670                                                 param->integer_value = 1;
1671                                                 break;
1672                                         }
1673                                         if (!strcasecmp(key, "no")) {
1674                                                 param->integer_value = 0;
1675                                                 break;
1676                                         }
1677                                         SPRINT(failure, "Value '%s' unknown. ('yes' or 'no')", key);
1678                                         goto parse_error;
1679                                 }
1680                                 param->string_value = (char *)MALLOC(strlen(key)+1);
1681                                 rmemuse++;
1682                                 UCPY(param->string_value, key);
1683                                 param->value_type = VALUE_TYPE_STRING;
1684                                 break;
1685
1686                                 default:
1687                                 SPRINT(failure, "Software error: PARAM_TYPE_* %d not parsed in function '%s'", param_defs[index].type, __FUNCTION__);
1688                                 goto parse_error;
1689                         }
1690
1691                         if (*p == ',') {
1692                                 p++;
1693                                 /* next item */
1694                                 param->value_extension = 1;
1695                                 goto nextparamvalue;
1696                         }
1697
1698                         /* end of line */
1699                         if (*p == '\0')
1700                                 break;
1701
1702                         /* to seperate the items, a space is required */
1703                         if (*p != ' ') {
1704                                 SPRINT(failure, "Character '%c' not expected here. Use ' ' to seperate parameters, or ',' for multiple values.", *p);
1705                                 goto parse_error;
1706                         }
1707                         /* skip spaces */
1708                         while(*p == 32)
1709                         {
1710                                 if (*p == 0)
1711                                         break;
1712                                 p++;
1713                         }
1714
1715                         /* check for next ACTION */
1716                         if (*p == ':') {
1717                                 p++;
1718                                 goto nextaction;
1719                         }
1720                 }
1721         }
1722
1723         fclose(fp[nesting--]);
1724         fduse--;
1725
1726         if (nesting >= 0)
1727                 goto go_root;
1728
1729         if (!ruleset_start) {
1730                 SPRINT(failure, "No ruleset defined.");
1731         }
1732         return(ruleset_start);
1733
1734         parse_error:
1735         printf("While parsing %s, an error occurred in line %d:\n", filename[nesting], line[nesting]);
1736         printf("-> %s\n", buffer);
1737         memset(pointer, ' ', sizeof(pointer));
1738         pointer[p-buffer] = '^';
1739         pointer[p-buffer+1] = '\0';
1740         printf("   %s\n", pointer);
1741         printf("%s\n", failure);
1742         SPRINT(ruleset_error, "Error in file %s, line %d: %s",  filename[nesting], line[nesting], failure);
1743
1744         openerror:
1745         while(nesting >= 0) {
1746                 fclose(fp[nesting--]);
1747                 fduse--;
1748         }
1749
1750         ruleset_free(ruleset_start);
1751         return(NULL);
1752 }
1753
1754 /*
1755  * return ruleset by name
1756  */
1757 struct route_ruleset *getrulesetbyname(const char *name)
1758 {
1759         struct route_ruleset *ruleset = ruleset_first;
1760
1761         while(ruleset) {
1762                 if (!strcasecmp(name, ruleset->name)) {
1763                         break;
1764                 }
1765                 ruleset = ruleset->next;
1766         }
1767         PDEBUG(DEBUG_ROUTE, "ruleset %s %s.\n", name, ruleset?"found":"not found");
1768         return(ruleset);
1769 }
1770
1771 /*
1772  * parses the current ruleset and returns action
1773  */
1774 struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
1775 {
1776         int                     match,
1777                                 couldmatch = 0, /* any rule could match */
1778                                 istrue,
1779                                 couldbetrue,
1780                                 condition,
1781                                 dialing_required,
1782                                 avail,
1783                                 any;
1784         struct route_rule       *rule = ruleset->rule_first;
1785         struct route_cond       *cond;
1786         struct route_action     *action = NULL;
1787         unsigned long           comp_len;
1788         int                     j, jj;
1789         char                    callerid[64], callerid2[64], redirid[64];
1790         int                     integer;
1791         char                    *string;
1792         FILE                    *tfp;
1793         double                  timeout;
1794         struct mISDNport        *mISDNport;
1795         struct admin_list       *admin;
1796
1797         /* reset timeout action */
1798         e_match_timeout = 0; /* no timeout */
1799         e_match_to_action = NULL;
1800
1801         SCPY(callerid, numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international));
1802         SCPY(callerid2, numberrize_callerinfo(e_callerinfo.id2, e_callerinfo.ntype2, options.national, options.international));
1803         SCPY(redirid, numberrize_callerinfo(e_redirinfo.id, e_redirinfo.ntype, options.national, options.international));
1804         
1805         PDEBUG(DEBUG_ROUTE, "parsing ruleset '%s'\n", ruleset->name);
1806         while(rule) {
1807                 PDEBUG(DEBUG_ROUTE, "checking rule in line %d\n", rule->line);
1808                 match = 1; /* this rule matches */
1809                 dialing_required = 0;
1810                 timeout = 0; /* timeout time */
1811                 cond = rule->cond_first;
1812                 while(cond) {
1813                         condition = 0; /* any condition element is true (1) or could be true (2) */
1814                         checkextension:
1815                         istrue = 0; /* this condition-element is true */
1816                         couldbetrue = 0; /* this conditions-element could be true */
1817                         switch(cond->match) {
1818                                 case MATCH_EXTERN:
1819                                 if (!e_ext.number[0])
1820                                         istrue = 1;      
1821                                 break;
1822
1823                                 case MATCH_INTERN:
1824                                 if (e_ext.number[0])
1825                                         istrue = 1;      
1826                                 break;
1827
1828                                 case MATCH_PORT:
1829                                 if (ea_endpoint->ep_portlist)
1830                                 if ((ea_endpoint->ep_portlist->port_type & PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1831                                         break;
1832                                 integer = e_callerinfo.isdn_port;
1833                                 goto match_integer;
1834
1835                                 case MATCH_INTERFACE:
1836                                 if (!e_callerinfo.interface[0])
1837                                         break;
1838                                 string = e_callerinfo.interface;
1839                                 goto match_string_prefix;
1840
1841                                 case MATCH_CALLERID:
1842                                 string = callerid;
1843                                 goto match_string_prefix;
1844
1845                                 case MATCH_CALLERID2:
1846                                 string = callerid2;
1847                                 goto match_string_prefix;
1848
1849                                 case MATCH_EXTENSION:
1850                                 string = e_ext.name;
1851                                 goto match_string;
1852
1853                                 case MATCH_DIALING:
1854                                 string = e_dialinginfo.id;
1855                                 goto match_string_prefix;
1856
1857                                 case MATCH_ENBLOCK:
1858                                 if (!e_overlap)
1859                                         istrue = 1;
1860                                 break;
1861
1862                                 case MATCH_OVERLAP:
1863                                 if (e_overlap)
1864                                         istrue = 1;
1865                                 break;
1866
1867                                 case MATCH_ANONYMOUS:
1868                                 if (e_callerinfo.present != INFO_PRESENT_ALLOWED)
1869                                         istrue = 1;
1870                                 break;
1871
1872                                 case MATCH_VISIBLE:
1873                                 if (e_callerinfo.present == INFO_PRESENT_ALLOWED)
1874                                         istrue = 1;
1875                                 break;
1876
1877                                 case MATCH_UNKNOWN:
1878                                 if (e_callerinfo.present == INFO_PRESENT_NOTAVAIL)
1879                                         istrue = 1;
1880                                 break;
1881
1882                                 case MATCH_AVAILABLE:
1883                                 if (e_callerinfo.present != INFO_PRESENT_NOTAVAIL)
1884                                         istrue = 1;
1885                                 break;
1886
1887                                 case MATCH_FAKE:
1888                                 if (e_callerinfo.screen == INFO_SCREEN_USER)
1889                                         istrue = 1;
1890                                 break;
1891
1892                                 case MATCH_REAL:
1893                                 if (e_callerinfo.screen != INFO_SCREEN_USER)
1894                                         istrue = 1;
1895                                 break;
1896
1897                                 case MATCH_REDIRECTED:
1898                                 if (e_redirinfo.ntype != INFO_NTYPE_NOTPRESENT)
1899                                         istrue = 1;
1900                                 break;
1901
1902                                 case MATCH_DIRECT:
1903                                 if (e_redirinfo.ntype == INFO_NTYPE_NOTPRESENT)
1904                                         istrue = 1;
1905                                 break;
1906
1907                                 case MATCH_REDIRID:
1908                                 string = redirid;
1909                                 goto match_string_prefix;
1910
1911                                 case MATCH_TIME:
1912                                 integer = now_tm->tm_hour*100 + now_tm->tm_min;
1913                                 goto match_integer;
1914
1915                                 case MATCH_MDAY:
1916                                 integer = now_tm->tm_mday;
1917                                 goto match_integer;
1918
1919                                 case MATCH_MONTH:
1920                                 integer = now_tm->tm_mon+1;
1921                                 goto match_integer;
1922
1923                                 case MATCH_YEAR:
1924                                 integer = now_tm->tm_year + 1900;
1925                                 goto match_integer;
1926
1927                                 case MATCH_WDAY:
1928                                 integer = now_tm->tm_wday;
1929                                 integer = integer?integer:7; /* correct sunday */
1930                                 goto match_integer;
1931
1932                                 case MATCH_CAPABILITY:
1933                                 integer = e_capainfo.bearer_capa;
1934                                 goto match_integer;
1935         
1936                                 case MATCH_INFOLAYER1:
1937                                 integer = e_capainfo.bearer_info1;
1938                                 goto match_integer;
1939
1940                                 case MATCH_HLC:
1941                                 integer = e_capainfo.hlc;
1942                                 goto match_integer;
1943
1944                                 case MATCH_FILE:
1945                                 tfp = fopen(cond->string_value, "r");
1946                                 if (!tfp) {
1947                                         break;
1948                                 }
1949                                 if (fgetc(tfp) == '1')
1950                                         istrue = 1;
1951                                 fclose(tfp);
1952                                 break;
1953
1954                                 case MATCH_EXECUTE:
1955                                 if (system(cond->string_value) == 0)
1956                                         istrue = 1;
1957                                 break;
1958
1959                                 case MATCH_DEFAULT:
1960                                 if (!couldmatch)
1961                                         istrue = 1;
1962                                 break;
1963
1964                                 case MATCH_TIMEOUT:
1965                                 timeout = now_d + cond->integer_value;
1966                                 istrue = 1;
1967                                 break;
1968
1969                                 case MATCH_FREE:
1970                                 case MATCH_NOTFREE:
1971                                 if (!(comp_len = (unsigned long)strchr(cond->string_value, ':')))
1972                                         break;
1973                                 comp_len = comp_len-(unsigned long)cond->string_value;
1974                                 avail = 0;
1975                                 mISDNport = mISDNport_first;
1976                                 while(mISDNport) {
1977                                         if (mISDNport->ifport)
1978                                         if (strlen(mISDNport->ifport->interface->name) == comp_len)
1979                                         if (!strncasecmp(mISDNport->ifport->interface->name, cond->string_value, comp_len)) 
1980                                         if (!mISDNport->l2hold || mISDNport->l2link>0) {
1981                                                 j = 0;
1982                                                 jj = mISDNport->b_num;
1983                                                 avail += jj;
1984                                                 while(j < jj) {
1985                                                         if (mISDNport->b_state[j])
1986                                                                 avail--;
1987                                                         j++;
1988                                                 }
1989                                         }
1990                                         mISDNport = mISDNport->next;
1991                                 }
1992                                 if (cond->match == MATCH_FREE) {
1993                                         if (avail >= atoi(cond->string_value + comp_len + 1))
1994                                                 istrue = 1;
1995                                 } else {
1996                                         if (avail < atoi(cond->string_value + comp_len + 1))
1997                                                 istrue = 1;
1998                                 }
1999                                 break;
2000
2001
2002                                 case MATCH_DOWN:
2003                                 mISDNport = mISDNport_first;
2004                                 while(mISDNport) {
2005                                         if (mISDNport->ifport)
2006                                         if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
2007                                         if (!mISDNport->l2hold || mISDNport->l2link>0)
2008                                                 break;
2009                                         mISDNport = mISDNport->next;
2010                                 }
2011                                 if (!mISDNport) /* all down */
2012                                         istrue = 1;
2013                                 break;
2014
2015                                 case MATCH_UP:
2016                                 mISDNport = mISDNport_first;
2017                                 while(mISDNport) {
2018                                         if (mISDNport->ifport)
2019                                         if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
2020                                         if (!mISDNport->l2hold || mISDNport->l2link>0)
2021                                                 break;
2022                                         
2023                                         mISDNport = mISDNport->next;
2024                                 }
2025                                 if (mISDNport) /* one link at least */
2026                                         istrue = 1;
2027                                 break;
2028
2029                                 case MATCH_BUSY:
2030                                 case MATCH_IDLE:
2031                                 any = 0;
2032                                 mISDNport = mISDNport_first;
2033                                 while(mISDNport) {
2034                                         if (mISDNport->ifport)
2035                                         if (!strcasecmp(mISDNport->ifport->interface->name, cond->string_value)) 
2036                                         if (mISDNport->use) /* break if in use */
2037                                                 break;
2038                                         mISDNport = mISDNport->next;
2039                                 }
2040                                 if (mISDNport && cond->match==MATCH_BUSY)
2041                                         istrue = 1;
2042                                 if (!mISDNport && cond->match==MATCH_IDLE)
2043                                         istrue = 1;
2044                                 break;
2045
2046                                 case MATCH_REMOTE:
2047                                 case MATCH_NOTREMOTE:
2048                                 admin = admin_first;
2049                                 while(admin) {
2050                                         if (admin->remote_name[0] && !strcmp(cond->string_value, admin->remote_name))
2051                                                 break;
2052                                         admin = admin->next;
2053                                 }
2054                                 if (admin && cond->match==MATCH_REMOTE)
2055                                         istrue = 1;
2056                                 if (!admin && cond->match==MATCH_NOTREMOTE)
2057                                         istrue = 1;
2058                                 break;
2059
2060                                 default:
2061                                 PERROR("Software error: MATCH_* %d not parsed in function '%s'", cond->match, __FUNCTION__);
2062                                 break;
2063
2064                                 match_integer:
2065                                 if (cond->value_type == VALUE_TYPE_INTEGER) {
2066                                         if (integer != cond->integer_value)
2067                                                 break;
2068                                         istrue = 1;
2069                                         break;
2070                                 }
2071                                 if (cond->value_type == VALUE_TYPE_INTEGER_RANGE) {
2072                                         /* check if negative range (2100 - 700 o'clock) */
2073                                         if (cond->integer_value > cond->integer_value_to) {
2074                                                 if (integer>=cond->integer_value && integer<=cond->integer_value_to)
2075                                                         istrue = 1;
2076                                                 break;
2077                                         }
2078                                         /* range is positive */
2079                                         if (integer>=cond->integer_value && integer<=cond->integer_value_to)
2080                                                 istrue = 1;
2081                                         break;
2082                                 }
2083                                 break;
2084
2085                                 match_string:
2086                                 if (strlen(cond->string_value) != strlen(string))
2087                                         break;
2088                                 /* fall through */
2089                                 match_string_prefix:
2090                                 comp_len = strlen(cond->string_value); /* because we must reach value's length */
2091                                 /* we must have greater or equal length to values */
2092                                 if ((unsigned long)strlen(string) < comp_len) {
2093                                         /* special case for unfinished dialing */
2094                                         if (cond->match == MATCH_DIALING) {
2095                                                 couldbetrue = 1; /* could match */
2096                                                 comp_len = strlen(string);
2097                                         } else {
2098                                                 break;
2099                                         }
2100                                 }
2101                                 /* on single string match */
2102                                 if (cond->value_type == VALUE_TYPE_STRING) {
2103                                         if (!strncmp(string, cond->string_value, comp_len)) {
2104                                                 istrue = 1;
2105                                                 /* must be set for changing 'e_extdialing' */
2106                                                 if (cond->match == MATCH_DIALING)
2107                                                         dialing_required = comp_len;
2108                                                 break;
2109                                         }
2110                                         break;
2111                                 }
2112                                 /* on range match */
2113                                 if (cond->value_type == VALUE_TYPE_STRING_RANGE) {
2114                                         /* check if negative range ("55"-"22") */
2115                                         if (cond->comp_string > 0) {
2116                                                 if (strncmp(string, cond->string_value, comp_len) >= 0) {
2117                                                         istrue = 1;
2118                                                         /* must be set for changing 'e_extdialing' */
2119                                                         if (cond->match == MATCH_DIALING)
2120                                                                 dialing_required = comp_len;
2121                                                         break;
2122                                                 }
2123                                                 if (strncmp(string, cond->string_value_to, comp_len) <= 0) {
2124                                                         /* must be set for changing 'e_extdialing' */
2125                                                         istrue = 1;
2126                                                         if (cond->match == MATCH_DIALING)
2127                                                                 dialing_required = comp_len;
2128                                                         break;
2129                                                 }
2130                                                 break;
2131                                         }
2132                                         /* range is positive */
2133                                         if (strncmp(string, cond->string_value, comp_len) < 0)
2134                                                 break;
2135                                         if (strncmp(string, cond->string_value_to, comp_len) > 0)
2136                                                 break;
2137                                         istrue = 1;
2138                                         if (cond->match == MATCH_DIALING)
2139                                                 dialing_required = comp_len;
2140                                         break;
2141                                 }
2142                                 break;
2143                         }
2144
2145                         /* set current condition */
2146                         if (istrue && !couldbetrue)
2147                                 condition = 1; /* element matches, so condition matches */
2148                         if (istrue && couldbetrue && !condition)
2149                                 condition = 2; /* element could match and other elements don't match, so condition could match */
2150
2151                         /* if not matching or could match */
2152                         if (condition != 1) {
2153                                 /* if we have more values to check */
2154                                 if (cond->value_extension && cond->next) {
2155                                         cond = cond->next;
2156                                         goto checkextension;
2157                                 }
2158                                 match = condition;
2159                                 break;
2160                         }
2161                         
2162                         /* skip exteded values, beacuse we already have one matching value */
2163                         while(cond->value_extension && cond->next)
2164                                 cond = cond->next;
2165
2166                         cond = cond->next;
2167                 }
2168                 if (timeout>now_d && match==1) /* the matching rule with timeout in the future */
2169                 if (e_match_timeout<1 || timeout<e_match_timeout) { /* first timeout or lower */
2170                         /* set timeout in the furture */
2171                         e_match_timeout = timeout;
2172                         e_match_to_action = rule->action_first;
2173                         e_match_to_extdialing = e_dialinginfo.id + dialing_required;
2174                         match = 0; /* matches in the future */
2175                 }
2176                 if (match == 1) {
2177                         /* matching, we return first action */
2178                         action = rule->action_first;
2179                         e_match_timeout = 0; /* no timeout */
2180                         e_match_to_action = NULL;
2181                         e_extdialing = e_dialinginfo.id + dialing_required;
2182                         break;
2183                 }
2184                 if (match == 2) {
2185                         /* rule could match if more is dialed */
2186                         couldmatch = 1;
2187                 }
2188                 rule = rule->next;
2189         }
2190         return(action);
2191 }
2192
2193 /*
2194  * parses the current action's parameters and return them
2195  */
2196 struct route_param *EndpointAppPBX::routeparam(struct route_action *action, unsigned long long id)
2197 {
2198         struct route_param *param = action->param_first;
2199
2200         while(param) {
2201                 if (param->id == id)
2202                         break;
2203                 param = param->next;
2204         }
2205         return(param);
2206 }
2207
2208
2209 /*
2210  * internal rules that are not defined by route.conf
2211  */
2212 struct route_action action_password = {
2213         NULL,
2214         NULL,
2215         ACTION_PASSWORD,
2216         0,
2217         0,
2218 };
2219
2220 struct route_action action_password_write = {
2221         NULL,
2222         NULL,
2223         ACTION_PASSWORD_WRITE,
2224         0,
2225         0,
2226 };
2227
2228 struct route_action action_external = {
2229         NULL,
2230         NULL,
2231         ACTION_EXTERNAL,
2232         0,
2233         0,
2234 };
2235
2236 struct route_action action_internal = {
2237         NULL,
2238         NULL,
2239         ACTION_INTERNAL,
2240         0,
2241         0,
2242 };
2243
2244 struct route_action action_remote = {
2245         NULL,
2246         NULL,
2247         ACTION_REMOTE,
2248         0,
2249         0,
2250 };
2251
2252 struct route_action action_vbox = {
2253         NULL,
2254         NULL,
2255         ACTION_VBOX_RECORD,
2256         0,
2257         0,
2258 };
2259
2260 struct route_action action_partyline = {
2261         NULL,
2262         NULL,
2263         ACTION_PARTYLINE,
2264         0,
2265         0,
2266 };
2267
2268 struct route_action action_disconnect = {
2269         NULL,
2270         NULL,
2271         ACTION_DISCONNECT,
2272         0,
2273         0,
2274 };
2275
2276