core, lib, modules: restructured source code tree
[sip-router] / src / modules / alias_db / alias_db.c
1 /*
2  * ALIAS_DB Module
3  *
4  * Copyright (C) 2004 Voice Sistem SRL
5  *
6  * This file is part of a module for Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  * History:
23  * --------
24  * 2004-09-01: first version (ramona)
25  */
26
27
28 #include <stdio.h>
29 #include <string.h>
30 #include "../../sr_module.h"
31 #include "../../lib/srdb1/db.h"
32 #include "../../dprint.h"
33 #include "../../error.h"
34 #include "../../mem/mem.h"
35 #include "../../ut.h"
36 #include "../../mod_fix.h"
37
38 #include "alookup.h"
39 #include "api.h"
40
41 MODULE_VERSION
42
43
44 /* Module destroy function prototype */
45 static void destroy(void);
46
47
48 /* Module child-init function prototype */
49 static int child_init(int rank);
50
51
52 /* Module initialization function prototype */
53 static int mod_init(void);
54
55 /* Fixup function */
56 static int lookup_fixup(void** param, int param_no);
57 static int find_fixup(void** param, int param_no);
58
59 static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2);
60 static int w_alias_db_lookup2(struct sip_msg* _msg, char* _table, char* flags);
61 static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in,
62                 char* _out);
63 static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in,
64                 char* _out, char* flags);
65
66
67 /* Module parameter variables */
68 static str db_url       = str_init(DEFAULT_RODB_URL);
69 str user_column         = str_init("username");
70 str domain_column       = str_init("domain");
71 str alias_user_column   = str_init("alias_username");
72 str alias_domain_column = str_init("alias_domain");
73 str domain_prefix       = {NULL, 0};
74 int alias_db_use_domain = 0;
75 int ald_append_branches = 0;
76
77 db1_con_t* db_handle;   /* Database connection handle */
78 db_func_t adbf;  /* DB functions */
79
80 /* Exported functions */
81 static cmd_export_t cmds[] = {
82         {"alias_db_lookup", (cmd_function)w_alias_db_lookup1, 1, lookup_fixup, 0,
83                 REQUEST_ROUTE|FAILURE_ROUTE},
84         {"alias_db_lookup", (cmd_function)w_alias_db_lookup2, 2, lookup_fixup, 0,
85                 REQUEST_ROUTE|FAILURE_ROUTE},
86         {"alias_db_find", (cmd_function)w_alias_db_find3, 3, find_fixup, 0,
87                 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
88         {"alias_db_find", (cmd_function)w_alias_db_find4, 4, find_fixup, 0,
89                 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
90         {"bind_alias_db",   (cmd_function)bind_alias_db, 1, 0, 0,
91                 0},
92         {0, 0, 0, 0, 0, 0}
93 };
94
95
96 /* Exported parameters */
97 static param_export_t params[] = {
98         {"db_url",              PARAM_STR, &db_url        },
99         {"user_column",         PARAM_STR, &user_column   },
100         {"domain_column",       PARAM_STR, &domain_column },
101         {"alias_user_column",   PARAM_STR, &alias_user_column   },
102         {"alias_domain_column", PARAM_STR, &alias_domain_column },
103         {"use_domain",          INT_PARAM, &alias_db_use_domain },
104         {"domain_prefix",       PARAM_STR, &domain_prefix },
105         {"append_branches",     INT_PARAM, &ald_append_branches   },
106         {0, 0, 0}
107 };
108
109
110 /* Module interface */
111 struct module_exports exports = {
112         "alias_db",
113         DEFAULT_DLFLAGS, /* dlopen flags */
114         cmds,       /* Exported functions */
115         params,     /* Exported parameters */
116         0,          /* exported statistics */
117         0,          /* exported MI functions */
118         0,          /* exported pseudo-variables */
119         0,          /* extra processes */
120         mod_init,   /* module initialization function */
121         0,          /* response function */
122         destroy,    /* destroy function */
123         child_init  /* child initialization function */
124 };
125
126
127 static int alias_flags_fixup(void** param)
128 {
129         char *c;
130         unsigned int flags;
131
132         c = (char*)*param;
133         flags = 0;
134
135         if(alias_db_use_domain) {
136                 flags |= ALIAS_DOMAIN_FLAG;
137         }
138
139         while (*c) {
140                 switch (*c)
141                 {
142                         case 'd':
143                         case 'D':
144                                 flags &= ~ALIAS_DOMAIN_FLAG;
145                                 break;
146                         case 'r':
147                         case 'R':
148                                 flags |= ALIAS_REVERSE_FLAG;
149                                 break;
150                         case 'u':
151                         case 'U':
152                                 flags |= ALIAS_DOMAIN_FLAG;
153                                 break;
154                         default:
155                                 LM_ERR("unsupported flag '%c'\n",*c);
156                                 return -1;
157                 }
158                 c++;
159         }
160         pkg_free(*param);
161         *param = (void*)(unsigned long)flags;
162         return 0;
163 }
164
165
166 static int lookup_fixup(void** param, int param_no)
167 {
168         if (param_no==1)
169         {
170                 /* string or pseudo-var - table name */
171                 return fixup_spve_null(param, 1);
172         } else if (param_no==2) {
173                 /* string - flags ? */
174                 return alias_flags_fixup(param);
175         } else {
176                 LM_CRIT(" invalid number of params %d \n",param_no);
177                 return -1;
178         }
179 }
180
181
182 static int find_fixup(void** param, int param_no)
183 {
184         pv_spec_t *sp;
185
186         if (param_no==1)
187         {
188                 /* string or pseudo-var - table name */
189                 return fixup_spve_null(param, 1);
190         } else if(param_no==2) {
191                 /* pseudo-var - source URI */
192                 return fixup_pvar_null(param, 1);
193         } else if(param_no==3) {
194                 /* pvar (AVP or VAR) - destination URI */
195                 if (fixup_pvar_null(param, 1))
196                         return E_CFG;
197                 sp = (pv_spec_t*)*param;
198                 if (sp->type!=PVT_AVP && sp->type!=PVT_SCRIPTVAR)
199                 {
200                         LM_ERR("PV type %d (param 3) cannot be written\n", sp->type);
201                         pv_spec_free(sp);
202                         return E_CFG;
203                 }
204                 return 0;
205         } else if (param_no==4) {
206                 /* string - flags  ? */
207                 return alias_flags_fixup(param);
208         } else {
209                 LM_CRIT(" invalid number of params %d \n",param_no);
210                 return -1;
211         }
212 }
213
214
215 /**
216  *
217  */
218 static int child_init(int rank)
219 {
220         if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
221                 return 0; /* do nothing for the main process */
222
223         db_handle = adbf.init(&db_url);
224         if (!db_handle)
225         {
226                 LM_ERR("unable to connect database\n");
227                 return -1;
228         }
229         return 0;
230
231 }
232
233
234 /**
235  *
236  */
237 static int mod_init(void)
238 {
239         /* Find a database module */
240         if (db_bind_mod(&db_url, &adbf))
241         {
242                 LM_ERR("unable to bind database module\n");
243                 return -1;
244         }
245         if (!DB_CAPABILITY(adbf, DB_CAP_QUERY))
246         {
247                 LM_CRIT("database modules does not "
248                         "provide all functions needed by alias_db module\n");
249                 return -1;
250         }
251
252         return 0;
253 }
254
255
256 /**
257  *
258  */
259 static void destroy(void)
260 {
261         if (db_handle) {
262                 adbf.close(db_handle);
263                 db_handle = 0;
264         }
265 }
266
267 static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2)
268 {
269         str table_s;
270         unsigned long flags;
271
272         flags = 0;
273         if(alias_db_use_domain) {
274                 flags |= ALIAS_DOMAIN_FLAG;
275         }
276
277         if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
278                 LM_ERR("invalid table parameter\n");
279                 return -1;
280         }
281
282         return alias_db_lookup_ex(_msg, table_s, flags);
283 }
284
285 static int w_alias_db_lookup2(struct sip_msg* _msg, char* _table, char* flags)
286 {
287         str table_s;
288
289         if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
290                 LM_ERR("invalid table parameter\n");
291         return -1;
292         }
293
294         return alias_db_lookup_ex(_msg, table_s, (unsigned long)flags);
295 }
296
297 static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in,
298                 char* _out)
299 {
300         str table_s;
301         unsigned long flags;
302
303         flags = 0;
304         if(alias_db_use_domain) {
305                 flags |= ALIAS_DOMAIN_FLAG;
306         }
307
308         if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
309                 LM_ERR("invalid table parameter\n");
310                 return -1;
311         }
312
313         return alias_db_find(_msg, table_s, _in, _out, (char*)flags);
314 }
315
316 static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in,
317                 char* _out, char* flags)
318 {
319         str table_s;
320
321         if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
322                 LM_ERR("invalid table parameter\n");
323                 return -1;
324         }
325
326         return alias_db_find(_msg, table_s, _in, _out, flags);
327 }
328
329 int bind_alias_db(struct alias_db_binds *pxb)
330 {
331         if (pxb == NULL) {
332                 LM_WARN("bind_alias_db: Cannot load alias_db API into a NULL pointer\n");
333                 return -1;
334         }
335
336         pxb->alias_db_lookup = alias_db_lookup;
337         pxb->alias_db_lookup_ex = alias_db_lookup_ex;
338         pxb->alias_db_find = alias_db_find;
339         return 0;
340 }