/* preauth prog:///usr/sbin/progname preauth ident[://:port] preauth stdio */ static int cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) { if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) return 1; if (strcmp (val->v.string, "stdio") == 0) preauth_mode = preauth_stdio; else if (strcmp (val->v.string, "ident") == 0) return parse_preauth_scheme (debug, val->v.string, NULL); else if (val->v.string[0] == '/') { preauth_program = xstrdup (val->v.string); preauth_mode = preauth_prog; } else { mu_url_t url; char *scheme; int rc = mu_url_create (&url, val->v.string); if (rc) { mu_diag_funcall (MU_DIAG_ERROR, "mu_url_create", val->v.string, rc); return 1; } rc = mu_url_parse (url); if (rc) { mu_cfg_format_error (debug, MU_DEBUG_ERROR, "%s: %s", val->v.string, mu_strerror (rc)); return 1; } rc = mu_url_aget_scheme (url, &scheme); if (rc) { mu_url_destroy (&url); mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("URL error: %s"), mu_strerror (rc)); return 1; } rc = parse_preauth_scheme (debug, scheme, url); mu_url_destroy (&url); free (scheme); return rc; } return 0; }
int mu_url_dup (mu_url_t old_url, mu_url_t *new_url) { int rc; const char *s; mu_url_t url = calloc (1, sizeof (*url)); if (!url) return ENOMEM; mu_url_sget_name (old_url, &s); url->name = strdup (s); if (!url->name) { free (url); return ENOMEM; } rc = mu_url_copy_hints (url, old_url); if (rc) { mu_url_destroy (&url); return rc; } *new_url = url; return 0; }
int mu_smtp_set_url (mu_smtp_t smtp, mu_url_t url) { if (!smtp) return EINVAL; mu_url_destroy (&smtp->url); if (!url) return 0; return mu_url_dup (url, &smtp->url); }
/* The folder is destroy if it is the last reference. */ void mu_folder_destroy (mu_folder_t *pfolder) { if (pfolder && *pfolder) { mu_folder_t folder = *pfolder; int destroy_lock = 0; mu_monitor_t monitor = folder->monitor; mu_monitor_wrlock (monitor); /* Check if this the last reference for this folder. If yes removed it from the list. */ mu_monitor_wrlock (&folder_lock); folder->ref--; /* Remove the folder from the list of known folder. */ if (folder->ref <= 0) mu_list_remove (known_folder_list, folder); /* If the list is empty we can safely remove it. */ if (mu_list_is_empty (known_folder_list)) mu_list_destroy (&known_folder_list); mu_monitor_unlock (&folder_lock); if (folder->ref <= 0) { mu_monitor_unlock (monitor); destroy_lock = 1; /* Notify the observers. */ if (folder->observable) { mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY, folder); mu_observable_destroy (&folder->observable, folder); } if (folder->_destroy) folder->_destroy (folder); mu_monitor_wrlock (monitor); if (folder->authority) mu_authority_destroy (&folder->authority, folder); if (folder->url) mu_url_destroy (&folder->url); if (folder->property) mu_property_destroy (&folder->property); free (folder); } mu_monitor_unlock (monitor); if (destroy_lock) mu_monitor_destroy (&monitor, folder); *pfolder = NULL; } }
int mu_folder_create (mu_folder_t *pfolder, const char *name) { int rc; mu_url_t url; rc = mu_url_create (&url, name); if (rc) return rc; rc = mu_folder_create_from_record (pfolder, url, NULL); if (rc) mu_url_destroy (&url); return rc; }
int mu_registrar_lookup (const char *name, int flags, mu_record_t *precord, int *pflags) { int rc; mu_url_t url; rc = mu_url_create (&url, name); if (rc) return rc; rc = mu_url_parse (url); if (rc == 0) rc = mu_registrar_lookup_url (url, flags, precord, pflags); mu_url_destroy (&url); return rc; }
/* A folder could be remote (IMAP), or local(a spool directory) like $HOME/Mail etc .. We maintain a list of known folders to avoid creating multiple folders for the same URL. So, when mu_folder_create is called we check if we already have a folder for that URL and return it, otherwise we create a new one. Downsides: the scheme to detect the same URL is very weak, and there could be cases where you'll want a different folder for the same URL, there is not easy way to do this. */ int mu_folder_create_from_record (mu_folder_t *pfolder, mu_url_t url, mu_record_t record) { if (!pfolder) return MU_ERR_OUT_PTR_NULL; if (record || /* Look in the registrar list(iterator), for a possible concrete mailbox implementation that could match the URL. */ mu_registrar_lookup_url (url, MU_FOLDER_ATTRIBUTE_DIRECTORY, &record, NULL) == 0) { int (*f_init) (mu_folder_t) = NULL; mu_record_get_folder (record, &f_init); if (f_init) { int status, mask; mu_folder_t folder; int (*u_init) (mu_url_t) = NULL; status = mu_record_check_url (record, url, &mask); if (status) /* FIXME: mask would provide more info */ return status; mu_record_get_url (record, &u_init); if (u_init) { status = u_init (url); if (status) return status; } mu_monitor_wrlock (&folder_lock); /* Check if we already have the same URL folder. */ if (is_known_folder (url, &folder)) { folder->ref++; *pfolder = folder; mu_url_destroy (&url); /* FIXME: Hmm */ mu_monitor_unlock (&folder_lock); return 0; } else mu_monitor_unlock (&folder_lock); /* Create a new folder. */ /* Allocate memory for the folder. */ folder = calloc (1, sizeof (*folder)); if (folder != NULL) { folder->url = url; /* Initialize the internal foilder lock, now so the concrete folder could use it. */ status = mu_monitor_create (&folder->monitor, 0, folder); if (status == 0) { /* Create the concrete folder type. */ status = f_init (folder); if (status == 0) { if (!folder->_match) folder->_match = mu_folder_imap_match; *pfolder = folder; folder->ref++; /* Put on the internal list of known folders. */ if (known_folder_list == NULL) mu_list_create (&known_folder_list); mu_list_append (known_folder_list, folder); } } /* Something went wrong, destroy the object. */ if (status) { if (folder->monitor) mu_monitor_destroy (&folder->monitor, folder); free (folder); } } return status; } } return MU_ERR_NOENT; }