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