[asterisk-commits] mjordan: branch mjordan/voicemail_refactor_11_10_19 r348361 - in /team/mjorda...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 16 07:33:38 CST 2011


Author: mjordan
Date: Fri Dec 16 07:30:28 2011
New Revision: 348361

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=348361
Log:
I think I'm getting closer to how I want this to look

Modified:
    team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h
    team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c
    team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c

Modified: team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h (original)
+++ team/mjordan/voicemail_refactor_11_10_19/include/asterisk/message_storage.h Fri Dec 16 07:30:28 2011
@@ -9,70 +9,25 @@
 #define MESSAGE_STORAGE_H_
 
 
-struct vm_config {
-	double volgain;
-	unsigned int max_silence;
+struct ast_msg_config {
 	unsigned int max_deleted_messages;
 	unsigned int max_messages;
-	unsigned int min_say_duration;
-	unsigned int min_message_duration;
-	unsigned int max_message_duration;
-	unsigned int max_message_greeting_length;
-	unsigned int skip_ms;
-	unsigned int min_password_length;
-	unsigned int silence_threshold;
-	unsigned int poll_frequency;
-	unsigned int max_logins;
 	enum vm_passwordlocation password_location;
-	char attach_format[MAX_FORMAT_LENGTH];
 	char format[MAX_FORMAT_LENGTH];
-	char dial_out_context[AST_MAX_CONTEXT];
-	char callback_context[AST_MAX_CONTEXT];
-	char op_exit_context[AST_MAX_CONTEXT];
-	char default_users_context[AST_MAX_CONTEXT];
-	char cid_internal_contexts[MAX_NUM_CID_CONTEXTS][AST_MAX_CONTEXT];
-	char extern_notify_cmd[PATH_MAX];
-	char extern_pass_cmd[PATH_MAX];
-	char extern_pass_check_cmd[PATH_MAX];
-	char directory_intro_path[PATH_MAX];
-	struct vm_sound_config * sound_config;
-	struct vm_listen_control_config * listen_control_config;
-	struct vm_smdi_config * smdi_config;
-	struct vm_adsi_config * adsi_config;
-	struct ast_flags globalflags;
-	struct ast_flags passwordflags;
+	struct ast_flags global_flags;
+	struct ast_flags password_flags;
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(mail_command);
-		AST_STRING_FIELD(email_from_string);
-		AST_STRING_FIELD(email_server);
-		AST_STRING_FIELD(email_date_format);
-		AST_STRING_FIELD(email_subject);
-		AST_STRING_FIELD(email_body);
-		AST_STRING_FIELD(pager_from_string);
-		AST_STRING_FIELD(pager_date_format);
-		AST_STRING_FIELD(pager_subject);
-		AST_STRING_FIELD(pager_body);
 		AST_STRING_FIELD(zonetag);
 		AST_STRING_FIELD(locale);
-		AST_STRING_FIELD(charset);
 	);
 };
 
-
-struct ast_msg_user {
+struct ast_msg_mailbox {
 	char context[AST_MAX_CONTEXT];		/*!< Mailbox context */
 	char mailbox[AST_MAX_EXTENSION];	/*!< Mailbox id, unique within a context */
 	char language[MAX_LANGUAGE];		/*!< Config: Language setting */
-	char callback[AST_MAX_CONTEXT];				 /*!< Callback context */
-	char dialout[AST_MAX_CONTEXT];				 /*!< Dialout context */
-	char uniqueid[80];					/*!< Unique integer identifier TODO: make this an integer? */
-	char exit[AST_MAX_CONTEXT];					 /*!< Context to exit out to */
-	char attachfmt[MAX_FORMAT_LENGTH];	/*!< Attachment format */
-	int min_say_duration;				/*!< Minimum number of seconds for say */
-	int min_message_duration;			/*!< Minimum number of seconds per message for this mailbox */
 	int max_messages;					/*!< Maximum number of msgs per folder for this mailbox */
 	int max_deleted_messages;			/*!< Maximum number of deleted msgs saved for this mailbox */
-	int max_message_duration;			/*!< Maximum number of seconds per message for this mailbox */
 	int hash_key;
 	enum vm_passwordlocation password_location;           /*!< Storage location of the password */
 	double volgain;						/*!< Volume gain for voicemails sent via email */
@@ -80,15 +35,7 @@
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(fullname);
 		AST_STRING_FIELD(password);
-		AST_STRING_FIELD(email_address);
-		AST_STRING_FIELD(email_subject);
-		AST_STRING_FIELD(email_body);
-		AST_STRING_FIELD(pager_address);
-		AST_STRING_FIELD(pager_subject);
-		AST_STRING_FIELD(pager_body);
-		AST_STRING_FIELD(email_from_address);
 		AST_STRING_FIELD(locale);
-		AST_STRING_FIELD(mail_command);
 		AST_STRING_FIELD(zonetag);
 		AST_STRING_FIELD(timezone);
 	);
@@ -96,16 +43,28 @@
 
 
 struct ast_msg_storage_tech {
+
 	const char * const name;
 
 	int (* const load_config)(struct ast_config *cfg, int reload);
 
+	int (* const load_mailboxes)(struct ast_config *mcfg, int reload, int by_variable);
+
+	struct ast_msg_config *(* const get_config)(void);
+
+	struct ast_msg_mailbox *(* const get_mailbox)(const char * const context, const char * const mailbox);
+
 	/* store message */
-
 	/* delete message */
 
 	/* retrieve message */
 };
+
+struct ast_msg_config *ast_get_message_storage_config(void);
+
+struct ast_msg_mailbox *ast_get_message_mailbox(const char * const context, const char * const mailbox);
+
+void ast_unregister_message_storage_tech(const char * const name);
 
 void ast_register_message_storage_tech(struct ast_msg_storage_tech *ms_tech);
 

Modified: team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c (original)
+++ team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c Fri Dec 16 07:30:28 2011
@@ -7,7 +7,6 @@
 #define USERS_CONFIG "users.conf"
 
 struct imap_config {
-	/* TODO: make the next two fields bit fields? */
 	struct ast_msg_config *msg_config;
 	unsigned int expunge_on_hangup;
 	unsigned int imap_greetings;
@@ -29,72 +28,126 @@
 	);
 };
 
-struct imap_user {
-	struct ast_msg_user *msg_user;
+/*! \internal \brief The IMAP mailbox definition */
+struct imap_mailbox {
+	struct ast_msg_mailbox *msg_mailbox;			/*!< The inherited message mailbox information */
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(user);               /*!< IMAP server login */
-		AST_STRING_FIELD(password);           /*!< IMAP server password if authpassword not defined */
-		AST_STRING_FIELD(default_folder);     /*!< IMAP voicemail folder */
-		AST_STRING_FIELD(shared_id);          /*!< Shared mailbox ID to use rather than the dialed one */
+		AST_STRING_FIELD(user);					/*!< IMAP server login */
+		AST_STRING_FIELD(password);				/*!< IMAP server password if auth_password not defined */
+		AST_STRING_FIELD(default_folder);		/*!< IMAP message folder */
+		AST_STRING_FIELD(shared_id);			/*!< Shared mailbox ID to use rather than the dialed one */
+		AST_STRING_FIELD(server);
+		AST_STRING_FIELD(port);
+		AST_STRING_FIELD(flags);
 	);
 };
 
+/*! \internal \brief Default delimiter in messages */
 static const char default_delimiter = '\0';
+
+/*! \internal \brief By default, messages are deleted if a hangup is detected */
+/* TODO: not sure if this actually should be here */
 static const unsigned int default_expunge_on_hangup = 1;
+
+/*! \internal \brief Default IMAP server hostname */
 static const char *default_imap_server_address = "localhost";
+
+/*! \internal \brief Default port to communicate over */
 static const char *default_imap_port = "143";
+
+/*! \internal \brief Default IMAP folder to store messages in */
 static const char *default_imap_folder = "INBOX";
 
+/*! \internal \brief Context that contains default settings */
 static const char *default_settings_context = "general";
+
+/*! \internal \brief Context that contains timezone information; skipped for mailboxes */
 static const char *default_timezone_context = "zonemessages";
 
+/* \internal \brief The IMAP storage layer configuration object
+ * \note Methods should *not* reference this object directly, but instead should
+ * get a reference from it through imap_get_config
+ */
 static struct imap_config *config;
-
-static struct ao2_container *imap_users;
 
 /*! \internal \brief The mutex that protects access to the imap config object */
 AST_MUTEX_DEFINE_STATIC(config_lock);
+
+/* \internal \brief The IMAP mailboxes */
+static struct ao2_container *imap_mailboxes;
+
+/*! \internal \brief The base storage technology that the IMAP tech uses as an intermediate layer */
+static struct ast_msg_storage_tech *base_tech;
 
 static struct ast_msg_storage_tech imap_message_storage_tech = {
 		.name = "IMAP",
 		.load_config = imap_load_config,
+		.load_mailboxes = imap_load_mailboxes,
+		.get_config = ast_get_message_storage_config,
+		.get_mailbox = ast_get_message_mailbox,
 };
 
-static struct imap_user *imap_user_new(void)
-{
-	struct imap_user *imu = NULL;
-
-	if ((imu = ao2_alloc(sizeof(*imu), imap_user_destroy))) {
-		if (ast_string_field_init(imu, 256)) {
-			ao2_ref(imu, -1);
-			imu = NULL;
-		}
-	}
-
-	return imu;
-}
-
-static void imap_user_destroy(void *obj)
-{
-	struct imap_user *imu = obj;
-
-	if (!imu) {
+static struct imap_mailbox *imap_mailbox_new(const char *context, const char *mailbox)
+{
+	struct imap_mailbox *imbox = NULL;
+	struct ast_msg_mailbox *mbox = NULL;
+
+	if (!base_tech) {
+		return NULL;
+	}
+
+	if (!(mbox = base_tech->get_mailbox(context, mailbox))) {
+		ast_log(AST_LOG_WARNING, "Attempted to create IMAP mailbox from unknown mailbox %s/%s\n", context, mailbox);
+		return NULL;
+	}
+
+	if ((imbox = ao2_alloc(sizeof(*imbox), imap_mailbox_destroy))) {
+		imbox->msg_mailbox = mbox;
+		if (ast_string_field_init(imbox, 256)) {
+			ao2_ref(imbox, -1);
+			imbox = NULL;
+		}
+	} else {
+		ao2_ref(mbox, -1);
+	}
+
+	return imbox;
+}
+
+static void imap_mailbox_destroy(void *obj)
+{
+	struct imap_mailbox *imbox = obj;
+
+	if (!imbox) {
 		return;
 	}
 
-	ao2_ref(imu->msg_user, -1);
-	ast_string_field_free_memory(imu);
+	ao2_ref(imbox->msg_mailbox, -1);
+	ast_string_field_free_memory(imbox);
 }
 
 static struct imap_config *imap_config_new(void)
 {
 	struct imap_config *iconfig = NULL;
+	struct ast_msg_config *config = NULL;
+
+	if (!base_tech) {
+		return NULL;
+	}
+
+	if (!(config = base_tech->get_config())) {
+		return NULL;
+	}
 
 	if ((iconfig = ao2_alloc(sizeof(*iconfig), imap_config_destroy))) {
+		iconfig->msg_config = config;
+
 		if (ast_string_field_init(iconfig, 256)) {
 			ao2_ref(iconfig, -1);
 			iconfig = NULL;
 		}
+	} else {
+		ao2_ref(config, -1);
 	}
 
 	return iconfig;
@@ -108,13 +161,17 @@
 		return;
 	}
 
-	ao2_ref(iconfig->msg_config, -1);
+	ao2_ref(&iconfig->msg_config, -1);
 	ast_string_field_free_memory(iconfig);
 }
 
-static void imap_populate_default_options(struct imap_config *iconfig)
+static void populate_default_config_options(struct imap_config *iconfig)
 {
 	iconfig->expunge_on_hangup = default_expunge_on_hangup;
+	iconfig->close_timeout = 30;
+	iconfig->open_timeout = 30;
+	iconfig->write_timeout = 30;
+	iconfig->read_timeout = 30;
 
 	strcpy(iconfig->delimiter, default_delimiter);
 
@@ -123,13 +180,27 @@
 	ast_string_field_set(iconfig, folder, default_imap_folder);
 }
 
-static int imap_load_config(struct imap_config *iconfig, struct ast_config *cfg, int reload)
+static int imap_load_config(struct ast_config *cfg, int reload)
 {
 	struct ast_variable *var;
 	struct ast_category *cat = ast_category_get(cfg, default_settings_context);
+	struct imap_config *iconfig;
 
 	if (!cat) {
 		ast_log(AST_LOG_ERROR, "No %s category defined in configuration\n", default_settings_context);
+		return 1;
+	}
+
+	if (!base_tech) {
+		ast_log(AST_LOG_ERROR, "No base message technology defined; cannot load configuration\n");
+		return 1;
+	} else if (base_tech->load_config(cfg, reload)) {
+		ast_log(AST_LOG_ERROR, "Base message technology %s failed to load config; cannot load IMAP configuration\n", base_tech->name);
+		return 1;
+	}
+
+	if (!(iconfig = imap_config_new())) {
+		ast_log(AST_LOG_ERROR, "Unable to allocate sufficient memory for imap_config object\n");
 		return 1;
 	}
 
@@ -183,6 +254,13 @@
 		}
 	}
 
+	ast_mutex_lock(&config_lock);
+	if (reload) {
+		ao2_ref(config, -1);
+	}
+	config = iconfig;
+	ast_mutex_unlock(&config_lock);
+
 	return 0;
 }
 
@@ -192,13 +270,13 @@
  * prematurely deleted in the case of a reload - methods that obtain the object should decrement the
  * reference count when they are finished with it.
  */
-static struct imap_config *get_imap_config(void)
+static struct ast_msg_config *imap_get_config(void)
 {
 	ast_mutex_lock(&config_lock);
 	ao2_ref(config, +1);
 	ast_mutex_unlock(&config_lock);
 
-	return config;
+	return (struct ast_msg_config *)config;
 }
 
 static int valid_user(struct imap_user *imu)
@@ -206,7 +284,7 @@
 	return 0;
 }
 
-static void populate_user_from_variable(const struct imap_config *iconfig, struct imap_user *imu, const char *cat_name, struct ast_variable *var)
+static void create_mailbox_from_variable(const struct imap_config *iconfig, struct imap_user *imu, const char *cat_name, struct ast_variable *var)
 {
 	char *values;
 	char *options;
@@ -248,38 +326,45 @@
 	}
 }
 
-static void populate_user_from_category(const struct imap_config *iconfig, struct imap_user *imu, struct ast_config *ucfg, const char *cat_name)
-{
-
-}
-
-static int imap_load_users(const struct imap_config *iconfig, struct ast_config *ucfg, int reload, int load_from_variable, struct ao2_container *user_container)
+static void create_mailbox_from_category(const struct imap_config *iconfig, struct imap_user *imu, struct ast_config *ucfg, const char *cat_name)
+{
+
+}
+
+static int imap_load_mailboxes(struct ast_config *mcfg, int reload, int by_variable)
 {
 	const char *cat_name;
-	struct imap_user *imu_tmp;
-	struct imap_user *imu_old;
-	struct imap_user *imu;
 	int res = 0;
-
-	for (cat_name = ast_category_browse(ucfg, NULL); cat_name; cat_name = ast_category_browse(ucfg, cat_name)) {
+	struct imap_mailbox *imbox = NULL;
+	struct imap_config *iconfig = NULL;
+	struct ao2_container *temp_container;
+
+	if (!base_tech) {
+		ast_log(AST_LOG_ERROR, "No base message technology defined; cannot load mailboxes\n");
+		return 1;
+	} else if (base_tech->load_mailboxes(mcfg, reload, by_variable)) {
+		ast_log(AST_LOG_ERROR, "Base message technology %s failed to load mailboxes; cannot load mailboxes\n", base_tech->name);
+		return 1;
+	}
+
+	iconfig = imap_get_config();
+
+	for (cat_name = ast_category_browse(mcfg, NULL); cat_name; cat_name = ast_category_browse(mcfg, cat_name)) {
 		/* Anything not in the general context or timezone context is assumed to be user data */
-		if (load_from_variable && (!strcasecmp(cat_name, default_general_context) || !strcasecmp(cat_name, default_timezone_context))) {
+		if (by_variable && (!strcasecmp(cat_name, default_settings_context) || !strcasecmp(cat_name, default_timezone_context))) {
 			continue;
 		}
 
-		if (!(imu = imap_user_new())) {
-			ast_log(AST_LOG_ERROR, "Failed to allocate memory for imap_user object\n");
-			res = 1;
-			continue;
-		}
-
-		if (!load_from_variable) {
-			for (var = ast_variable_browse(ucfg, cat_name); var; var = var->next) {
-				populate_user_from_variable(iconfig, imu, cat_name, var);
+		if (!by_variable) {
+			for (var = ast_variable_browse(mcfg, cat_name); var; var = var->next) {
+				if (imbox = create_mailbox_from_variable(iconfig, imu, cat_name, var)) {
+					ao2_link(user_container, )
+				}
 			}
 		} else {
-			if (ast_true(ast_config_option(ucfg, cat_name, "hasvoicemail"))) {
-				populate_user_from_category(iconfig, imu, ucfg, cat_name);
+			/* TODO: this should probably be changed to hasmailbox or something along those lines */
+			if (ast_true(ast_config_option(mcfg, cat_name, "hasvoicemail"))) {
+				imbox = create_mailbox_from_category(iconfig, imu, ucfg, cat_name);
 			}
 		}
 
@@ -288,94 +373,43 @@
 		}
 		ao2_ref(imu, -1);
 	}
+
+	ao2_ref(iconfig, -1);
+
 	return 0;
 }
 
-static int load_configs(int reload)
-{
-	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
-	struct ast_config *cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
-	struct ast_config *ucfg = ast_config_load(USERS_CONFIG, config_flags);
-	struct imap_config *iconfig;
-
-	/* If both configs are unchanged exit; otherwise load both */
-	if (cfg == CONFIG_STATUS_FILEUNCHANGED && ucfg == CONFIG_STATUS_FILEUNCHANGED) {
-		return 0;
-	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED && ucfg != CONFIG_STATUS_FILEUNCHANGED) {
-		ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
-		cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
-	} else if (cfg != CONFIG_STATUS_FILEUNCHANGED && ucfg == CONFIG_STATUS_FILEUNCHANGED) {
-		ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
-		ucfg = ast_config_load(USER_CONFIG, config_flags);
-	}
-
-	if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
-		if (ucfg && ucfg != CONFIG_STATUS_FILEINVALID) {
-			ast_config_destroy(ucfg);
-		}
-		ast_log(AST_LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format.  Aborting.\n");
-		return 1;
-	}
-
-	if (ucfg == CONFIG_STATUS_FILEINVALID) {
-		ast_log(AST_LOG_WARNING, "Config file " USERS_CONFIG " is in an invalid format.  Avoiding.\n");
-		ucfg = NULL;
+static int reload(void)
+{
+	return 0;
+}
+
+static int unload_module(void)
+{
+	ast_unregister_message_storage_tech(imap_message_storage_tech.name);
+
+	ao2_ref(config, -1);
+	ao2_ref(imap_mailboxes, -1);
+
+	return 0;
+}
+
+static int load_module(void)
+{
+	/* TODO: base? */
+	if (!(base_tech = ast_get_message_storage_tech("base"))) {
+		ast_log(AST_LOG_ERROR, "Unable to obtain base message technology\n");
+		return AST_MODULE_LOAD_FAILURE;
+	}
+
+	if (!(imap_mailboxes = ao2_container_alloc())) {
+		ast_log(AST_LOG_ERROR, "Unable to allocate IMAP users container\n");
+		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	/* Since we have good config objects, attempt to create a new IMAP config from them */
-	if (!(iconfig = imap_config_new())) {
+	if (!(config = imap_config_new())) {
 		ast_log(AST_LOG_ERROR, "Failed to allocate memory for new IMAP config object\n");
-		return 1;
-	}
-	if (imap_load_config(iconfig, cfg, reload)) {
-		ast_log(AST_LOG_ERROR, "Failed to load and parse " VOICEMAIL_CONFIG ".  Aborting.\n");
-		ast_config_destroy(cfg);
-		if (ucfg) {
-			ast_config_destroy(ucfg);
-		}
-		return 1;
-	}
-
-	/* Load user information from both the main config and from the optional user config */
-	imap_load_users(iconfig, cfg, reload, 1, imap_users);
-	if (ucfg) {
-		imap_load_users(iconfig, ucfg, reload, 0, imap_users);
-	}
-
-	/* Update and replace the current IMAP configuration object */
-	ast_mutex_lock(&config_lock);
-	if (reload) {
-		ao2_ref(config, -1);
-	}
-	config = iconfig;
-	ast_mutex_unlock(&config_lock);
-
-	return 0;
-}
-
-static int reload(void)
-{
-	int res = 0;
-
-	res |= load_configs(1);
-
-	return res;
-}
-
-/* If I were to allow unloading it would look something like this */
-static int unload_module(void)
-{
-	return 0;
-}
-
-static int load_module(void)
-{
-	if (!(imap_users = ao2_container_alloc())) {
-		ast_log(LOG_ERROR, "Unable to allocate IMAP users container\n");
-		return AST_MODULE_LOAD_FAILURE;
-	}
-
-	if (load_configs(0)) {
 		ao2_ref(imap_users, -1);
 		return AST_MODULE_LOAD_FAILURE;
 	}

Modified: team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c?view=diff&rev=348361&r1=348360&r2=348361
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c (original)
+++ team/mjordan/voicemail_refactor_11_10_19/res/res_message_storage.c Fri Dec 16 07:30:28 2011
@@ -22,11 +22,12 @@
 		return;
 	}
 
-	/* Don't add the tech if its already been added */
+	/* Add the tech if it hasn't already been added */
 	ao2_lock(msg_storage_techs);
 	it_techs = ao2_iterator_init(msg_storage_techs, 0);
 	while ((tech_current = ao2_iterator_next(&it_techs))) {
 		if (!strncmp(ms_tech->name, tech_current->name, sizeof(ms_tech->name))) {
+			ast_log(AST_LOG_WARNING, "Message storage technology %s already registered\n", ms_tech->name)
 			ao2_ref(tech_current, -1);
 			ao2_iterator_destroy(&it_techs);
 			ao2_unlock(msg_storage_techs);
@@ -38,6 +39,21 @@
 	ao2_unlock(msg_storage_techs);
 
 	ao2_link(msg_storage_techs, ms_tech);
+}
+
+void ast_unregister_message_storage_tech(const char * const name)
+{
+	struct ast_msg_storage_tech tech_temp = { .name = name, };
+	struct ast_msg_storage_tech *ms_tech;
+
+	if (ast_strlen_zero(name)) {
+		return;
+	}
+
+	if ((ms_tech = ao2_find(msg_storage_techs, tech_temp, OBJ_POINTER))) {
+		ao2_ref(ms_tech, -1);
+		ao2_unlink(msg_storage_techs, ms_tech);
+	}
 }
 
 struct ast_msg_storage_tech *ast_get_message_storage_tech(const char * const name)




More information about the asterisk-commits mailing list