1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
/*
* $Id: script_cb.c,v 1.3 2005/06/20 07:46:45 bogdan_iancu Exp $
*
* Script callbacks
*
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of openser, a free SIP server.
*
* openser is free software; you can redistribute it and/or modify
* 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
*
* openser is distributed in the hope that it will be useful,
* 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
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* --------
* 2003-03-29 cleaning pkg allocation introduced (jiri)
* 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
* 2005-02-13 script callbacks devided into request and reply types (bogdan)
*/
#include <stdlib.h>
#include "script_cb.h"
#include "dprint.h"
#include "error.h"
#include "mem/mem.h"
static struct script_cb *pre_req_cb=0;
static struct script_cb *post_req_cb=0;
static struct script_cb *pre_rpl_cb=0;
static struct script_cb *post_rpl_cb=0;
static unsigned int cb_id=0;
static inline int add_callback( struct script_cb **list,
cb_function f, void *param)
{
struct script_cb *new_cb;
new_cb=pkg_malloc(sizeof(struct script_cb));
if (new_cb==0) {
LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
return -1;
}
new_cb->cbf = f;
new_cb->id = cb_id++;
new_cb->param = param;
/* link at the beginning of the list */
new_cb->next = *list;
*list = new_cb;
return 0;
}
int register_script_cb( cb_function f, int type, void *param )
{
/* type checkings */
if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
"type not specified\n");
goto error;
}
if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
(type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
"be exactly one\n");
goto error;
}
if (type&REQ_TYPE_CB) {
/* callback for request script */
if (type&PRE_SCRIPT_CB) {
if (add_callback( &pre_req_cb, f, param)<0)
goto add_error;
} else if (type&POST_SCRIPT_CB) {
if (add_callback( &post_req_cb, f, param)<0)
goto add_error;
}
}
if (type&RPL_TYPE_CB) {
/* callback (also) for reply script */
if (type&PRE_SCRIPT_CB) {
if (add_callback( &pre_rpl_cb, f, param)<0)
goto add_error;
} else if (type&POST_SCRIPT_CB) {
if (add_callback( &post_rpl_cb, f, param)<0)
goto add_error;
}
}
return 0;
add_error:
LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
error:
return -1;
}
static inline void destroy_cb_list(struct script_cb **list)
{
struct script_cb *foo;
while( *list ) {
foo = *list;
*list = (*list)->next;
pkg_free( foo );
}
}
void destroy_script_cb()
{
destroy_cb_list( &pre_req_cb );
destroy_cb_list( &post_req_cb );
destroy_cb_list( &pre_rpl_cb );
destroy_cb_list( &post_req_cb );
}
static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
{
for ( ; cb ; cb=cb->next ) {
/* stop on error */
if (cb->cbf(msg, cb->param)==0)
return 0;
}
return 1;
}
static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
{
for ( ; cb ; cb=cb->next){
cb->cbf( msg, cb->param);
}
return 1;
}
int exec_pre_req_cb( struct sip_msg *msg)
{
return exec_pre_cb( msg, pre_req_cb);
}
int exec_pre_rpl_cb( struct sip_msg *msg)
{
return exec_pre_cb( msg, pre_rpl_cb);
}
int exec_post_req_cb( struct sip_msg *msg)
{
return exec_post_cb( msg, post_req_cb);
}
int exec_post_rpl_cb( struct sip_msg *msg)
{
return exec_post_cb( msg, post_rpl_cb);
}
|