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