modules/app_perl/perlfunc.c
ac9ce6fb
 /*
  * $Id$
  *
f448282e
  * Perl module for Kamailio
ac9ce6fb
  *
  * Copyright (C) 2006 Collax GmbH 
  *                    (Bastian Friedrich <bastian.friedrich@collax.com>)
  *
27642a08
  * This file is part of Kamailio, a free SIP server.
ac9ce6fb
  *
27642a08
  * Kamailio is free software; you can redistribute it and/or modify
ac9ce6fb
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
27642a08
  * Kamailio is distributed in the hope that it will be useful,
ac9ce6fb
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
ac9ce6fb
  *
  */
 
 #include <string.h>
 #include <stdio.h>
 
 #include "../../mem/mem.h"
 #include "../../data_lump.h"
 #include "../../parser/parse_param.h"
 #include "../../parser/msg_parser.h"
 #include "../../dprint.h"
 #include "../../action.h"
 #include "../../config.h"
 #include "../../parser/parse_uri.h"
 
 #include "perlfunc.h"
ba3fa594
 #include "app_perl_mod.h"
ac9ce6fb
 
 
 /*
  * Check for existence of a function.
  */
 int perl_checkfnc(char *fnc) {
 
 	if (get_cv(fnc, 0)) {
 		return 1;
 	} else {
 		return 0;
 	}
 }
 
 /*
  * Run function without paramters
  */
 
 int perl_exec_simple(char* fnc, char* args[], int flags) {
 
b5527627
 	app_perl_reset_interpreter();
ac9ce6fb
 	if (perl_checkfnc(fnc)) {
387847d7
 		LM_DBG("running perl function \"%s\"", fnc);
ac9ce6fb
 
 		call_argv(fnc, flags, args);
 	} else {
387847d7
 		LM_ERR("unknown function '%s' called.\n", fnc);
ac9ce6fb
 		return -1;
 	}
 
 	return 1;
 }
 
 int perl_exec_simple1(struct sip_msg* _msg, char* fnc, char* str2) {
 	char *args[] = { NULL };
 
 	return perl_exec_simple(fnc, args, G_DISCARD | G_NOARGS | G_EVAL);
 }
 
 int perl_exec_simple2(struct sip_msg* _msg, char* fnc, char* param) {
 	char *args[] = { param, NULL };
 
 	return perl_exec_simple(fnc, args, G_DISCARD | G_EVAL);
 }
 
 /*
  * Run function, with current SIP message as a parameter
  */
 int perl_exec1(struct sip_msg* _msg, char* fnc, char *foobar) {
 	return perl_exec2(_msg, fnc, NULL);
 }
 
 int perl_exec2(struct sip_msg* _msg, char* fnc, char* mystr) {
 	int retval;
 	SV *m;
3ebe3eef
 	str reason;
ac9ce6fb
 
b5527627
 	app_perl_reset_interpreter();
 
ac9ce6fb
 	dSP;
 
 	if (!perl_checkfnc(fnc)) {
387847d7
 		LM_ERR("unknown perl function called.\n");
3ebe3eef
 		reason.s = "Internal error";
 		reason.len = sizeof("Internal error")-1;
3f611962
 		if (slb.freply(_msg, 500, &reason) == -1)
ac9ce6fb
 		{
387847d7
 			LM_ERR("failed to send reply\n");
ac9ce6fb
 		}
 		return -1;
 	}
1624884c
 	
 	switch ((_msg->first_line).type) {
 	case SIP_REQUEST:
 		if (parse_sip_msg_uri(_msg) < 0) {
387847d7
 			LM_ERR("failed to parse Request-URI\n");
1624884c
 
 			reason.s = "Bad Request-URI";
 			reason.len = sizeof("Bad Request-URI")-1;
3f611962
 			if (slb.freply(_msg, 400, &reason) == -1) {
387847d7
 				LM_ERR("failed to send reply\n");
1624884c
 			}
 			return -1;
ac9ce6fb
 		}
1624884c
 		break;
 	case SIP_REPLY:
 		break;
 	default:
387847d7
 		LM_ERR("invalid firstline");
ac9ce6fb
 		return -1;
 	}
 
 	ENTER;				/* everything created after here */
 	SAVETMPS;			/* ...is a temporary variable.   */
6ff74701
 	PUSHMARK(SP);		/* remember the stack pointer    */
ac9ce6fb
 
6ff74701
 	m = sv_newmortal();
 	sv_setref_pv(m, "Kamailio::Message", (void *)_msg);
 	SvREADONLY_on(SvRV(m));
 
341f810d
 	XPUSHs(m);			/* Our reference to the stack... */
 
ac9ce6fb
 	if (mystr)
 		XPUSHs(sv_2mortal(newSVpv(mystr, strlen(mystr))));
 					/* Our string to the stack... */
 
 	PUTBACK;			/* make local stack pointer global */
 
 	call_pv(fnc, G_EVAL|G_SCALAR);		/* call the function     */
 	SPAGAIN;			/* refresh stack pointer         */
 	/* pop the return value from stack */
 	retval = POPi;
 
 	PUTBACK;
 	FREETMPS;			/* free that return value        */
 	LEAVE;				/* ...and the XPUSHed "mortal" args.*/
 
 	return retval;
 }