From 6a32e98c492f66fb5914e5f585c62f88bad09714 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Tue, 15 May 2012 19:37:41 -0400 Subject: [PATCH] Add mod_megaco skeleton with basic profile support and a lot of todos for Kapil --- libs/ldns/install-sh | 29 +++-- src/include/switch_apr.h | 3 +- src/mod/endpoints/mod_megaco/Makefile | 3 + src/mod/endpoints/mod_megaco/megaco.c | 132 ++++++++++++++++++++ src/mod/endpoints/mod_megaco/mod_megaco.c | 141 ++++++++++++++++++++++ src/mod/endpoints/mod_megaco/mod_megaco.h | 56 +++++++++ 6 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 src/mod/endpoints/mod_megaco/Makefile create mode 100644 src/mod/endpoints/mod_megaco/megaco.c create mode 100644 src/mod/endpoints/mod_megaco/mod_megaco.c create mode 100644 src/mod/endpoints/mod_megaco/mod_megaco.h diff --git a/libs/ldns/install-sh b/libs/ldns/install-sh index 6781b987bd..a9244eb078 100755 --- a/libs/ldns/install-sh +++ b/libs/ldns/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-01-19.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -156,6 +156,10 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -200,7 +208,11 @@ if test $# -eq 0; then fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for `test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -385,7 +392,7 @@ do case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ do for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 0c8673570f..e125eb9390 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -773,7 +773,8 @@ typedef gid_t switch_gid_t; typedef ino_t switch_ino_t; typedef dev_t switch_dev_t; #endif - typedef off64_t switch_off_t; + +typedef off_t switch_off_t; /** * Structure for referencing file information diff --git a/src/mod/endpoints/mod_megaco/Makefile b/src/mod/endpoints/mod_megaco/Makefile new file mode 100644 index 0000000000..e65d0f78eb --- /dev/null +++ b/src/mod/endpoints/mod_megaco/Makefile @@ -0,0 +1,3 @@ +BASE=../../../.. +LOCAL_OBJS=megaco.o +include $(BASE)/build/modmake.rules diff --git a/src/mod/endpoints/mod_megaco/megaco.c b/src/mod/endpoints/mod_megaco/megaco.c new file mode 100644 index 0000000000..72d03424f1 --- /dev/null +++ b/src/mod/endpoints/mod_megaco/megaco.c @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2012, Sangoma Technologies +* Mathieu Rene +* All rights reserved. +* +* +*/ + +#include "mod_megaco.h" + +megaco_profile_t *megaco_profile_locate(const char *name) +{ + megaco_profile_t *profile = switch_core_hash_find_rdlock(megaco_globals.profile_hash, name, megaco_globals.profile_rwlock); + + if (profile) { + if (switch_thread_rwlock_tryrdlock(profile->rwlock) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile %s is locked\n", name); + profile = NULL; + } + } + + return profile; +} + +void megaco_profile_release(megaco_profile_t *profile) +{ + switch_thread_rwlock_unlock(profile->rwlock); +} + +static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) +{ + switch_xml_t cfg, xml, x_profiles, x_profile, x_settings; + switch_status_t status = SWITCH_STATUS_FALSE; + switch_event_t *event = NULL; + int count; + const char *file = "megaco.conf"; + + if (!(xml = switch_xml_open_cfg(file, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open %s\n", file); + goto done; + } + + if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { + goto done; + } + + for (x_profile = switch_xml_child(x_profiles, "profile"); x_profile; x_profile = x_profile->next) { + const char *name = switch_xml_attr_soft(x_profile, "name"); + if (strcmp(name, profile->name)) { + continue; + } + + if (!(x_settings = switch_xml_child(x_profile, "settings"))) { + goto done; + } + count = switch_event_import_xml(switch_xml_child(x_settings, "param"), "name", "value", &event); + // status = switch_xml_config_parse_event(event, count, reload, instructions); + + /* TODO: Initialize stack configuration */ + } + +done: + if (xml) { + switch_xml_free(xml); + } + + if (event) { + switch_event_destroy(&event); + } + return status; +} + +switch_status_t megaco_profile_start(const char *profilename) +{ + switch_memory_pool_t *pool; + megaco_profile_t *profile; + + switch_assert(profilename); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting profile: %s\n", profilename); + + switch_core_new_memory_pool(&pool); + profile = switch_core_alloc(pool, sizeof(*profile)); + profile->pool = pool; + profile->name = switch_core_strdup(pool, profilename); + + switch_thread_rwlock_create(&profile->rwlock, pool); + + /* TODO: Kapil: Insert stack per-interface startup code here */ + + switch_core_hash_insert_wrlock(megaco_globals.profile_hash, profile->name, profile, megaco_globals.profile_rwlock); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started profile: %s\n", profile->name); + + return SWITCH_STATUS_SUCCESS; +fail: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_FALSE; +} + + +switch_status_t megaco_profile_destroy(megaco_profile_t **profile) +{ + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopping profile: %s\n", (*profile)->name); + switch_thread_rwlock_wrlock((*profile)->rwlock); + + + /* TODO: Kapil: Insert stack per-interface shutdown code here */ + + + switch_thread_rwlock_unlock((*profile)->rwlock); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopped profile: %s\n", (*profile)->name); + switch_core_hash_delete_wrlock(megaco_globals.profile_hash, (*profile)->name, megaco_globals.profile_rwlock); + + switch_core_destroy_memory_pool(&(*profile)->pool); + + return SWITCH_STATUS_SUCCESS; +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.c b/src/mod/endpoints/mod_megaco/mod_megaco.c new file mode 100644 index 0000000000..bf23077e00 --- /dev/null +++ b/src/mod/endpoints/mod_megaco/mod_megaco.c @@ -0,0 +1,141 @@ +/* +* Copyright (c) 2012, Sangoma Technologies +* Mathieu Rene +* All rights reserved. +* +* +*/ + +#include "mod_megaco.h" + +struct megaco_globals megaco_globals; + +SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown); +SWITCH_MODULE_DEFINITION(mod_megaco, mod_megaco_load, mod_megaco_shutdown, NULL); + + +#define MEGACO_FUNCTION_SYNTAX "profile [name] [start | stop]" +SWITCH_STANDARD_API(megaco_function) +{ + int argc; + char *argv[10]; + char *dup = NULL; + + if (zstr(cmd)) { + goto usage; + } + + dup = strdup(cmd); + argc = switch_split(dup, ' ', argv); + + if (argc < 1 || zstr(argv[0])) { + goto usage; + } + + if (!strcmp(argv[0], "profile")) { + if (zstr(argv[1]) || zstr(argv[2])) { + goto usage; + } + if (!strcmp(argv[2], "start")) { + megaco_profile_t *profile = megaco_profile_locate(argv[1]); + if (profile) { + megaco_profile_release(profile); + stream->write_function(stream, "-ERR Profile %s is already started\n", argv[2]); + } else { + megaco_profile_start(argv[1]); + stream->write_function(stream, "+OK\n"); + } + } else if (!strcmp(argv[2], "stop")) { + megaco_profile_t *profile = megaco_profile_locate(argv[1]); + if (profile) { + megaco_profile_release(profile); + megaco_profile_destroy(&profile); + stream->write_function(stream, "+OK\n"); + } else { + stream->write_function(stream, "-ERR No such profile\n"); + } + } + } + + goto done; + + usage: + stream->write_function(stream, "-ERR Usage: "MEGACO_FUNCTION_SYNTAX"\n"); + + done: + switch_safe_free(dup); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t console_complete_hashtable(switch_hash_t *hash, const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + switch_hash_index_t *hi; + void *val; + const void *vvar; + switch_console_callback_match_t *my_matches = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + + for (hi = switch_hash_first(NULL, hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + switch_console_push_match(&my_matches, (const char *) vvar); + } + + if (my_matches) { + *matches = my_matches; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + +static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + switch_status_t status; + switch_thread_rwlock_rdlock(megaco_globals.profile_rwlock); + status = console_complete_hashtable(megaco_globals.profile_hash, line, cursor, matches); + switch_thread_rwlock_unlock(megaco_globals.profile_rwlock); + return status; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load) +{ + switch_api_interface_t *api_interface; + + memset(&megaco_globals, 0, sizeof(megaco_globals)); + megaco_globals.pool = pool; + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + switch_core_hash_init(&megaco_globals.profile_hash, pool); + switch_thread_rwlock_create(&megaco_globals.profile_rwlock, pool); + + SWITCH_ADD_API(api_interface, "megaco", "megaco", megaco_function, MEGACO_FUNCTION_SYNTAX); + + switch_console_set_complete("add megaco profile ::megaco::list_profiles start"); + switch_console_set_complete("add megaco profile ::megaco::list_profiles stop"); + switch_console_add_complete_func("::megaco::list_profiles", list_profiles); + + /* TODO: Kapil: Insert stack global startup code here */ + + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown) +{ + /* TODO: Kapil: Insert stack global shutdown code here */ + return SWITCH_STATUS_SUCCESS; +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.h b/src/mod/endpoints/mod_megaco/mod_megaco.h new file mode 100644 index 0000000000..b12982de8c --- /dev/null +++ b/src/mod/endpoints/mod_megaco/mod_megaco.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2012, Sangoma Technologies +* Mathieu Rene +* All rights reserved. +* +* +*/ + + +#ifndef MOD_MEGACO_H +#define MOD_MEGACO_H + +#include + +struct megaco_globals { + switch_memory_pool_t *pool; + switch_hash_t *profile_hash; + switch_thread_rwlock_t *profile_rwlock; + /* TODO: Kapil: add global variables here */ +}; +extern struct megaco_globals megaco_globals; /* < defined in mod_megaco.c */ + +typedef enum { + PF_RUNNING = (1 << 0) +} megaco_profile_flags_t; + +typedef struct megaco_profile_s { + char *name; + switch_memory_pool_t *pool; + switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */ + megaco_profile_flags_t flags; + + /* TODO: Kapil: Insert interface-specific stack elements here */ +} megaco_profile_t; + + +megaco_profile_t *megaco_profile_locate(const char *name); +void megaco_profile_release(megaco_profile_t *profile); + +switch_status_t megaco_profile_start(const char *profilename); +switch_status_t megaco_profile_destroy(megaco_profile_t **profile); + + +#endif /* MOD_MEGACO_H */ + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */