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