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