plugin API works
This commit is contained in:
+2
-1
@@ -19,6 +19,7 @@
|
||||
#
|
||||
|
||||
|
||||
SUBDIRS = src doc scripts contrib
|
||||
SUBDIRS = libltdl src doc scripts contrib
|
||||
INCLUDES = $(LTDLINCL)
|
||||
|
||||
EXTRA_DIST = TODO RELNOTES siproxd.spec autogen.sh
|
||||
|
||||
@@ -75,9 +75,6 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `ltdl' library (-lltdl). */
|
||||
#undef HAVE_LIBLTDL
|
||||
|
||||
/* Define to 1 if you have the `osip2' library (-losip2). */
|
||||
#undef HAVE_LIBOSIP2
|
||||
|
||||
|
||||
+50
-85
@@ -20,7 +20,7 @@ dnl 1-Nov-2003 tries check for NETFILTER (IPTABLES)
|
||||
dnl 18-Nov-2003 tries include sysconfdir to search for config
|
||||
dnl 19-Nov-2003 tries changes to support Solaris & BSD/OS
|
||||
dnl 22-Nov-2003 tries test for gethostbyname_r() & # of args
|
||||
dnl 22-Jan-2004 tries add --enable-static option
|
||||
dnl 22-Jan-2004 tries add --enable-static-exe option
|
||||
dnl 06-Mar-2004 tries del daemon(), add setsid()
|
||||
dnl 09-Apr-2004 tries add --with-custom-fwmodule
|
||||
dnl 09-May-2004 tries fli4l-uclibc links statically agains pthreads
|
||||
@@ -38,6 +38,8 @@ dnl 18-Apr-2005 tries added libresolv
|
||||
dnl 9-Oct-2005 tries libresolv is now included in static build
|
||||
dnl 10-Jun-2007 tries test more .h files (DNS resolver related)
|
||||
dnl 18-Dec-2007 tries requires libosip2-3.x.x
|
||||
dnl 02-Feb-2008 tries removed variety of fli4l and static extra
|
||||
dnl build options
|
||||
dnl
|
||||
dnl
|
||||
|
||||
@@ -73,21 +75,39 @@ dnl
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_LIBTOOL
|
||||
AC_CHECK_PROG(docbook2pdf,docbook2pdf,yes,)
|
||||
AM_CONDITIONAL(have_docbook2pdf,test "$docbook2pdf" = "yes")
|
||||
AC_CHECK_PROG(docbook2html,docbook2html,yes,)
|
||||
AM_CONDITIONAL(have_docbook2html,test "$docbook2html" = "yes")
|
||||
|
||||
dnl
|
||||
dnl prepare libtool
|
||||
dnl
|
||||
dnl We require the ltdl (libtool portable dynamic loader)
|
||||
dnl for our plugins. As this would require the automake/libtool
|
||||
dnl packages to be present we include that library with
|
||||
dnl the siproxd package as so called "convenience library"
|
||||
dnl
|
||||
AC_LIBLTDL_CONVENIENCE
|
||||
dnl
|
||||
dnl Check for dlopen support
|
||||
AC_LIBTOOL_DLOPEN
|
||||
dnl Configure libtool
|
||||
AC_PROG_LIBTOOL
|
||||
dnl
|
||||
dnl Substitute LTDLINCL and LIBLTDL in the Makefiles
|
||||
AC_SUBST(LTDLINCL)
|
||||
AC_SUBST(LIBLTDL)
|
||||
AC_CONFIG_SUBDIRS(libltdl)
|
||||
|
||||
dnl allow plugins to use functions in main program
|
||||
LDFLAGS="-export-dynamic"
|
||||
|
||||
dnl **********************************************
|
||||
dnl * Location of libraries / headerfiles
|
||||
dnl **********************************************
|
||||
|
||||
dnl
|
||||
dnl add
|
||||
dnl --with-extra-includes
|
||||
dnl --with-extra-libs
|
||||
dnl
|
||||
@@ -114,16 +134,24 @@ for each in $extra_libs; do
|
||||
done
|
||||
|
||||
|
||||
dnl **********************************************
|
||||
dnl * Selection of static build variants
|
||||
dnl **********************************************
|
||||
|
||||
dnl
|
||||
dnl add
|
||||
dnl --enable-static-exe
|
||||
AC_MSG_CHECKING(build statically linked executable)
|
||||
AC_ARG_ENABLE(static-exe,
|
||||
[ --enable-static-exe build statically linked executable],
|
||||
LDFLAGS="$LDFLAGS -static";
|
||||
dnl --enable-static-libosip2
|
||||
dnl
|
||||
build_static_libosip="no"
|
||||
AC_MSG_CHECKING(link statically against libosip2)
|
||||
AC_ARG_ENABLE(static-libosip2,
|
||||
[ --enable-static-libosip2 link statically against libosip2],
|
||||
build_static_libosip="yes";
|
||||
AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
|
||||
|
||||
|
||||
dnl **********************************************
|
||||
dnl * Debugging helps
|
||||
dnl **********************************************
|
||||
dnl
|
||||
dnl add
|
||||
dnl --enable-dmalloc
|
||||
@@ -193,80 +221,15 @@ case "$target" in
|
||||
esac
|
||||
|
||||
|
||||
dnl
|
||||
dnl Feature:
|
||||
dnl Fli4l libc5 support (only available on Linux, yet)
|
||||
dnl Fli4l uClibc support (only available on Linux, yet)
|
||||
dnl
|
||||
build_fli4l_libc5="no"
|
||||
build_fli4l_21_uclibc="no"
|
||||
build_fli4l_22_uclibc="no"
|
||||
case "$target" in
|
||||
*-*-linux*)
|
||||
AC_MSG_CHECKING(whether build for FLI4L 2.0.x libc5 )
|
||||
AC_ARG_ENABLE(fli4l-libc5,
|
||||
[ --enable-fli4l-libc5 build FLI4L 2.0.x (libc5)],
|
||||
build_fli4l_libc5=$enableval,)
|
||||
AC_MSG_RESULT($build_fli4l_libc5)
|
||||
|
||||
AC_MSG_CHECKING(whether build for FLI4L 2.1.x uClibc)
|
||||
AC_ARG_ENABLE(fli4l-21-uclibc,
|
||||
[ --enable-fli4l-21-uclibc build FLI4L 2.1.x (uClibc, no pthreads support)],
|
||||
build_fli4l_21_uclibc=$enableval,)
|
||||
AC_MSG_RESULT($build_fli4l_21_uclibc)
|
||||
|
||||
AC_MSG_CHECKING(whether build for FLI4L 2.2.x uClibc)
|
||||
AC_ARG_ENABLE(fli4l-22-uclibc,
|
||||
[ --enable-fli4l-22-uclibc build FLI4L 2.2.x (uClibc, with pthreads support)],
|
||||
build_fli4l_22_uclibc=$enableval,)
|
||||
AC_MSG_RESULT($build_fli4l_22_uclibc)
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_RESULT(building FLI4L not available on this platform)
|
||||
;;
|
||||
esac
|
||||
|
||||
build_static_libosip="no"
|
||||
build_static_pthread="no"
|
||||
if test "x$build_fli4l_libc5" = "xyes"; then
|
||||
dnl FLI4l 2.0.x libc5: make libosip and libpthread static
|
||||
build_static_libosip="yes"
|
||||
build_static_pthread="yes"
|
||||
elif test "x$build_fli4l_21_uclibc" = "xyes"; then
|
||||
dnl FLI4l 2.1.x uClibc: build all static
|
||||
LDFLAGS="$LDFLAGS -static";
|
||||
elif test "x$build_fli4l_22_uclibc" = "xyes"; then
|
||||
dnl FLI4l 2.2.x uClibc: make libosip
|
||||
build_static_libosip="yes"
|
||||
fi
|
||||
|
||||
|
||||
dnl
|
||||
dnl Check for pthreads
|
||||
dnl
|
||||
ACX_PTHREAD(,
|
||||
echo "*** ERROR: pthreads is required!"; exit 1;)
|
||||
if test "x$build_static_pthread" = "xno"; then
|
||||
dnl link dynamically (default)
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
CC="$PTHREAD_CC"
|
||||
else
|
||||
dnl link statically to this lib
|
||||
dnl (this probably only will work on linux yet...)
|
||||
AC_MSG_CHECKING("where I can find static threads library")
|
||||
libpthreads_static=`find $extra_libs /lib /usr/lib /usr/local/lib \
|
||||
-name 'lib*thread*.a' 2>/dev/null| \
|
||||
egrep 'lib[p]?thread[s]?.a' |head -1`
|
||||
if test "x$libpthreads_static" != "x"; then
|
||||
LIBS="$libpthreads_static $LIBS"
|
||||
AC_MSG_RESULT($libpthreads_static)
|
||||
else
|
||||
echo "*** ERROR: a static threads library is required!";exit 1;
|
||||
fi
|
||||
CC="$PTHREAD_CC"
|
||||
fi
|
||||
|
||||
|
||||
dnl
|
||||
@@ -299,6 +262,9 @@ if test x$libosip_prefix_dir != x; then
|
||||
CPPFLAGS="$CPPFLAGS -I$libosip_prefix_dir/include"
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Static or dynamic linking against libosip
|
||||
dnl
|
||||
if test "x$build_static_libosip" = "xno"; then
|
||||
dnl link dynamically (default)
|
||||
AC_CHECK_LIB(osip2, osip_init,,
|
||||
@@ -330,7 +296,9 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl correct version of libosip2?
|
||||
dnl
|
||||
ACX_CHECK_LIBOSIP_VERSION()
|
||||
|
||||
|
||||
@@ -383,9 +351,8 @@ dnl
|
||||
dnl Checks for libraries
|
||||
dnl Note: the __res_query symbol is to catch the lib when building "static"
|
||||
dnl
|
||||
AC_CHECK_LIB(resolv,res_query,)
|
||||
AC_CHECK_LIB(resolv,__res_query,)
|
||||
AC_CHECK_LIB(ltdl,lt_dlopen,)
|
||||
AC_CHECK_LIB(resolv,res_query,) dnl found only in static lib
|
||||
AC_CHECK_LIB(resolv,__res_query,) dnl found in static and dynamic lib
|
||||
|
||||
|
||||
dnl
|
||||
@@ -399,11 +366,9 @@ AC_CHECK_FUNCS(strerror)
|
||||
AC_CHECK_FUNCS(gethostbyname)
|
||||
|
||||
dnl !! with FLI4L 2.0.x strange behavior with gethostbyname_r()
|
||||
dnl !! has been seen, dont use it.
|
||||
if test "x$build_fli4l_libc5" = "xno"; then
|
||||
dnl AC_CHECK_FUNCS(gethostbyname_r)
|
||||
ACX_WHICH_GETHOSTBYNAME_R()
|
||||
fi
|
||||
dnl !! has been seen, dont use it. the ACX_WHICH_GETHOSTBYNAME_R
|
||||
dnl !! shall then be commented out.
|
||||
ACX_WHICH_GETHOSTBYNAME_R()
|
||||
|
||||
AC_CHECK_FUNCS(getopt_long setsid syslog)
|
||||
AC_CHECK_FUNCS(getuid setuid getgid setgid getpwnam chroot)
|
||||
|
||||
@@ -26,6 +26,8 @@ AM_CFLAGS = -Wall -D_GNU_SOURCE \
|
||||
# Siproxd itself
|
||||
#
|
||||
sbin_PROGRAMS = siproxd
|
||||
siproxd_LDFLAGS=-export-dynamic
|
||||
siproxd_LDADD = $(LIBLTDL)
|
||||
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c \
|
||||
sip_utils.c sip_layer.c log.c readconf.c rtpproxy.c \
|
||||
rtpproxy_relay.c accessctl.c route_processing.c \
|
||||
|
||||
+26
-8
@@ -28,14 +28,28 @@
|
||||
#include <osipparser2/osip_parser.h>
|
||||
|
||||
#include "siproxd.h"
|
||||
#include "log.h"
|
||||
#include "plugins.h"
|
||||
#include "log.h"
|
||||
|
||||
static char const ident[]="$Id$";
|
||||
|
||||
/* configuration storage */
|
||||
/* Plug-in identification */
|
||||
static char name[]="plugin_demo";
|
||||
static char desc[]="This is just a demo plugin without any purpose";
|
||||
|
||||
/* global configuration storage - required for config file location */
|
||||
extern struct siproxd_config configuration;
|
||||
|
||||
/* plugin configuration storage */
|
||||
static struct plugin_config {
|
||||
char *string;
|
||||
} plugin_cfg;
|
||||
|
||||
/* Instructions for config parser */
|
||||
static cfgopts_t plugin_cfg_opts[] = {
|
||||
{ "plugin_demo_string", TYP_STRING, &plugin_cfg.string },
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -49,13 +63,21 @@ int plugin_init(plugin_def_t *plugin_def) {
|
||||
plugin_def->api_version=SIPROXD_API_VERSION;
|
||||
|
||||
/* Name and descriptive text of the plugin */
|
||||
plugin_def->name=strdup("plugin_demo");
|
||||
plugin_def->desc=strdup("This is just a demo plugin without any purpose");
|
||||
plugin_def->name=name;
|
||||
plugin_def->desc=desc;
|
||||
|
||||
/* Execution mask - during what stages of SIP processing shall
|
||||
* the plugin be called. */
|
||||
plugin_def->exe_mask=PLUGIN_DETERMINE_TARGET|PLUGIN_PRE_PROXY;
|
||||
|
||||
/* read the config file */
|
||||
if (read_config(configuration.configfile,
|
||||
configuration.config_search,
|
||||
plugin_cfg_opts, name) == STS_FAILURE) {
|
||||
ERROR("Plugin '%s': could not load config file", name);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
INFO("plugin_demo is initialized");
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
@@ -77,10 +99,6 @@ int plugin_process(int stage, sip_ticket_t *ticket){
|
||||
* connections, whatever the plugin messes around with)
|
||||
*/
|
||||
int plugin_end(plugin_def_t *plugin_def){
|
||||
/* free my allocated rescources */
|
||||
if (plugin_def->name) {free(plugin_def->name); plugin_def->name=NULL;}
|
||||
if (plugin_def->desc) {free(plugin_def->desc); plugin_def->desc=NULL;}
|
||||
|
||||
INFO("plugin_demo ends here");
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
+40
-18
@@ -29,29 +29,55 @@
|
||||
#include <osipparser2/osip_parser.h>
|
||||
|
||||
#include "siproxd.h"
|
||||
#include "log.h"
|
||||
#include "plugins.h"
|
||||
#include "log.h"
|
||||
|
||||
static char const ident[]="$Id$";
|
||||
|
||||
/* configuration storage */
|
||||
/* Plug-in identification */
|
||||
static char name[]="plugin_shortdial";
|
||||
static char desc[]="Handles Dial shortcuts as defined in config file";
|
||||
|
||||
/* global configuration storage - required for config file location */
|
||||
extern struct siproxd_config configuration;
|
||||
|
||||
|
||||
/* plugin configuration storage */
|
||||
static struct plugin_config {
|
||||
char *shortdial_akey;
|
||||
stringa_t shortdial_entry;
|
||||
} plugin_cfg;
|
||||
/* Instructions for config parser */
|
||||
static cfgopts_t plugin_cfg_opts[] = {
|
||||
{ "plugin_shortdial_akey", TYP_STRING, &plugin_cfg.shortdial_akey },
|
||||
{ "plugin_shortdial_entry", TYP_STRINGA,&plugin_cfg.shortdial_entry },
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
static int plugin_shortdial_redirect(sip_ticket_t *ticket, int shortcut_no);
|
||||
static int plugin_shortdial(sip_ticket_t *ticket);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Plugin API functions code
|
||||
*/
|
||||
/* Initialization */
|
||||
int plugin_init(plugin_def_t *plugin_def) {
|
||||
plugin_def->api_version=SIPROXD_API_VERSION;
|
||||
plugin_def->name=strdup("plugin_shortdial");
|
||||
plugin_def->desc=strdup("Handles Dial shortcuts as defined in config file");
|
||||
plugin_def->name=name;
|
||||
plugin_def->desc=desc;
|
||||
plugin_def->exe_mask=PLUGIN_DETERMINE_TARGET;
|
||||
|
||||
/* read the config file */
|
||||
if (read_config(configuration.configfile,
|
||||
configuration.config_search,
|
||||
plugin_cfg_opts, name) == STS_FAILURE) {
|
||||
ERROR("Plugin '%s': could not load config file", name);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -64,10 +90,6 @@ int plugin_process(int stage, sip_ticket_t *ticket){
|
||||
|
||||
/* De-Initialization */
|
||||
int plugin_end(plugin_def_t *plugin_def){
|
||||
/* free my allocated rescources */
|
||||
if (plugin_def->name) {free(plugin_def->name); plugin_def->name=NULL;}
|
||||
if (plugin_def->desc) {free(plugin_def->desc); plugin_def->desc=NULL;}
|
||||
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -85,8 +107,8 @@ static int plugin_shortdial(sip_ticket_t *ticket) {
|
||||
int shortcut_no=0;
|
||||
|
||||
/* plugin loaded and not configured, return with success */
|
||||
if (configuration.pi_shortdial_akey==NULL) return STS_SUCCESS;
|
||||
if (configuration.pi_shortdial_entry.used==0) return STS_SUCCESS;
|
||||
if (plugin_cfg.shortdial_akey==NULL) return STS_SUCCESS;
|
||||
if (plugin_cfg.shortdial_entry.used==0) return STS_SUCCESS;
|
||||
|
||||
DEBUGC(DBCLASS_PLUGIN,"plugin entered");
|
||||
req_url=osip_message_get_uri(ticket->sipmsg);
|
||||
@@ -103,23 +125,23 @@ static int plugin_shortdial(sip_ticket_t *ticket) {
|
||||
/* REQ URI with username must exist, length as defined in config,
|
||||
* shortdial must be enabled and short dial key must match */
|
||||
if (!req_url || !req_url->username ||
|
||||
!configuration.pi_shortdial_akey ||
|
||||
(strlen(req_url->username) != strlen(configuration.pi_shortdial_akey)) ||
|
||||
(req_url->username[0] != configuration.pi_shortdial_akey[0]))
|
||||
!plugin_cfg.shortdial_akey ||
|
||||
(strlen(req_url->username) != strlen(plugin_cfg.shortdial_akey)) ||
|
||||
(req_url->username[0] != plugin_cfg.shortdial_akey[0]))
|
||||
return STS_SUCCESS; /* ignore */
|
||||
|
||||
shortcut_no = atoi(&(req_url->username[1]));
|
||||
if ((shortcut_no <= 0) || (shortcut_no >= LONG_MAX)) return STS_SUCCESS; /* not a number */
|
||||
|
||||
/* requested number is not defined (out of range) */
|
||||
if (shortcut_no > configuration.pi_shortdial_entry.used) {
|
||||
if (shortcut_no > plugin_cfg.shortdial_entry.used) {
|
||||
DEBUGC(DBCLASS_PLUGIN, "shortdial: shortcut %i > available shortcuts (%i)",
|
||||
shortcut_no, configuration.pi_shortdial_entry.used);
|
||||
shortcut_no, plugin_cfg.shortdial_entry.used);
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
/* requested number is not defined (empty) */
|
||||
if (!configuration.pi_shortdial_entry.string[shortcut_no-1]) {
|
||||
if (!plugin_cfg.shortdial_entry.string[shortcut_no-1]) {
|
||||
DEBUGC(DBCLASS_PLUGIN, "shortdial: shortcut %i empty", shortcut_no);
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
@@ -153,7 +175,7 @@ static int plugin_shortdial_redirect(sip_ticket_t *ticket, int shortcut_no) {
|
||||
size_t len;
|
||||
osip_contact_t *contact = NULL;
|
||||
|
||||
new_to_user=configuration.pi_shortdial_entry.string[shortcut_no-1];
|
||||
new_to_user=plugin_cfg.shortdial_entry.string[shortcut_no-1];
|
||||
if (!new_to_user) return STS_SUCCESS;
|
||||
|
||||
DEBUGC(DBCLASS_PLUGIN,"redirect: redirecting [%s]->[%s]",
|
||||
|
||||
+14
-7
@@ -104,6 +104,20 @@ int load_plugins (void) {
|
||||
/* call the init function */
|
||||
sts=(*plugin_init)(cur);
|
||||
|
||||
/* Tell the user something about the plugin we have just loaded */
|
||||
INFO("Plugin '%s' [%s] loaded with %s, exemask=0x%X",
|
||||
cur->name, cur->desc, (sts==STS_SUCCESS)?"success":"failure",
|
||||
cur->exe_mask);
|
||||
|
||||
/* check return status from plugin - failure leads to unload */
|
||||
if (sts != STS_SUCCESS) {
|
||||
/* complain and unload the plugin */
|
||||
ERROR("Plugin '%s' did fail to load.", cur->name);
|
||||
sts=(*plugin_end)(cur);
|
||||
free(cur);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check API version that the plugin was biuilt against */
|
||||
if (cur->api_version != SIPROXD_API_VERSION) {
|
||||
/* complain and unload the plugin */
|
||||
@@ -120,11 +134,6 @@ int load_plugins (void) {
|
||||
cur->plugin_end = plugin_end;
|
||||
cur->dlhandle = handle;
|
||||
|
||||
/* Tell the user something about the plugin we have just loaded */
|
||||
INFO("Plugin '%s' [%s] loaded with %s, exemask=0x%X",
|
||||
cur->name, cur->desc, (sts==STS_SUCCESS)?"success":"failure",
|
||||
cur->exe_mask);
|
||||
|
||||
/* store forward pointer */
|
||||
if (siproxd_plugins == NULL) {
|
||||
/* first in chain */
|
||||
@@ -220,8 +229,6 @@ int unload_plugins(void) {
|
||||
ERROR("lt_dlclose() failed, ptr=%p", cur);
|
||||
}
|
||||
|
||||
/* NOTE: cur->name and cur->desc must be cleaned up by the plugin! */
|
||||
|
||||
/* deallocate plugins list item */
|
||||
if (last) last->next=NULL;
|
||||
free(cur);
|
||||
|
||||
+59
-7
@@ -38,7 +38,7 @@ static char const ident[]="$Id$";
|
||||
extern struct siproxd_config configuration;
|
||||
|
||||
/* prototypes used locally only */
|
||||
static int parse_config (FILE *configfile, cfgopts_t cfgopts[]);
|
||||
static int parse_config (FILE *configfile, cfgopts_t cfgopts[], char *filter);
|
||||
|
||||
|
||||
/* try to open (whichever is found first):
|
||||
@@ -48,11 +48,14 @@ static int parse_config (FILE *configfile, cfgopts_t cfgopts[]);
|
||||
* /usr/etc/<name>.conf
|
||||
* /usr/local/etc/<name>.conf
|
||||
*
|
||||
* cfgopts: control array for the parser. defined keywors and types
|
||||
* filter: passed to parse_config (read there for details)
|
||||
*
|
||||
* RETURNS
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
int read_config(char *name, int search, cfgopts_t cfgopts[]) {
|
||||
int read_config(char *name, int search, cfgopts_t cfgopts[], char *filter) {
|
||||
int sts;
|
||||
FILE *configfile=NULL;
|
||||
int i;
|
||||
@@ -97,7 +100,7 @@ int read_config(char *name, int search, cfgopts_t cfgopts[]) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
sts = parse_config(configfile, cfgopts);
|
||||
sts = parse_config(configfile, cfgopts, filter);
|
||||
fclose(configfile);
|
||||
|
||||
/*
|
||||
@@ -126,18 +129,31 @@ int read_config(char *name, int search, cfgopts_t cfgopts[]) {
|
||||
/*
|
||||
* parse configuration file
|
||||
*
|
||||
* configfile - file STREAM to open config file
|
||||
*
|
||||
* configoptions - control structure for config parser
|
||||
*
|
||||
* filter = NULL - no filtering done
|
||||
* filter = "plugin_xxx" - only consider keywords starting
|
||||
* with "plugin_xxx", skip the rest.
|
||||
* PLugins set this to load their scope
|
||||
* of config options
|
||||
* filter = "" - read main configuration, skipp everything
|
||||
* starting with "plugin_" (hardwired).
|
||||
*
|
||||
* RETURNS
|
||||
* STS_SUCCESS on success
|
||||
* STS_FAILURE on error
|
||||
*/
|
||||
static int parse_config (FILE *configfile, cfgopts_t configoptions[]) {
|
||||
static int parse_config (FILE *configfile, cfgopts_t configoptions[],
|
||||
char *filter) {
|
||||
char buff[1024];
|
||||
char *ptr;
|
||||
int i;
|
||||
int k;
|
||||
int i, k;
|
||||
int num;
|
||||
size_t len;
|
||||
char *tmpptr;
|
||||
char *eqsign;
|
||||
|
||||
while (fgets(buff,sizeof(buff),configfile) != NULL) {
|
||||
/* life insurance */
|
||||
@@ -161,7 +177,43 @@ static int parse_config (FILE *configfile, cfgopts_t configoptions[]) {
|
||||
}
|
||||
if (i == strlen(buff)) continue;
|
||||
|
||||
DEBUGC(DBCLASS_CONFIG,"pc:\"%s\"",buff);
|
||||
|
||||
/* search for token separator '=' */
|
||||
eqsign = strchr(buff, '=');
|
||||
if (eqsign == NULL) {
|
||||
ERROR("Syntax error in config file [%s]", buff);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* keyword filtering:
|
||||
* filter = NULL - no filtering done
|
||||
* filter = "plugin_xxx" - only consider keywords starting
|
||||
* with "plugin_xxx", skip the rest.
|
||||
* PLugins set this to load their scope
|
||||
* of config options
|
||||
* filter = "" - read main configuration, skipp everything
|
||||
* starting with "plugin_" (hardwired).
|
||||
*/
|
||||
if (filter) {
|
||||
/* filter == "": skip all plugin config entries */
|
||||
if (filter[0] == '\0') {
|
||||
ptr=strstr(buff,"plugin_");
|
||||
if (ptr && (ptr < eqsign)) {
|
||||
DEBUGC(DBCLASS_CONFIG,"skipped: \"%s\"",buff);
|
||||
continue;
|
||||
}
|
||||
/* filter == "something": only consider "somethingxxxxx" */
|
||||
} else {
|
||||
ptr=strstr(buff, filter);
|
||||
if ((ptr==NULL) || (ptr > eqsign)) {
|
||||
DEBUGC(DBCLASS_CONFIG,"skipped: \"%s\"",buff);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} /* filter == NULL */
|
||||
|
||||
DEBUGC(DBCLASS_CONFIG,"cfg line:\"%s\"",buff);
|
||||
|
||||
/* scan for known keyword */
|
||||
for (k=0; configoptions[k].keyword != NULL; k++) {
|
||||
|
||||
+7
-5
@@ -45,7 +45,7 @@ static char const ident[]="$Id$";
|
||||
/* configuration storage */
|
||||
struct siproxd_config configuration;
|
||||
/* instructions for config parser */
|
||||
cfgopts_t main_cfg_opts[] = {
|
||||
static cfgopts_t main_cfg_opts[] = {
|
||||
{ "debug_level", TYP_INT4, &configuration.debuglevel },
|
||||
{ "debug_port", TYP_INT4, &configuration.debugport },
|
||||
{ "sip_listen_port", TYP_INT4, &configuration.sip_listen_port },
|
||||
@@ -82,12 +82,10 @@ cfgopts_t main_cfg_opts[] = {
|
||||
{ "pid_file", TYP_STRING, &configuration.pid_file },
|
||||
{ "default_expires", TYP_INT4, &configuration.default_expires },
|
||||
{ "autosave_registrations",TYP_INT4, &configuration.autosave_registrations },
|
||||
{ "pi_shortdial_akey", TYP_STRING, &configuration.pi_shortdial_akey },
|
||||
{ "pi_shortdial_entry", TYP_STRINGA,&configuration.pi_shortdial_entry },
|
||||
{ "ua_string", TYP_STRING, &configuration.ua_string },
|
||||
{ "use_rport", TYP_INT4, &configuration.use_rport },
|
||||
{ "obscure_loops", TYP_INT4, &configuration.obscure_loops },
|
||||
{ "plugin_dir", TYP_STRING, &configuration.plugin_dir },
|
||||
{ "plugindir", TYP_STRING, &configuration.plugin_dir },
|
||||
{ "load_plugin", TYP_STRINGA,&configuration.load_plugin },
|
||||
{0, 0, 0}
|
||||
};
|
||||
@@ -232,9 +230,13 @@ int main (int argc, char *argv[])
|
||||
INFO(PACKAGE"-"VERSION"-"BUILDSTR" "UNAME" starting up");
|
||||
|
||||
/* read the config file */
|
||||
if (read_config(configfile, config_search, main_cfg_opts) == STS_FAILURE) {
|
||||
if (read_config(configfile, config_search, main_cfg_opts, "") == STS_FAILURE) {
|
||||
exit(1);
|
||||
}
|
||||
/* remember where config file is located, so the plugins
|
||||
* can load it as well - if required */
|
||||
configuration.configfile = strdup(configfile);
|
||||
configuration.config_search = config_search;
|
||||
|
||||
/* if a debug level > 0 has been given on the commandline use its
|
||||
value and not what is in the config file */
|
||||
|
||||
+4
-3
@@ -57,6 +57,9 @@ typedef struct {
|
||||
* global configuration option table
|
||||
*/
|
||||
struct siproxd_config {
|
||||
char *configfile;
|
||||
int config_search;
|
||||
/* everything below here will be filled according to the config file */
|
||||
unsigned int debuglevel;
|
||||
int debugport;
|
||||
char *inbound_if;
|
||||
@@ -92,8 +95,6 @@ struct siproxd_config {
|
||||
char *pid_file;
|
||||
int default_expires;
|
||||
int autosave_registrations;
|
||||
char *pi_shortdial_akey;
|
||||
stringa_t pi_shortdial_entry;
|
||||
char *ua_string;
|
||||
int use_rport;
|
||||
int obscure_loops;
|
||||
@@ -209,7 +210,7 @@ int sip_fixup_asterisk(char *buff, int *buflen); /*X*/
|
||||
int sip_obscure_callid(sip_ticket_t *ticket); /*X*/
|
||||
|
||||
/* readconf.c */
|
||||
int read_config(char *name, int search, cfgopts_t cfgopts[]); /*X*/
|
||||
int read_config(char *name, int search, cfgopts_t cfgopts[], char *filter); /*X*/
|
||||
int make_default_config(void); /*X*/
|
||||
|
||||
/* rtpproxy.c */
|
||||
|
||||
Reference in New Issue
Block a user