all: updated FSF address in GPL text
[sip-router] / modules / app_mono / app_mono_mod.c
1 /**
2  * $Id$
3  *
4  * Copyright (C) 2011 Daniel-Constantin Mierla (asipto.com)
5  *
6  * This file is part of 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  */
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27
28 #include "../../sr_module.h"
29 #include "../../dprint.h"
30 #include "../../ut.h"
31 #include "../../mod_fix.h"
32
33 #include "app_mono_api.h"
34
35 MODULE_VERSION
36
37 /** parameters */
38
39 /* List of allowed chars for a prefix*/
40 static int  mod_init(void);
41 static void mod_destroy(void);
42 static int  child_init(int rank);
43
44 static int w_app_mono_exec(struct sip_msg *msg, char *script, char *mparam);
45 static int w_app_mono_run(struct sip_msg *msg, char *mparam, char *extra);
46
47 static int fixup_mono_exec(void** param, int param_no);
48
49 int app_mono_load_param(modparam_t type, void *val);
50 int app_mono_register_param(modparam_t type, void *val);
51
52 static param_export_t params[]={
53         {"load",     STR_PARAM|USE_FUNC_PARAM, (void*)app_mono_load_param},
54         {"register", STR_PARAM|USE_FUNC_PARAM, (void*)app_mono_register_param},
55         {0, 0, 0}
56 };
57
58 static cmd_export_t cmds[]={
59         {"mono_exec", (cmd_function)w_app_mono_exec, 1, fixup_mono_exec,
60                 0, ANY_ROUTE},
61         {"mono_exec", (cmd_function)w_app_mono_exec, 2, fixup_mono_exec,
62                 0, ANY_ROUTE},
63         {"mono_run",  (cmd_function)w_app_mono_run,  0, 0,
64                 0, ANY_ROUTE},
65         {"mono_run", (cmd_function)w_app_mono_run,   1, fixup_spve_null,
66                 0, ANY_ROUTE},
67         {0, 0, 0, 0, 0, 0}
68 };
69
70 struct module_exports exports = {
71         "app_mono",
72         RTLD_NOW | RTLD_GLOBAL, /* dlopen flags */
73         cmds,
74         params,
75         0,
76         0,              /* exported MI functions */
77         0,              /* exported pseudo-variables */
78         0,              /* extra processes */
79         mod_init,       /* module initialization function */
80         0,              /* response function */
81         mod_destroy,    /* destroy function */
82         child_init      /* per child init function */
83 };
84
85
86
87 /**
88  * init module function
89  */
90 static int mod_init(void)
91 {
92         mono_sr_init_mod();
93         return 0;
94 }
95
96
97 /* each child get a new connection to the database */
98 static int child_init(int rank)
99 {
100         if(rank==PROC_MAIN || rank==PROC_TCP_MAIN)
101                 return 0; /* do nothing for the main process */
102
103         if (rank==PROC_INIT)
104         {
105                 /* do a probe before forking */
106                 if(mono_sr_init_probe()!=0)
107                         return -1;
108                 return 0;
109         }
110         if(mono_sr_init_child()<0)
111                 return -1;
112         if(mono_sr_init_load()<0)
113                 return -1;
114         return 0;
115 }
116
117
118 static void mod_destroy(void)
119 {
120         mono_sr_destroy();
121 }
122
123 char _mono_buf_stack[2][512];
124
125 /**
126  *
127  */
128 static int w_app_mono_exec(struct sip_msg *msg, char *script, char *mparam)
129 {
130         str s;
131         str p;
132
133         if(!mono_sr_initialized())
134         {
135                 LM_ERR("Lua env not intitialized");
136                 return -1;
137         }
138         if(fixup_get_svalue(msg, (gparam_p)script, &s)<0)
139         {
140                 LM_ERR("cannot get the script\n");
141                 return -1;
142         }
143         if(s.len>=511)
144         {
145                 LM_ERR("script too long %d\n", s.len);
146                 return -1;
147         }
148         if(mparam!=NULL)
149         {
150                 if(fixup_get_svalue(msg, (gparam_p)mparam, &p)<0)
151                 {
152                         LM_ERR("cannot get the parameter\n");
153                         return -1;
154                 }
155                 if(p.len>=511)
156                 {
157                         LM_ERR("parameter value too long %d\n", p.len);
158                         return -1;
159                 }
160                 memcpy(_mono_buf_stack[1], p.s, p.len);
161                 _mono_buf_stack[1][p.len] = '\0';
162         }
163         memcpy(_mono_buf_stack[0], s.s, s.len);
164         _mono_buf_stack[0][s.len] = '\0';
165         return app_mono_exec(msg, _mono_buf_stack[0],
166                         (mparam)?_mono_buf_stack[1]:NULL);
167 }
168
169 /**
170  *
171  */
172 static int w_app_mono_run(struct sip_msg *msg, char *mparam, char *extra)
173 {
174         str p;
175
176         if(!mono_sr_initialized())
177         {
178                 LM_ERR("Lua env not intitialized");
179                 return -1;
180         }
181         if(mparam!=NULL)
182         {
183                 if(fixup_get_svalue(msg, (gparam_p)mparam, &p)<0)
184                 {
185                         LM_ERR("cannot get the parameter\n");
186                         return -1;
187                 }
188                 if(p.len>=511)
189                 {
190                         LM_ERR("parameter value too long %d\n", p.len);
191                         return -1;
192                 }
193                 memcpy(_mono_buf_stack[0], p.s, p.len);
194                 _mono_buf_stack[0][p.len] = '\0';
195         }
196         return app_mono_run(msg, (mparam)?_mono_buf_stack[0]:NULL);
197 }
198
199
200 int app_mono_load_param(modparam_t type, void *val)
201 {
202         if(val==NULL)
203                 return -1;
204         return sr_mono_load_script((char*)val);
205 }
206
207 int app_mono_register_param(modparam_t type, void *val)
208 {
209         if(val==NULL)
210                 return -1;
211         return sr_mono_register_module((char*)val);
212 }
213
214 static int fixup_mono_exec(void** param, int param_no)
215 {
216         if(sr_mono_assembly_loaded())
217         {
218                 LM_ERR("cannot use lua_exec(...) when an assembly is loaded\n");
219                 return -1;
220         }
221         return fixup_spve_null(param, 1);
222 }
223