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