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