[svn-commits] mjordan: branch mjordan/voicemail_refactor_11_10_19 r342868 - in /team/mjorda...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Oct 31 16:48:16 CDT 2011


Author: mjordan
Date: Mon Oct 31 16:48:12 2011
New Revision: 342868

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=342868
Log:
Began parsing IMAP settings

Added:
    team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_configuration.c
      - copied, changed from r342660, team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_config_parser.c
Removed:
    team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_config_parser.c
    team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_file_backend.c
    team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_imap_backend.c
    team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_odbc_backend.c
Modified:
    team/mjordan/voicemail_refactor_11_10_19/res/res_message_imap.c

Copied: team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_configuration.c (from r342660, team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_config_parser.c)
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_configuration.c?view=diff&rev=342868&p1=team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_config_parser.c&r1=342660&p2=team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_configuration.c&r2=342868
==============================================================================
--- team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_config_parser.c (original)
+++ team/mjordan/voicemail_refactor_11_10_19/apps/voicemail/vm_configuration.c Mon Oct 31 16:48:12 2011
@@ -1954,7 +1954,6 @@
 	return result;
 }
 
-
 void vm_register_config_tests(void)
 {
 	AST_TEST_REGISTER(test_vm_default_config);

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=342868&r1=342867&r2=342868
==============================================================================
--- 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 Mon Oct 31 16:48:12 2011
@@ -7,8 +7,15 @@
 #define USERS_CONFIG "users.conf"
 
 struct imap_config {
-	int expunge_on_hangup:1;
-	int imap_greetings:1;
+	/* TODO: make the next two fields bit fields? */
+	struct ast_msg_config *msg_config;
+	unsigned int expunge_on_hangup;
+	unsigned int imap_greetings;
+	int read_timeout;
+	int write_timeout;
+	int open_timeout;
+	int close_timeout;
+	int version;
 	char delimiter;
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(server);
@@ -23,6 +30,7 @@
 };
 
 struct imap_user {
+	struct ast_msg_user *msg_user;
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(user);               /*!< IMAP server login */
 		AST_STRING_FIELD(password);           /*!< IMAP server password if authpassword not defined */
@@ -32,25 +40,254 @@
 };
 
 static const char default_delimiter = '\0';
+static const unsigned int default_expunge_on_hangup = 1;
+static const char *default_imap_server_address = "localhost";
+static const char *default_imap_port = "143";
+static const char *default_imap_folder = "INBOX";
+
+static const char *default_settings_context = "general";
+static const char *default_timezone_context = "zonemessages";
 
 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);
 
 static struct ast_msg_storage_tech imap_message_storage_tech = {
 		.name = "IMAP",
 		.load_config = imap_load_config,
 };
 
-static int imap_load_config(struct ast_config *cfg, int reload)
-{
-
-	/* lock something */
-	return 0;
-}
-
-static int imap_load_users(struct ast_config *ucfg, int reload)
-{
+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) {
+		return;
+	}
+
+	ao2_ref(imu->msg_user, -1);
+	ast_string_field_free_memory(imu);
+}
+
+static struct imap_config *imap_config_new(void)
+{
+	struct imap_config *iconfig = NULL;
+
+	if ((iconfig = ao2_alloc(sizeof(*iconfig), imap_config_destroy))) {
+		if (ast_string_field_init(iconfig, 256)) {
+			ao2_ref(iconfig, -1);
+			iconfig = NULL;
+		}
+	}
+
+	return iconfig;
+}
+
+static void imap_config_destroy(void *obj)
+{
+	struct imap_config *iconfig = obj;
+
+	if (!iconfig) {
+		return;
+	}
+
+	ao2_ref(iconfig->msg_config, -1);
+	ast_string_field_free_memory(iconfig);
+}
+
+static void imap_populate_default_options(struct imap_config *iconfig)
+{
+	iconfig->expunge_on_hangup = default_expunge_on_hangup;
+
+	strcpy(iconfig->delimiter, default_delimiter);
+
+	ast_string_field_set(iconfig, server, default_imap_server_address);
+	ast_string_field_set(iconfig, port, default_imap_port);
+	ast_string_field_set(iconfig, folder, default_imap_folder);
+}
+
+static int imap_load_config(struct imap_config *iconfig, struct ast_config *cfg, int reload)
+{
+	struct ast_variable *var;
+	struct ast_category *cat = ast_category_get(cfg, default_settings_context);
+
+	if (!cat) {
+		ast_log(AST_LOG_ERROR, "No %s category defined in configuration\n", default_settings_context);
+		return 1;
+	}
+
+	imap_populate_default_options(iconfig);
+
+	for (var = ast_category_first(cat); var; var = var->next) {
+		if (!strcasecmp(var->name, "imapserver")) {
+			ast_string_field_set(iconfig, server, var->value);
+		} else if (!strcasecmp(var->name, "imapport")) {
+			ast_string_field_set(iconfig, port, var->value);
+		} else if (!strcasecmp(var->name, "imapflags")) {
+			ast_string_field_set(iconfig, flags, var->value);
+		} else if (!strcasecmp(var->name, "authuser")) {
+			ast_string_field_set(iconfig, auth_user, var->value);
+		} else if (!strcasecmp(var->name, "authpassword")) {
+			ast_string_field_set(iconfig, auth_password, var->value);
+		} else if (!strcasecmp(var->name, "expungeonhangup")) {
+			if (ast_false(var->value)) {
+				iconfig->expunge_on_hangup = 0;
+			} else {
+				iconfig->expunge_on_hangup = 1;
+			}
+		} else if (!strcasecmp(var->name, "imapfolder")) {
+			ast_string_field_set(iconfig, folder, var->value);
+		} else if (!strcasecmp(var->name, "imapparentfolder")) {
+			ast_string_field_set(iconfig, parent_folder, var->value);
+		} else if (!strcasecmp(var->name, "greetingfolder") || !strcasecmp(var->name, "greetingsfolder")) {
+			ast_string_field_set(iconfig, greeting_folder, var->value);
+		} else if (!strcasecmp(var->name, "imapgreetings")) {
+			if (ast_true(var->value)) {
+				iconfig->imap_greetings = 1;
+			} else {
+				iconfig->imap_greetings = 0;
+			}
+		} else if (!strcasecmp(var->name, "imapreadtimeout")) {
+			if (sscanf(var->value, "%30ud", &(iconfig->read_timeout)) != 1) {
+				ast_log(AST_LOG_WARNING, "Invalid imapreadtimeout of %s.\n", var->value);
+			}
+		} else if (!strcasecmp(var->name, "imapwritetimeout")) {
+			if (sscanf(var->value, "%30ud", &(iconfig->write_timeout)) != 1) {
+				ast_log(AST_LOG_WARNING, "Invalid imapwritetimeout of %s.\n", var->value);
+			}
+		} else if (!strcasecmp(var->name, "imapopentimeout")) {
+			if (sscanf(var->value, "%30ud", &(iconfig->open_timeout)) != 1) {
+				ast_log(AST_LOG_WARNING, "Invalid imapopentimeout of %s.\n", var->value);
+			}
+		} else if (!strcasecmp(var->name, "imapclosetimeout")) {
+			if (sscanf(var->value, "%30ud", &(iconfig->close_timeout)) != 1) {
+				ast_log(AST_LOG_WARNING, "Invalid imapclosetimeout of %s.\n", var->value);
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*! \internal \brief Safely access the global IMAP configuration object
+ * \note IMAP methods should use this to safely get a reference to the global IMAP config object.  This
+ * method increases the object reference count on the configuration object to prevent it from being
+ * 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)
+{
+	ast_mutex_lock(&config_lock);
+	ao2_ref(config, +1);
+	ast_mutex_unlock(&config_lock);
+
+	return config;
+}
+
+static int valid_user(struct imap_user *imu)
+{
+	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)
+{
+	char *values;
+	char *options;
+	char *option_key;
+	char *option_value;
+	char *value;
+
+	ast_copy_string(vmu->mailbox, var->name, sizeof(vmu->mailbox));
+	ast_copy_string(vmu->context, context, sizeof(vmu->context));
+
+	values = ast_strdup(var->value);
+
+	if ((value = strsep(&values, ","))) {
+		ast_string_field_set(vmu, password, value);
+	}
+	if (values && (value = strsep(&values, ","))) {
+		ast_string_field_set(vmu, fullname, value);
+	}
+	if (values && (value = strsep(&values, ","))) {
+		ast_string_field_set(vmu, email_address, value);
+	}
+	if (values && (value = strsep(&values, ","))) {
+		ast_string_field_set(vmu, pager_address, value);
+	}
+	if (values && (value = strsep(&values, ","))) {
+		options = ast_strdup(value);
+		while ((option_value = strsep(&options, "|"))) {
+			if ((option_key = strsep(&option_value, "=")) && option_value) {
+				apply_user_option(vmcfg, vmu, option_key, option_value);
+			}
+		}
+		if (options) {
+			ast_free(options);
+		}
+	}
+
+	if (values) {
+		ast_free(values);
+	}
+}
+
+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)
+{
+	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)) {
+		/* 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))) {
+			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);
+			}
+		} else {
+			if (ast_true(ast_config_option(ucfg, cat_name, "hasvoicemail"))) {
+				populate_user_from_category(iconfig, imu, ucfg, cat_name);
+			}
+		}
+
+		if (!validate_user(imu)) {
+			ao2_link(user_container, imu);
+		}
+		ao2_ref(imu, -1);
+	}
 	return 0;
 }
 
@@ -59,6 +296,7 @@
 	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) {
@@ -80,16 +318,39 @@
 	}
 
 	if (ucfg == CONFIG_STATUS_FILEINVALID) {
-		ast_log(AST_LOG_WARNING, "Config file " USER_CONFIG " is in an invalid format.  Avoiding.\n");
+		ast_log(AST_LOG_WARNING, "Config file " USERS_CONFIG " is in an invalid format.  Avoiding.\n");
 		ucfg = NULL;
 	}
 
-	imap_load_config(cfg, reload);
-
-	imap_load_users(cfg, reload);
+	/* Since we have good config objects, attempt to create a new IMAP config from them */
+	if (!(iconfig = 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(ucfg, reload);
-	}
+		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)
@@ -121,7 +382,7 @@
 
 	ast_register_message_storage_tech(&imap_message_storage_tech);
 
-	return res;
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Asterisk Message Storage for IMAP",




More information about the svn-commits mailing list