dbox-storage.c revision b811d88426068f2b959642e20348bfeeb9a6356d
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2005 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#include "home-expand.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mkdir-parents.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "unlink-directory.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "subscription-file/subscription-file.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-copy.h"
abf015c9682f0f723db87a7c97bc284ef814818fTimo Sirainen#include "index-mail.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "dbox-uidlist.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "dbox-sync.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "dbox-file.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "dbox-storage.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdio.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdlib.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <unistd.h>
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen#include <sys/stat.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define CREATE_MODE 0770 /* umask() should limit it more */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Don't allow creating too long mailbox names. They could start causing
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen problems when they reach the limit. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define DBOX_MAX_MAILBOX_NAME_LENGTH (PATH_MAX/2)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenextern struct mail_storage dbox_storage;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenextern struct mailbox dbox_mailbox;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenstatic bool dbox_handle_errors(struct index_storage *istorage)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen{
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen struct mail_storage *storage = &istorage->storage;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (ENOACCESS(errno))
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen mail_storage_set_error(storage, MAIL_STORAGE_ERR_NO_PERMISSION);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen else if (ENOSPACE(errno))
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen mail_storage_set_error(storage, "Not enough disk space");
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen else if (ENOTFOUND(errno))
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen mail_storage_set_error(storage, "Directory structure is broken");
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen else
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return FALSE;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return TRUE;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic struct mail_storage *
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainendbox_create(const char *data, const char *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen enum mail_storage_flags flags,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen enum mail_storage_lock_method lock_method)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct dbox_storage *storage;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct index_storage *istorage;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *root_dir, *index_dir, *p;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen size_t len;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen pool_t pool;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen root_dir = index_dir = NULL;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (data == NULL || *data == '\0') {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we won't do any guessing for this format. */
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (debug)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen i_info("dbox: mailbox location not given");
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen return NULL;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* <root dir> [:INDEX=<dir>] */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (debug)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_info("dbox: data=%s", data);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen p = strchr(data, ':');
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen if (p == NULL)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen root_dir = data;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen else {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen root_dir = t_strdup_until(data, p);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen do {
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen p++;
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen if (strncmp(p, "INDEX=", 6) == 0)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen index_dir = t_strcut(p+6, ':');
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen p = strchr(p, ':');
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen } while (p != NULL);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen }
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen /* strip trailing '/' */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen len = strlen(root_dir);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (root_dir[len-1] == '/')
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen root_dir = t_strndup(root_dir, len-1);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (index_dir == NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen index_dir = root_dir;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen else if (strcmp(index_dir, "MEMORY") == 0)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen index_dir = NULL;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (debug) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_info("dbox: root=%s, index=%s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen root_dir, index_dir == NULL ? "" : index_dir);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen root_dir = home_expand(root_dir);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mkdir_parents(root_dir, CREATE_MODE) < 0 && errno != EEXIST) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_error("mkdir_parents(%s) failed: %m", root_dir);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen pool = pool_alloconly_create("storage", 512);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen storage = p_new(pool, struct dbox_storage, 1);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen istorage = INDEX_STORAGE(storage);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen istorage->storage = dbox_storage;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen istorage->storage.pool = pool;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen istorage->dir = p_strdup(pool, root_dir);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen istorage->index_dir = p_strdup(pool, home_expand(index_dir));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen istorage->user = p_strdup(pool, user);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen istorage->callbacks = p_new(pool, struct mail_storage_callbacks, 1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_storage_init(istorage, flags, lock_method);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return STORAGE(storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void dbox_free(struct mail_storage *_storage)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct index_storage *storage = (struct index_storage *) _storage;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen index_storage_deinit(storage);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen pool_unref(storage->storage.pool);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen}
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic bool dbox_autodetect(const char *data, enum mail_storage_flags flags)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct stat st;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *path;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen data = t_strcut(data, ':');
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen path = t_strconcat(data, "/inbox/"DBOX_MAILDIR_NAME, NULL);
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen if (stat(path, &st) < 0) {
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen if (debug)
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen i_info("dbox autodetect: stat(%s) failed: %m", path);
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen return FALSE;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!S_ISDIR(st.st_mode)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (debug)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_info("dbox autodetect: %s not a directory", path);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return FALSE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return TRUE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenbool dbox_is_valid_mask(struct mail_storage *storage, const char *mask)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *p;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen bool newdir;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return TRUE;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen /* make sure it's not absolute path */
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (*mask == '/' || *mask == '~')
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen return FALSE;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen /* make sure the mailbox name doesn't contain any foolishness:
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen "../" could give access outside the mailbox directory.
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen "./" and "//" could fool ACL checks. */
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen newdir = TRUE;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen for (p = mask; *p != '\0'; p++) {
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen if (newdir) {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (p[0] == '/')
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen return FALSE; /* // */
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (p[0] == '.') {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (p[1] == '/')
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen return FALSE; /* ./ */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (p[1] == '.' && p[2] == '/')
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return FALSE; /* ../ */
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen }
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen if (strncmp(p, DBOX_MAILDIR_NAME,
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen sizeof(DBOX_MAILDIR_NAME)-1) == 0 &&
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen (p[sizeof(DBOX_MAILDIR_NAME)-1] == '\0' ||
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen p[sizeof(DBOX_MAILDIR_NAME)-1] == '/')) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* don't allow the dbox-Mails directory to be
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen used as part of the mask */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return FALSE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen newdir = p[0] == '/';
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mask[0] == '.' && (mask[1] == '\0' ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (mask[1] == '.' && mask[2] == '\0'))) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* "." and ".." aren't allowed. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool dbox_is_valid_create_name(struct mail_storage *storage,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen size_t len;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen len = strlen(name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (name[0] == '\0' || name[len-1] == '/' ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen len > DBOX_MAX_MAILBOX_NAME_LENGTH)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mailbox_name_is_too_large(name, '/'))
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return FALSE;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return dbox_is_valid_mask(storage, name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainenstatic bool dbox_is_valid_existing_name(struct mail_storage *storage,
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen size_t len;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen len = strlen(name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (name[0] == '\0' || name[len-1] == '/')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return dbox_is_valid_mask(storage, name);
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const char *
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainendbox_get_path(struct index_storage *storage, const char *name)
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 &&
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen (*name == '/' || *name == '~'))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return home_expand(name);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen return t_strconcat(storage->dir, "/", name, NULL);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen}
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainenstatic int create_dbox(struct index_storage *storage, const char *dir)
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen{
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen const char *path;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen path = t_strconcat(dir, "/", DBOX_MAILDIR_NAME, NULL);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
e30b9e07f9657c35ca09ac36d57d60cbe2ebbc66Timo Sirainen if (dbox_handle_errors(storage))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen mail_storage_set_critical(&storage->storage,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "mkdir(%s) failed: %m", dir);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int create_index_dir(struct index_storage *storage, const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *dir;
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (storage->index_dir == NULL)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return 0;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (strcmp(storage->index_dir, storage->dir) == 0)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen return 0;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen dir = t_strconcat(storage->index_dir, "/", name,
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen "/"DBOX_MAILDIR_NAME, NULL);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (mkdir_parents(dir, CREATE_MODE) < 0 && errno != EEXIST) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen mail_storage_set_critical(&storage->storage,
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen "mkdir(%s) failed: %m", dir);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen return -1;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return 0;
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen}
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainenstatic bool dbox_is_recent(struct index_mailbox *ibox __attr_unused__,
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen uint32_t uid __attr_unused__)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic const char *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainendbox_get_index_dir(struct index_storage *storage, const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (storage->index_dir == NULL)
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen return NULL;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if ((storage->storage.flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0 &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (*name == '/' || *name == '~')) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen name = home_expand(name);
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen p = strrchr(name, '/');
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return t_strconcat(t_strdup_until(name, p),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "/"DBOX_MAILDIR_NAME"/", p+1, NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return t_strconcat(storage->index_dir,
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen "/", name, "/"DBOX_MAILDIR_NAME, NULL);
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen}
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainen
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainenstatic const char *
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainendbox_get_mailbox_path(struct mail_storage *_storage,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char *name, bool *is_file_r)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *is_file_r = FALSE;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (*name == '\0')
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return istorage->dir;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return dbox_get_path(istorage, name);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainenstatic const char *
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainendbox_get_mailbox_control_dir(struct mail_storage *_storage, const char *name)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen{
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return dbox_get_path(istorage, name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic const char *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainendbox_get_mailbox_index_dir(struct mail_storage *_storage, const char *name)
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return dbox_get_index_dir(istorage, name);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen}
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic struct mailbox *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainendbox_open(struct dbox_storage *storage, const char *name,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen enum mailbox_open_flags flags)
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen{
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct dbox_mailbox *mbox;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct mail_index *index;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen const char *path, *index_dir, *value;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen pool_t pool;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen path = dbox_get_path(istorage, name);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen index_dir = dbox_get_index_dir(istorage, name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (create_dbox(istorage, path) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return NULL;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (create_index_dir(istorage, name) < 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen return NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen index = index_storage_alloc(index_dir, path, DBOX_INDEX_PREFIX);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen pool = pool_alloconly_create("mailbox", 1024);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mbox = p_new(pool, struct dbox_mailbox, 1);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mbox->ibox.box = dbox_mailbox;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mbox->ibox.box.pool = pool;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mbox->ibox.storage = istorage;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mbox->ibox.mail_vfuncs = &dbox_mail_vfuncs;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mbox->ibox.is_recent = dbox_is_recent;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (index_storage_mailbox_init(&mbox->ibox, index, name, flags,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen FALSE) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* the memory was already freed */
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen value = getenv("DBOX_ROTATE_SIZE");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (value != NULL)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->rotate_size = (uoff_t)strtoul(value, NULL, 10) * 1024;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen else
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->rotate_size = DBOX_DEFAULT_ROTATE_SIZE;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen value = getenv("DBOX_ROTATE_MIN_SIZE");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (value != NULL)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->rotate_min_size = (uoff_t)strtoul(value, NULL, 10) * 1024;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen else
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->rotate_min_size = DBOX_DEFAULT_ROTATE_MIN_SIZE;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen value = getenv("DBOX_ROTATE_DAYS");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (value != NULL)
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen mbox->rotate_days = (unsigned int)strtoul(value, NULL, 10);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen else
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->rotate_days = DBOX_DEFAULT_ROTATE_DAYS;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->storage = storage;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->path = p_strdup(pool, path);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->dbox_file_ext_idx =
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_index_ext_register(index, "dbox-seq", 0,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen sizeof(uint32_t), sizeof(uint32_t));
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->dbox_offset_ext_idx =
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_index_ext_register(index, "dbox-off", 0,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen sizeof(uint64_t), sizeof(uint64_t));
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mbox->uidlist = dbox_uidlist_init(mbox);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (mbox->ibox.keep_locked) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (dbox_uidlist_lock(mbox->uidlist) < 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mailbox *box = &mbox->ibox.box;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen mailbox_close(&box);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen return &mbox->ibox.box;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen}
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainenstatic struct mailbox *
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainendbox_mailbox_open(struct mail_storage *_storage, const char *name,
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct istream *input, enum mailbox_open_flags flags)
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen{
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen const char *path;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct stat st;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_clear_error(_storage);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (input != NULL) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_critical(_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen "dbox doesn't support streamed mailboxes");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (strcmp(name, "INBOX") == 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return dbox_open(storage, "INBOX", flags);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!dbox_is_valid_existing_name(_storage, name)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage, "Invalid mailbox name");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen path = dbox_get_path(istorage, name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (stat(path, &st) == 0) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return dbox_open(storage, name, flags);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen } else if (errno == ENOENT) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_critical(_storage, "stat(%s) failed: %m",
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen path);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic int dbox_mailbox_create(struct mail_storage *_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *name,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen bool directory __attr_unused__)
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen{
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *path, *mail_path;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct stat st;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen mail_storage_clear_error(_storage);
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!dbox_is_valid_create_name(_storage, name)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen mail_storage_set_error(_storage, "Invalid mailbox name");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen path = dbox_get_path(istorage, name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_path = t_strconcat(path, "/", DBOX_MAILDIR_NAME, NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (stat(mail_path, &st) == 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage, "Mailbox already exists");
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return create_dbox(istorage, path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainenstatic int dbox_mailbox_delete(struct mail_storage *_storage,
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen const char *name)
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen struct index_storage *istorage = INDEX_STORAGE(storage);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *path, *mail_path;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct stat st;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_clear_error(_storage);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (strcmp(name, "INBOX") == 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage, "INBOX can't be deleted.");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!dbox_is_valid_existing_name(_storage, name)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage, "Invalid mailbox name");
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen path = dbox_get_path(istorage, name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_path = t_strconcat(path, "/", DBOX_MAILDIR_NAME, NULL);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (stat(mail_path, &st) < 0 && ENOTFOUND(errno)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (stat(path, &st) < 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen /* exists as a \NoSelect mailbox */
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (rmdir(path) == 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return 0;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (errno == ENOTEMPTY) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen "Mailbox has only submailboxes: %s", name);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen } else {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_critical(_storage,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen "rmdir() failed for %s: %m", path);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
7f472e15b5f19a3536634863950c80a88079da23Timo Sirainen
7f472e15b5f19a3536634863950c80a88079da23Timo Sirainen /* make sure the indexes are closed before trying to delete the
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen directory that contains them */
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen index_storage_destroy_unrefed();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlink_directory(mail_path, TRUE) < 0) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (!dbox_handle_errors(istorage)) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mail_storage_set_critical(_storage,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "unlink_directory() failed for %s: %m",
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen mail_path);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen /* try also removing the root directory. it can fail if the deleted
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen mailbox had submailboxes. do it as long as we can. */
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen while (rmdir(path) == 0) {
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen const char *p = strrchr(name, '/');
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (p == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen break;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen name = t_strdup_until(name, p);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen path = dbox_get_path(istorage, name);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen return 0;
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen}
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainenstatic int dbox_mailbox_rename(struct mail_storage *_storage,
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen const char *oldname, const char *newname)
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen{
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen struct index_storage *storage = (struct index_storage *)_storage;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen const char *oldpath, *newpath, *p;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen struct stat st;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_clear_error(_storage);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen if (!dbox_is_valid_existing_name(_storage, oldname) ||
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen !dbox_is_valid_create_name(_storage, newname)) {
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen mail_storage_set_error(_storage, "Invalid mailbox name");
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen return -1;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen oldpath = dbox_get_path(storage, oldname);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen newpath = dbox_get_path(storage, newname);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen /* create the hierarchy */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p = strrchr(newpath, '/');
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (p != NULL) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen p = t_strdup_until(newpath, p);
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (mkdir_parents(p, CREATE_MODE) < 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (dbox_handle_errors(storage))
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen return -1;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen mail_storage_set_critical(_storage,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen "mkdir_parents(%s) failed: %m", p);
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* first check that the destination mailbox doesn't exist.
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen this is racy, but we need to be atomic and there's hardly any
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen possibility that someone actually tries to rename two mailboxes
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen to same new one */
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen if (lstat(newpath, &st) == 0) {
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen mail_storage_set_error(_storage,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen "Target mailbox already exists");
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else if (errno == ENOTDIR) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_set_error(_storage,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Target mailbox doesn't allow inferior mailboxes");
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else if (errno != ENOENT && errno != EACCES) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_set_critical(_storage, "lstat(%s) failed: %m",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen newpath);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return -1;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen /* NOTE: renaming INBOX works just fine with us, it's simply recreated
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen the next time it's needed. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (rename(oldpath, newpath) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (ENOTFOUND(errno)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_set_error(_storage,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, oldname);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else if (!dbox_handle_errors(storage)) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_storage_set_critical(_storage,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen "rename(%s, %s) failed: %m", oldpath, newpath);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return 0;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen}
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int dbox_set_subscribed(struct mail_storage *_storage,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen const char *name, bool set)
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen{
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen const char *path;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen path = t_strconcat(INDEX_STORAGE(storage)->dir,
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen "/"DBOX_SUBSCRIPTION_FILE_NAME, NULL);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen return subsfile_set_subscribed(_storage, path,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen INDEX_STORAGE(storage)->temp_prefix,
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen name, set);
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen}
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainenstatic int dbox_get_mailbox_name_status(struct mail_storage *_storage,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen const char *name,
02a6291366caff79793db35d479e2a062bec2af4Timo Sirainen enum mailbox_name_status *status)
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen{
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen struct index_storage *storage = (struct index_storage *)_storage;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen struct stat st;
573085b4b25b0bbae8d27969df2c91702eefa23eTimo Sirainen const char *path, *mail_path;
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen mail_storage_clear_error(_storage);
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen if (!dbox_is_valid_existing_name(_storage, name)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *status = MAILBOX_NAME_INVALID;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen path = dbox_get_path(storage, name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_path = t_strconcat(path, "/", DBOX_MAILDIR_NAME, NULL);
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen if (strcmp(name, "INBOX") == 0 || stat(mail_path, &st) == 0) {
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen *status = MAILBOX_NAME_EXISTS;
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen return 0;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen }
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen if (!dbox_is_valid_create_name(_storage, name)) {
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen *status = MAILBOX_NAME_INVALID;
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (errno == ENOENT) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *status = MAILBOX_NAME_VALID;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen } else {
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen mail_storage_set_critical(_storage, "stat(%s) failed: %m",
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen path);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen return -1;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen }
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen}
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainenstatic int dbox_storage_close(struct mailbox *box)
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen{
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen if (mbox->ibox.keep_locked)
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen dbox_uidlist_unlock(mbox->uidlist);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen dbox_uidlist_deinit(mbox->uidlist);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen if (mbox->file != NULL)
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen dbox_file_close(mbox->file);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen index_storage_mailbox_free(box);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return 0;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen}
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainendbox_notify_changes(struct mailbox *box, unsigned int min_interval,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen mailbox_notify_callback_t *callback, void *context)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen mbox->ibox.min_notify_interval = min_interval;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen mbox->ibox.notify_callback = callback;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen mbox->ibox.notify_context = context;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen if (callback == NULL) {
8abe071cb14a622b9d84b00a9269f96d01a576f6Timo Sirainen index_mailbox_check_remove_all(&mbox->ibox);
8abe071cb14a622b9d84b00a9269f96d01a576f6Timo Sirainen return;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen }
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen index_mailbox_check_add(&mbox->ibox,
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen t_strconcat(mbox->path, "/"DBOX_MAILDIR_NAME, NULL));
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen}
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void dbox_class_init(void)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen{
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_transaction_class_init();
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen}
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenstatic void dbox_class_deinit(void)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen{
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_transaction_class_deinit();
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen}
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenstruct mail_storage dbox_storage = {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen MEMBER(name) DBOX_STORAGE_NAME,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen MEMBER(hierarchy_sep) '/',
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_class_init,
0992011130e9d0a498ca860ddbe4028398a530c5Timo Sirainen dbox_class_deinit,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_create,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_free,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_autodetect,
0992011130e9d0a498ca860ddbe4028398a530c5Timo Sirainen index_storage_set_callbacks,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_get_mailbox_path,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_get_mailbox_control_dir,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_get_mailbox_index_dir,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_open,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_create,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_delete,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_rename,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_list_init,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_list_next,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_mailbox_list_deinit,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_set_subscribed,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dbox_get_mailbox_name_status,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_storage_get_last_error
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen};
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct mailbox dbox_mailbox = {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen MEMBER(name) NULL,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen MEMBER(storage) NULL,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_storage_is_readonly,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen index_storage_allow_new_keywords,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen dbox_storage_close,
f934b271c69c7b3e5e3bca23ff9b3ab6187262c2Timo Sirainen index_storage_get_status,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dbox_storage_sync_init,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_mailbox_sync_next,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_mailbox_sync_deinit,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen dbox_notify_changes,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen index_transaction_begin,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen index_transaction_commit,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen index_transaction_rollback,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_keywords_create,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_keywords_free,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_storage_get_uids,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_mail_alloc,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_header_lookup_init,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_header_lookup_deinit,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_storage_search_init,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen index_storage_search_deinit,
878a83a906e1be6354b563ead096955a22ad5fbeTimo Sirainen index_storage_search_next,
878a83a906e1be6354b563ead096955a22ad5fbeTimo Sirainen index_storage_search_next_update_seq,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dbox_save_init,
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen dbox_save_continue,
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen dbox_save_finish,
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen dbox_save_cancel,
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen mail_storage_copy,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_storage_is_inconsistent
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen};
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen