[asterisk-commits] mjordan: branch mjordan/voicemail_refactor_11_10_19 r342868 - in /team/mjorda...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list