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