mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
5.9 KiB
279 lines
5.9 KiB
/*
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2006 Voice Sistem SRL
|
|
*
|
|
* This file is part of Kamailio.
|
|
*
|
|
* Kamailio 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.
|
|
*
|
|
* Kamailio 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* History:
|
|
* ---------
|
|
* 2006-11-30 first version (lavinia)
|
|
* 2007-10-05 support for libxmlrpc-c3 version 1.x.x added (dragos)
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <sys/signal.h>
|
|
#include <sys/wait.h>
|
|
#include <grp.h>
|
|
#include <stdlib.h>
|
|
#include "mi_xmlrpc.h"
|
|
#include "xr_writer.h"
|
|
#include "xr_parser.h"
|
|
#include "xr_server.h"
|
|
|
|
#define XMLRPC_SERVER_WANT_ABYSS_HANDLERS
|
|
|
|
#ifdef XMLRPC_OLD_VERSION
|
|
|
|
#include "abyss.h"
|
|
#include <xmlrpc_abyss.h>
|
|
#include <xmlrpc.h>
|
|
|
|
#else
|
|
|
|
#include <xmlrpc-c/base.h>
|
|
#include <xmlrpc-c/abyss.h>
|
|
#include <xmlrpc-c/server.h>
|
|
#include <xmlrpc-c/server_abyss.h>
|
|
|
|
#endif
|
|
|
|
|
|
#include "../../sr_module.h"
|
|
#include "../../str.h"
|
|
#include "../../pt.h"
|
|
#include "../../mem/mem.h"
|
|
#include "../../mem/shm_mem.h"
|
|
#include "../../cfg/cfg_struct.h"
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_value * xr_response;
|
|
xmlrpc_registry * registryP;
|
|
|
|
int rpl_opt = 0;
|
|
|
|
/* module functions */
|
|
static int mod_init();
|
|
static void destroy(void);
|
|
static int child_init(int rank);
|
|
static void xmlrpc_process(int rank);
|
|
|
|
static int port = 8080;
|
|
static char *log_file = NULL;
|
|
static int read_buf_size = MAX_READ;
|
|
static TServer srv;
|
|
MODULE_VERSION
|
|
|
|
|
|
static proc_export_t mi_procs[] = {
|
|
{"MI XMLRPC", 0, 0, xmlrpc_process, 1 },
|
|
{0,0,0,0,0}
|
|
};
|
|
|
|
|
|
/* module parameters */
|
|
static param_export_t mi_params[] = {
|
|
{"port", INT_PARAM, &port},
|
|
{"log_file", PARAM_STRING, &log_file},
|
|
{"reply_option", INT_PARAM, &rpl_opt},
|
|
{"buffer_size", INT_PARAM, &read_buf_size},
|
|
{0,0,0}
|
|
};
|
|
|
|
/* module exports */
|
|
struct module_exports exports = {
|
|
"mi_xmlrpc", /* module name */
|
|
DEFAULT_DLFLAGS, /* dlopen flags */
|
|
0, /* exported functions */
|
|
mi_params, /* exported parameters */
|
|
0, /* exported statistics */
|
|
0, /* exported MI functions */
|
|
0, /* exported PV */
|
|
mi_procs, /* extra processes */
|
|
mod_init, /* module initialization function */
|
|
0, /* response handling function */
|
|
destroy, /* destroy function */
|
|
child_init /* per-child init function */
|
|
};
|
|
|
|
|
|
static int mod_init(void)
|
|
{
|
|
LM_DBG("testing port number...\n");
|
|
|
|
if ( port <= 1024 ) {
|
|
LM_WARN("port<1024, using 8080...\n");
|
|
port = 8080;
|
|
}
|
|
|
|
if (init_async_lock()!=0) {
|
|
LM_ERR("failed to init async lock\n");
|
|
return -1;
|
|
}
|
|
|
|
/* add space for extra processes */
|
|
register_procs(1);
|
|
|
|
/* add child to update local config framework structures */
|
|
cfg_register_child(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int child_init(int rank)
|
|
{
|
|
int pid;
|
|
if (rank==PROC_MAIN) {
|
|
pid=fork_process(PROC_NOCHLDINIT, "MI XMLRPC", 1);
|
|
if (pid<0)
|
|
return -1; /* error */
|
|
if(pid==0){
|
|
/* child */
|
|
|
|
/* initialize the config framework */
|
|
if (cfg_child_init())
|
|
return -1;
|
|
|
|
xmlrpc_process(1);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void xmlrpc_sigchld( int sig )
|
|
{
|
|
pid_t pid;
|
|
int status;
|
|
|
|
while(1) {
|
|
pid = waitpid( (pid_t) -1, &status, WNOHANG );
|
|
|
|
/* none left */
|
|
if ( pid == 0 )
|
|
break;
|
|
|
|
if (pid<0) {
|
|
/* because of ptrace */
|
|
if ( errno == EINTR )
|
|
continue;
|
|
|
|
break;
|
|
}
|
|
#ifndef XMLRPC_OLD_VERSION
|
|
else
|
|
ServerHandleSigchld(pid);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
static void xmlrpc_process(int rank)
|
|
{
|
|
/* install handler to catch termination of child processes */
|
|
if (signal(SIGCHLD, xmlrpc_sigchld)==SIG_ERR) {
|
|
LM_ERR("failed to install signal handler for SIGCHLD\n");
|
|
goto error;
|
|
}
|
|
|
|
/* Server Abyss init */
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
#ifdef XMLRPC_OLD_VERSION
|
|
xmlrpc_server_abyss_init_registry();
|
|
registryP= xmlrpc_server_abyss_registry();
|
|
#else
|
|
registryP = xmlrpc_registry_new(&env);
|
|
#endif
|
|
|
|
DateInit();
|
|
MIMETypeInit();
|
|
|
|
if (!ServerCreate(&srv, "XmlRpcServer", port, "", log_file)) {
|
|
LM_ERR("failed to create XMLRPC server\n");
|
|
goto error;
|
|
}
|
|
|
|
#ifdef XMLRPC_OLD_VERSION
|
|
if (!ServerAddHandler(&srv, xmlrpc_server_abyss_rpc2_handler)) {
|
|
LM_ERR("failed to add handler to server\n");
|
|
goto error;
|
|
}
|
|
|
|
ServerDefaultHandler(&srv, xmlrpc_server_abyss_default_handler);
|
|
|
|
#else
|
|
|
|
xmlrpc_server_abyss_set_handlers2(&srv, "/RPC2", registryP);
|
|
|
|
#endif
|
|
|
|
ServerInit(&srv);
|
|
|
|
if( init_mi_child(PROC_NOCHLDINIT, 1) != 0 ) {
|
|
LM_CRIT("failed to init the mi process\n");
|
|
goto error;
|
|
}
|
|
|
|
if ( xr_writer_init(read_buf_size) != 0 ) {
|
|
LM_ERR("failed to init the reply writer\n");
|
|
goto error;
|
|
}
|
|
#ifdef XMLRPC_OLD_VERSION
|
|
xmlrpc_env_init(&env);
|
|
#endif
|
|
|
|
if ( rpl_opt == 1 ) {
|
|
xr_response = xmlrpc_build_value(&env, "()");
|
|
if ( env.fault_occurred ){
|
|
LM_ERR("failed to create an empty array: %s\n", env.fault_string);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if ( set_default_method(&env,registryP) != 0 ) {
|
|
LM_ERR("failed to set up the default method!\n");
|
|
goto cleanup;
|
|
}
|
|
|
|
/* Run server abyss */
|
|
LM_INFO("starting xmlrpc server\n");
|
|
|
|
ServerRun(&srv);
|
|
|
|
LM_CRIT("Server terminated!!!\n");
|
|
|
|
cleanup:
|
|
xmlrpc_env_clean(&env);
|
|
if ( xr_response ) xmlrpc_DECREF(xr_response);
|
|
error:
|
|
exit(-1);
|
|
}
|
|
|
|
|
|
static void destroy(void)
|
|
{
|
|
destroy_async_lock();
|
|
}
|