[dovecot-cvs] dovecot/src/lib-storage Makefile.am, 1.16, 1.17 mail-namespace.c, NONE, 1.1 mail-namespace.h, NONE, 1.1 mail-storage-private.h, 1.50, 1.51 mail-storage.c, 1.78, 1.79 mail-storage.h, 1.128, 1.129
tss at dovecot.org
tss at dovecot.org
Tue Apr 3 11:34:32 EEST 2007
Update of /var/lib/cvs/dovecot/src/lib-storage
In directory talvi:/tmp/cvs-serv21629/lib-storage
Modified Files:
Makefile.am mail-storage-private.h mail-storage.c
mail-storage.h
Added Files:
mail-namespace.c mail-namespace.h
Log Message:
Moved namespace handling to lib-storage. Beginnings of namespace support for
non-IMAP parts of Dovecot.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/Makefile.am,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- Makefile.am 22 Feb 2007 21:51:07 -0000 1.16
+++ Makefile.am 3 Apr 2007 08:34:29 -0000 1.17
@@ -11,6 +11,7 @@
libstorage_a_SOURCES = \
mail.c \
mail-copy.c \
+ mail-namespace.c \
mail-search.c \
mail-storage.c \
mailbox-list.c \
@@ -18,6 +19,7 @@
headers = \
mail-copy.h \
+ mail-namespace.h \
mail-search.h \
mail-storage.h \
mail-storage-private.h \
--- NEW FILE: mail-namespace.c ---
/* Copyright (C) 2005-2007 Timo Sirainen */
#include "lib.h"
#include "file-lock.h"
#include "mail-storage.h"
#include "mail-namespace.h"
#include <stdlib.h>
static void namespace_init_storage(struct mail_namespace *ns)
{
ns->prefix_len = strlen(ns->prefix);
ns->real_sep = mail_storage_get_hierarchy_sep(ns->storage);
if (ns->sep == '\0')
ns->sep = ns->real_sep;
if (ns->sep == '"' || ns->sep == '\\') {
ns->sep_str[0] = '\\';
ns->sep_str[1] = ns->sep;
} else {
ns->sep_str[0] = ns->sep;
}
}
static struct mail_namespace *
namespace_add_env(pool_t pool, const char *data, unsigned int num,
const char *user, enum mail_storage_flags flags,
enum file_lock_method lock_method)
{
struct mail_namespace *ns;
const char *sep, *type, *prefix;
bool inbox, hidden, subscriptions;
ns = p_new(pool, struct mail_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;
hidden = getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL;
subscriptions = getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS",
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_error("Unknown namespace type: %s", type);
return NULL;
}
if (ns->type != NAMESPACE_PRIVATE)
flags |= MAIL_STORAGE_FLAG_SHARED_NAMESPACE;
if (ns->inbox)
flags |= MAIL_STORAGE_FLAG_HAS_INBOX;
if (prefix == NULL)
prefix = "";
if ((flags & MAIL_STORAGE_FLAG_DEBUG) != 0) {
i_info("Namespace: type=%s, prefix=%s, sep=%s, "
"inbox=%s, hidden=%s, subscriptions=%s",
type == NULL ? "" : type, prefix, sep == NULL ? "" : sep,
inbox ? "yes" : "no",
hidden ? "yes" : "no",
subscriptions ? "yes" : "no");
}
ns->prefix = p_strdup(pool, prefix);
ns->inbox = inbox;
ns->hidden = hidden;
ns->subscriptions = subscriptions;
if (mail_storage_create(ns, NULL, data, user, flags, lock_method) < 0) {
i_error("Failed to create storage for '%s' with data: %s",
ns->prefix, data);
return NULL;
}
if (sep != NULL)
ns->sep = *sep;
namespace_init_storage(ns);
return ns;
}
int mail_namespaces_init(pool_t pool, const char *user,
struct mail_namespace **namespaces_r)
{
struct mail_namespace *namespaces, *ns, **ns_p;
enum mail_storage_flags flags;
enum file_lock_method lock_method;
const char *mail, *data;
unsigned int i;
mail_storage_parse_env(&flags, &lock_method);
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, flags,
lock_method);
t_pop();
if (*ns_p != NULL)
return -1;
ns_p = &(*ns_p)->next;
}
if (namespaces != NULL) {
*namespaces_r = namespaces;
return 0;
}
/* 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 mail_namespace, 1);
ns->type = NAMESPACE_PRIVATE;
ns->inbox = TRUE;
ns->subscriptions = TRUE;
ns->prefix = "";
flags |= MAIL_STORAGE_FLAG_HAS_INBOX;
if (mail_storage_create(ns, NULL, mail, user, flags, lock_method) < 0) {
if (mail != NULL && *mail != '\0')
i_error("Failed to create storage with data: %s", mail);
else {
const char *home;
home = getenv("HOME");
if (home == NULL) home = "not set";
i_error("MAIL environment missing and "
"autodetection failed (home %s)", home);
}
return -1;
}
namespace_init_storage(ns);
*namespaces_r = ns;
return 0;
}
struct mail_namespace *mail_namespaces_init_empty(pool_t pool)
{
struct mail_namespace *ns;
ns = p_new(pool, struct mail_namespace, 1);
ns->prefix = "";
return ns;
}
void mail_namespaces_deinit(struct mail_namespace **_namespaces)
{
struct mail_namespace *namespaces = *_namespaces;
*_namespaces = NULL;
while (namespaces != NULL) {
if (namespaces->storage != NULL)
mail_storage_destroy(&namespaces->storage);
namespaces = namespaces->next;
}
}
const char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name)
{
char *ret, *p;
if (ns->sep == ns->real_sep)
return name;
ret = p_strdup(unsafe_data_stack_pool, name);
for (p = ret; *p != '\0'; p++) {
if (*p == ns->sep)
*p = ns->real_sep;
}
return ret;
}
static struct mail_namespace *
mail_namespace_find_int(struct mail_namespace *namespaces, const char **mailbox,
bool show_hidden)
{
#define CHECK_VISIBILITY(ns, show_hidden) \
((!(ns)->hidden) || (show_hidden))
struct mail_namespace *ns = namespaces;
const char *box = *mailbox;
struct mail_namespace *best = NULL;
size_t best_len = 0;
bool inbox;
inbox = strncasecmp(box, "INBOX", 5) == 0;
if (inbox && box[5] == '\0') {
/* find the INBOX namespace */
*mailbox = "INBOX";
while (ns != NULL) {
if (ns->inbox && CHECK_VISIBILITY(ns, show_hidden))
return ns;
if (*ns->prefix == '\0')
best = ns;
ns = ns->next;
}
return best;
}
for (; ns != NULL; ns = ns->next) {
if (ns->prefix_len >= best_len &&
(strncmp(ns->prefix, box, ns->prefix_len) == 0 ||
(inbox && strncmp(ns->prefix, "INBOX", 5) == 0 &&
strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) &&
CHECK_VISIBILITY(ns, show_hidden)) {
best = ns;
best_len = ns->prefix_len;
}
}
if (best != NULL) {
if (best_len > 0)
*mailbox += best_len;
else if (inbox && (box[5] == best->sep || box[5] == '\0'))
*mailbox = t_strconcat("INBOX", box+5, NULL);
*mailbox = mail_namespace_fix_sep(best, *mailbox);
}
return best;
}
struct mail_namespace *
mail_namespace_find(struct mail_namespace *namespaces, const char **mailbox)
{
return mail_namespace_find_int(namespaces, mailbox, TRUE);
}
struct mail_namespace *
mail_namespace_find_visible(struct mail_namespace *namespaces,
const char **mailbox)
{
return mail_namespace_find_int(namespaces, mailbox, FALSE);
}
struct mail_namespace *
mail_namespace_find_prefix(struct mail_namespace *namespaces,
const char *prefix)
{
struct mail_namespace *ns;
unsigned int len = strlen(prefix);
for (ns = namespaces; ns != NULL; ns = ns->next) {
if (ns->prefix_len == len &&
strcmp(ns->prefix, prefix) == 0)
return ns;
}
return NULL;
}
--- NEW FILE: mail-namespace.h ---
#ifndef __MAIL_NAMESPACE_H
#define __MAIL_NAMESPACE_H
enum namespace_type {
NAMESPACE_PRIVATE,
NAMESPACE_SHARED,
NAMESPACE_PUBLIC
};
struct mail_namespace {
struct mail_namespace *next;
enum namespace_type type;
char sep, real_sep, sep_str[3];
const char *prefix;
size_t prefix_len;
bool inbox, hidden, subscriptions;
struct mail_storage *storage;
};
int mail_namespaces_init(pool_t pool, const char *user,
struct mail_namespace **namespaces_r);
struct mail_namespace *mail_namespaces_init_empty(pool_t pool);
void mail_namespaces_deinit(struct mail_namespace **namespaces);
const char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name);
struct mail_namespace *
mail_namespace_find(struct mail_namespace *namespaces, const char **mailbox);
struct mail_namespace *
mail_namespace_find_visible(struct mail_namespace *namespaces,
const char **mailbox);
struct mail_namespace *
mail_namespace_find_prefix(struct mail_namespace *namespaces,
const char *prefix);
#endif
Index: mail-storage-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage-private.h,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- mail-storage-private.h 30 Mar 2007 18:57:34 -0000 1.50
+++ mail-storage-private.h 3 Apr 2007 08:34:29 -0000 1.51
@@ -53,6 +53,7 @@
pool_t pool;
char *error;
+ struct mail_namespace *ns;
struct mailbox_list *list;
const char *user; /* name of user accessing the storage */
Index: mail-storage.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- mail-storage.c 30 Mar 2007 18:57:34 -0000 1.78
+++ mail-storage.c 3 Apr 2007 08:34:29 -0000 1.79
@@ -7,6 +7,7 @@
#include "mail-index-private.h"
#include "mailbox-list-private.h"
#include "mail-storage-private.h"
+#include "mail-namespace.h"
#include "index/index-storage.h"
#include <stdlib.h>
@@ -149,10 +150,10 @@
}
}
-struct mail_storage *
-mail_storage_create(const char *driver, const char *data, const char *user,
- enum mail_storage_flags flags,
- enum file_lock_method lock_method)
+int mail_storage_create(struct mail_namespace *ns, const char *driver,
+ const char *data, const char *user,
+ enum mail_storage_flags flags,
+ enum file_lock_method lock_method)
{
struct mail_storage *storage_class, *storage;
struct mail_storage *const *classes;
@@ -173,14 +174,14 @@
"don't know what to do with it: %s "
"(try prefixing it with mbox: or maildir:)",
data);
- return NULL;
+ return -1;
}
classes = &storage_class;
count = 1;
} else {
storage_class = mail_storage_find(driver);
if (storage_class == NULL)
- return NULL;
+ return -1;
classes = &storage_class;
count = 1;
}
@@ -190,6 +191,7 @@
storage->flags = flags;
storage->lock_method = lock_method;
storage->user = p_strdup(storage->pool, user);
+ storage->ns = ns;
storage->callbacks =
p_new(storage->pool, struct mail_storage_callbacks, 1);
@@ -202,11 +204,13 @@
pool_unref(storage->pool);
}
if (i == count)
- return NULL;
+ return -1;
if (hook_mail_storage_created != NULL)
hook_mail_storage_created(storage);
- return storage;
+
+ ns->storage = storage;
+ return 0;
}
void mail_storage_destroy(struct mail_storage **_storage)
@@ -319,6 +323,11 @@
return storage->list;
}
+struct mail_namespace *mail_storage_get_namespace(struct mail_storage *storage)
+{
+ return storage->ns;
+}
+
void mail_storage_set_callbacks(struct mail_storage *storage,
struct mail_storage_callbacks *callbacks,
void *context)
Index: mail-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/mail-storage.h,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -d -r1.128 -r1.129
--- mail-storage.h 30 Mar 2007 13:40:12 -0000 1.128
+++ mail-storage.h 3 Apr 2007 08:34:29 -0000 1.129
@@ -136,6 +136,7 @@
MAILBOX_SYNC_TYPE_KEYWORDS = 0x04
};
+struct mail_namespace;
struct mail_storage;
struct mail_search_arg;
struct mail_keywords;
@@ -204,15 +205,16 @@
/* Create a new instance of registered mail storage class with given
storage-specific data. If driver is NULL, it's tried to be autodetected
from data. If data is NULL, it uses the first storage that exists.
- May return NULL if anything fails. */
-struct mail_storage *
-mail_storage_create(const char *driver, const char *data, const char *user,
- enum mail_storage_flags flags,
- enum file_lock_method lock_method);
+ The storage is put into ns->storage. */
+int mail_storage_create(struct mail_namespace *ns, const char *driver,
+ const char *data, const char *user,
+ enum mail_storage_flags flags,
+ enum file_lock_method lock_method);
void mail_storage_destroy(struct mail_storage **storage);
char mail_storage_get_hierarchy_sep(struct mail_storage *storage);
struct mailbox_list *mail_storage_get_list(struct mail_storage *storage);
+struct mail_namespace *mail_storage_get_namespace(struct mail_storage *storage);
void mail_storage_set_list_error(struct mail_storage *storage);
/* Set storage callback functions to use. */
More information about the dovecot-cvs
mailing list