core, lib, modules: restructured source code tree
[sip-router] / src / modules / app_perl / perlfunc.c
1 /*
2  * $Id$
3  *
4  * Perl module for Kamailio
5  *
6  * Copyright (C) 2006 Collax GmbH 
7  *                    (Bastian Friedrich <bastian.friedrich@collax.com>)
8  *
9  * This file is part of Kamailio, a free SIP server.
10  *
11  * Kamailio is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * Kamailio is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24  *
25  */
26
27 #include <string.h>
28 #include <stdio.h>
29
30 #include "../../mem/mem.h"
31 #include "../../data_lump.h"
32 #include "../../parser/parse_param.h"
33 #include "../../parser/msg_parser.h"
34 #include "../../dprint.h"
35 #include "../../action.h"
36 #include "../../config.h"
37 #include "../../parser/parse_uri.h"
38
39 #include "perlfunc.h"
40 #include "app_perl_mod.h"
41
42
43 /*
44  * Check for existence of a function.
45  */
46 int perl_checkfnc(char *fnc) {
47
48         if (get_cv(fnc, 0)) {
49                 return 1;
50         } else {
51                 return 0;
52         }
53 }
54
55 /*
56  * Run function without paramters
57  */
58
59 int perl_exec_simple(char* fnc, char* args[], int flags) {
60
61         app_perl_reset_interpreter();
62         if (perl_checkfnc(fnc)) {
63                 LM_DBG("running perl function \"%s\"", fnc);
64
65                 call_argv(fnc, flags, args);
66         } else {
67                 LM_ERR("unknown function '%s' called.\n", fnc);
68                 return -1;
69         }
70
71         return 1;
72 }
73
74 int perl_exec_simple1(struct sip_msg* _msg, char* fnc, char* str2) {
75         char *args[] = { NULL };
76
77         return perl_exec_simple(fnc, args, G_DISCARD | G_NOARGS | G_EVAL);
78 }
79
80 int perl_exec_simple2(struct sip_msg* _msg, char* fnc, char* param) {
81         char *args[] = { param, NULL };
82
83         return perl_exec_simple(fnc, args, G_DISCARD | G_EVAL);
84 }
85
86 /*
87  * Run function, with current SIP message as a parameter
88  */
89 int perl_exec1(struct sip_msg* _msg, char* fnc, char *foobar) {
90         return perl_exec2(_msg, fnc, NULL);
91 }
92
93 int perl_exec2(struct sip_msg* _msg, char* fnc, char* mystr) {
94         int retval;
95         SV *m;
96         str reason;
97
98         app_perl_reset_interpreter();
99
100         dSP;
101
102         if (!perl_checkfnc(fnc)) {
103                 LM_ERR("unknown perl function called.\n");
104                 reason.s = "Internal error";
105                 reason.len = sizeof("Internal error")-1;
106                 if (slb.freply(_msg, 500, &reason) == -1)
107                 {
108                         LM_ERR("failed to send reply\n");
109                 }
110                 return -1;
111         }
112         
113         switch ((_msg->first_line).type) {
114         case SIP_REQUEST:
115                 if (parse_sip_msg_uri(_msg) < 0) {
116                         LM_ERR("failed to parse Request-URI\n");
117
118                         reason.s = "Bad Request-URI";
119                         reason.len = sizeof("Bad Request-URI")-1;
120                         if (slb.freply(_msg, 400, &reason) == -1) {
121                                 LM_ERR("failed to send reply\n");
122                         }
123                         return -1;
124                 }
125                 break;
126         case SIP_REPLY:
127                 break;
128         default:
129                 LM_ERR("invalid firstline");
130                 return -1;
131         }
132
133         ENTER;                          /* everything created after here */
134         SAVETMPS;                       /* ...is a temporary variable.   */
135         PUSHMARK(SP);           /* remember the stack pointer    */
136
137         m = sv_newmortal();
138         sv_setref_pv(m, "Kamailio::Message", (void *)_msg);
139         SvREADONLY_on(SvRV(m));
140
141         XPUSHs(m);                      /* Our reference to the stack... */
142
143         if (mystr)
144                 XPUSHs(sv_2mortal(newSVpv(mystr, strlen(mystr))));
145                                         /* Our string to the stack... */
146
147         PUTBACK;                        /* make local stack pointer global */
148
149         call_pv(fnc, G_EVAL|G_SCALAR);          /* call the function     */
150         SPAGAIN;                        /* refresh stack pointer         */
151         /* pop the return value from stack */
152         retval = POPi;
153
154         PUTBACK;
155         FREETMPS;                       /* free that return value        */
156         LEAVE;                          /* ...and the XPUSHed "mortal" args.*/
157
158         return retval;
159 }