Mercurial > dovecot > core-2.2
view src/imap/namespace.c @ 1750:4e14ba3c115b HEAD
Added "inbox" setting to specify which namespace has the INBOX.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 06 Sep 2003 20:44:51 +0300 |
parents | 31c4bb26a1e9 |
children | 9547667cfa19 |
line wrap: on
line source
/* Copyright (C) 2003 Timo Sirainen */ #include "common.h" #include "commands.h" #include "namespace.h" #include <stdlib.h> static struct namespace * namespace_add_env(pool_t pool, const char *data, unsigned int num, const char *user) { struct namespace *ns; const char *sep, *type, *prefix; int inbox; ns = p_new(pool, struct namespace, 1); sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num)); type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num)); prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num)); inbox = getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL; if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0) ns->type = NAMESPACE_PRIVATE; else if (strncmp(type, "shared", 6) == 0) ns->type = NAMESPACE_SHARED; else if (strncmp(type, "public", 6) == 0) ns->type = NAMESPACE_PUBLIC; else i_fatal("Unknown namespace type: %s", type); if (prefix == NULL) prefix = ""; ns->prefix = p_strdup(pool, prefix); ns->inbox = inbox; ns->storage = mail_storage_create_with_data(data, user, ns->prefix, sep != NULL ? *sep : '\0'); if (ns->storage == NULL) { i_fatal("Failed to create storage for '%s' with data: %s", ns->prefix, data); } if (hook_mail_storage_created != NULL) hook_mail_storage_created(&ns->storage); ns->hierarchy_sep = ns->storage->hierarchy_sep; return ns; } struct namespace *namespace_init(pool_t pool, const char *user) { struct namespace *namespaces, *ns, **ns_p; const char *mail, *data; unsigned int i; namespaces = NULL; ns_p = &namespaces; /* first try NAMESPACE_* environments */ for (i = 1; ; i++) { t_push(); data = getenv(t_strdup_printf("NAMESPACE_%u", i)); t_pop(); if (data == NULL) break; t_push(); *ns_p = namespace_add_env(pool, data, i, user); t_pop(); ns_p = &(*ns_p)->next; } if (namespaces != NULL) return namespaces; /* fallback to MAIL */ mail = getenv("MAIL"); if (mail == NULL) { /* support also maildir-specific environment */ mail = getenv("MAILDIR"); if (mail != NULL) mail = t_strconcat("maildir:", mail, NULL); } ns = p_new(pool, struct namespace, 1); ns->storage = mail_storage_create_with_data(mail, user, NULL, '\0'); if (ns->storage == NULL) { if (mail != NULL && *mail != '\0') i_fatal("Failed to create storage with data: %s", mail); else { const char *home; home = getenv("HOME"); if (home == NULL) home = "not set"; i_fatal("MAIL environment missing and " "autodetection failed (home %s)", home); } } ns->type = NAMESPACE_PRIVATE; ns->inbox = TRUE; ns->prefix = p_strdup(pool, ""); ns->hierarchy_sep = ns->storage->hierarchy_sep; if (hook_mail_storage_created != NULL) hook_mail_storage_created(&ns->storage); return ns; } void namespace_deinit(struct namespace *namespaces) { while (namespaces != NULL) { mail_storage_destroy(namespaces->storage); namespaces = namespaces->next; } } struct namespace * namespace_find(struct namespace *namespaces, const char *mailbox) { struct namespace *best = NULL; size_t len, best_len = 0; int inbox; inbox = strncasecmp(mailbox, "INBOX", 5) == 0; if (inbox && mailbox[5] == '\0') { /* find the INBOX namespace */ while (namespaces != NULL) { if (namespaces->inbox) return namespaces; if (namespaces->prefix == NULL) best = namespaces; namespaces = namespaces->next; } return best; } while (namespaces != NULL) { len = namespaces->prefix == NULL ? 0 : strlen(namespaces->prefix); if (len >= best_len && (strncmp(namespaces->prefix, mailbox, len) == 0 || (inbox && strncmp(namespaces->prefix, "INBOX", 5) == 0 && mailbox[5] == namespaces->hierarchy_sep && namespaces->prefix[5] == namespaces->hierarchy_sep && strncmp(namespaces->prefix+6, mailbox+6, len-6) == 0))) { best = namespaces; best_len = len; } namespaces = namespaces->next; } return best; }