diff options
Diffstat (limited to 'src/lib-storage/mailbox-list.h')
-rw-r--r-- | src/lib-storage/mailbox-list.h | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/src/lib-storage/mailbox-list.h b/src/lib-storage/mailbox-list.h new file mode 100644 index 0000000..a329896 --- /dev/null +++ b/src/lib-storage/mailbox-list.h @@ -0,0 +1,339 @@ +#ifndef MAILBOX_LIST_H +#define MAILBOX_LIST_H + +#include "mail-error.h" + +#ifdef PATH_MAX +# define MAILBOX_LIST_NAME_MAX_LENGTH PATH_MAX +#else +# define MAILBOX_LIST_NAME_MAX_LENGTH 4096 +#endif + +struct fs; +struct mail_namespace; +struct mail_storage; +struct mailbox_list; + +enum mailbox_list_properties { + /* maildir_name must always be empty */ + MAILBOX_LIST_PROP_NO_MAILDIR_NAME = 0x01, + /* alt directories not supported */ + MAILBOX_LIST_PROP_NO_ALT_DIR = 0x02, + /* no support for \noselect directories, only mailboxes */ + MAILBOX_LIST_PROP_NO_NOSELECT = 0x04, + /* mail root directory isn't required */ + MAILBOX_LIST_PROP_NO_ROOT = 0x08, + /* Automatically create mailbox directories when needed. Normally it's + assumed that if a mailbox directory doesn't exist, the mailbox + doesn't exist either. */ + MAILBOX_LIST_PROP_AUTOCREATE_DIRS = 0x10, + /* Explicitly disable mailbox list index */ + MAILBOX_LIST_PROP_NO_LIST_INDEX = 0x20, + /* Disable checking mailbox_list.is_internal_name(). The layout is + implemented in a way that there aren't any such reserved internal + names. For example Maildir++ prefixes all mailboxes with "." */ + MAILBOX_LIST_PROP_NO_INTERNAL_NAMES = 0x40, +}; + +enum mailbox_list_flags { + /* Mailboxes are files, not directories. */ + MAILBOX_LIST_FLAG_MAILBOX_FILES = 0x01, + /* Namespace already has a mailbox list, don't assign this + mailbox list to it. */ + MAILBOX_LIST_FLAG_SECONDARY = 0x02, + /* There are no mail files, only index and/or control files. */ + MAILBOX_LIST_FLAG_NO_MAIL_FILES = 0x04, + /* LAYOUT=index: Don't delete any files in delete_mailbox(). */ + MAILBOX_LIST_FLAG_NO_DELETES = 0x08 +}; + +enum mailbox_info_flags { + MAILBOX_NOSELECT = 0x001, + MAILBOX_NONEXISTENT = 0x002, + MAILBOX_CHILDREN = 0x004, + MAILBOX_NOCHILDREN = 0x008, + MAILBOX_NOINFERIORS = 0x010, + MAILBOX_MARKED = 0x020, + MAILBOX_UNMARKED = 0x040, + MAILBOX_SUBSCRIBED = 0x080, + MAILBOX_CHILD_SUBSCRIBED = 0x100, + MAILBOX_CHILD_SPECIALUSE = 0x200, + + /* Internally used by lib-storage, use mailbox_info.special_use + to actually access these: */ + MAILBOX_SPECIALUSE_ALL = 0x00010000, + MAILBOX_SPECIALUSE_ARCHIVE = 0x00020000, + MAILBOX_SPECIALUSE_DRAFTS = 0x00040000, + MAILBOX_SPECIALUSE_FLAGGED = 0x00080000, + MAILBOX_SPECIALUSE_JUNK = 0x00100000, + MAILBOX_SPECIALUSE_SENT = 0x00200000, + MAILBOX_SPECIALUSE_TRASH = 0x00400000, + MAILBOX_SPECIALUSE_IMPORTANT = 0x00800000, +#define MAILBOX_SPECIALUSE_MASK 0x00ff0000 + + /* Internally used by lib-storage: */ + MAILBOX_SELECT = 0x20000000, + MAILBOX_MATCHED = 0x40000000 +}; + +enum mailbox_list_path_type { + /* Return directory's path (eg. ~/dbox/INBOX) */ + MAILBOX_LIST_PATH_TYPE_DIR, + MAILBOX_LIST_PATH_TYPE_ALT_DIR, + /* Return mailbox path (eg. ~/dbox/INBOX/dbox-Mails) */ + MAILBOX_LIST_PATH_TYPE_MAILBOX, + MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX, + /* Return control directory */ + MAILBOX_LIST_PATH_TYPE_CONTROL, + /* Return index directory ("" for in-memory) */ + MAILBOX_LIST_PATH_TYPE_INDEX, + /* Return the private index directory (NULL if none) */ + MAILBOX_LIST_PATH_TYPE_INDEX_PRIVATE, + /* Return the index cache directory (usually same as + MAILBOX_LIST_PATH_TYPE_INDEX) */ + MAILBOX_LIST_PATH_TYPE_INDEX_CACHE, + /* Return mailbox list index directory (usually same as + MAILBOX_LIST_PATH_TYPE_INDEX) */ + MAILBOX_LIST_PATH_TYPE_LIST_INDEX, +}; + +enum mailbox_list_file_type { + MAILBOX_LIST_FILE_TYPE_UNKNOWN = 0, + MAILBOX_LIST_FILE_TYPE_FILE, + MAILBOX_LIST_FILE_TYPE_DIR, + MAILBOX_LIST_FILE_TYPE_SYMLINK, + MAILBOX_LIST_FILE_TYPE_OTHER +}; + +struct mailbox_list_settings { + const char *layout; /* FIXME: shouldn't be here */ + const char *root_dir; + const char *index_dir; + const char *index_pvt_dir; + const char *index_cache_dir; + const char *control_dir; + const char *alt_dir; /* FIXME: dbox-specific.. */ + /* Backend-local directory where volatile data, such as lock files, + can be temporarily created. This setting allows specifying a + separate directory for them to reduce disk I/O on the real storage. + The volatile_dir can point to an in-memory filesystem. */ + const char *volatile_dir; + + const char *inbox_path; + const char *subscription_fname; + const char *list_index_fname; + /* Mailbox list index directory. NULL defaults to index directory. + The path may be relative to the index directory. */ + const char *list_index_dir; + /* If non-empty, it means that mails exist in a maildir_name + subdirectory. eg. if you have a directory containing directories: + + mail/ + mail/foo/ + mail/foo/Maildir + + If mailbox_name is empty, you have mailboxes "mail", "mail/foo" and + "mail/foo/Maildir". + + If mailbox_name is "Maildir", you have a non-selectable mailbox + "mail" and a selectable mailbox "mail/foo". */ + const char *maildir_name; + /* if set, store mailboxes under root_dir/mailbox_dir_name/. + this setting contains either "" or "dir/". */ + const char *mailbox_dir_name; + + /* Used for escaping the mailbox name in storage (storage_name). If the + UTF-8 vname has characters that can't reversibly (or safely) be + converted to storage_name and back, encode the problematic parts + using <storage_name_escape_char><hex>. The storage_name_escape_char + itself also has to be encoded the same way. For example + { vname="A/B.C%D", storage_name_escape_char='%', namespace_sep='/', + storage_sep='.' } -> storage_name="A.B%2eC%25D". */ + char storage_name_escape_char; + /* Used for escaping the user/client-visible UTF-8 vname. If the + storage_name can't be converted reversibly to the vname and back, + encode the problematic parts using <vname_escape_char><hex>. The + vname_escape_char itself also has to be encoded the same way. For + example { storage_name="A/B.C%D", vname_escape_char='%', + namespace_sep='/', storage_sep='.' } -> vname="A%2fB/C%25D". + + Note that it's possible for escape_char and broken_char to be the + same character. They're just used for different directions in + conversion. */ + char vname_escape_char; + /* Use UTF-8 mailbox names on filesystem instead of mUTF-7 */ + bool utf8; + /* Don't check/create the alt-dir symlink. */ + bool alt_dir_nocheck; + /* Use maildir_name also for index/control directories. This should + have been the default since the beginning, but for backwards + compatibility it had to be made an option. */ + bool index_control_use_maildir_name; + /* Perform mailbox iteration using the index directory instead of the + mail root directory. This can be helpful if the indexes are on a + faster storage. This could perhaps be made the default at some point, + but for now since it's less tested it's optional. */ + bool iter_from_index_dir; + /* Avoid creating or listing \NoSelect mailboxes. */ + bool no_noselect; + /* Do not validate names as fs names (allows weird names) */ + bool no_fs_validation; +}; + +struct mailbox_permissions { + /* The actual uid/gid of the mailbox */ + uid_t file_uid; + gid_t file_gid; + + /* mode and GID to use for newly created files/dirs. + (gid_t)-1 is used if the default GID can be used. */ + mode_t file_create_mode, dir_create_mode; + gid_t file_create_gid; + /* origin (e.g. path) where the file_create_gid was got from */ + const char *file_create_gid_origin; + + bool gid_origin_is_mailbox_path; + bool mail_index_permissions_set; +}; + +/* register all drivers */ +void mailbox_list_register_all(void); + +void mailbox_list_register(const struct mailbox_list *list); +void mailbox_list_unregister(const struct mailbox_list *list); + +const struct mailbox_list * +mailbox_list_find_class(const char *driver); + +/* Returns 0 if ok, -1 if driver was unknown. */ +int mailbox_list_create(const char *driver, struct mail_namespace *ns, + const struct mailbox_list_settings *set, + enum mailbox_list_flags flags, + struct mailbox_list **list_r, const char **error_r); +void mailbox_list_destroy(struct mailbox_list **list); + +const char * +mailbox_list_get_driver_name(const struct mailbox_list *list) ATTR_PURE; +const struct mailbox_list_settings * +mailbox_list_get_settings(const struct mailbox_list *list) ATTR_PURE; +enum mailbox_list_flags +mailbox_list_get_flags(const struct mailbox_list *list) ATTR_PURE; +struct mail_namespace * +mailbox_list_get_namespace(const struct mailbox_list *list) ATTR_PURE; +struct mail_user * +mailbox_list_get_user(const struct mailbox_list *list) ATTR_PURE; +int mailbox_list_get_storage(struct mailbox_list **list, const char *vname, + struct mail_storage **storage_r); +void mailbox_list_get_default_storage(struct mailbox_list *list, + struct mail_storage **storage); +char mailbox_list_get_hierarchy_sep(struct mailbox_list *list); + +/* Returns the mode and GID that should be used when creating new files and + directories to the specified mailbox. (gid_t)-1 is returned if it's not + necessary to change the default gid. */ +void mailbox_list_get_permissions(struct mailbox_list *list, const char *name, + struct mailbox_permissions *permissions_r); +/* Like mailbox_list_get_permissions(), but for creating files/dirs to the + mail root directory (or even the root dir itself). */ +void mailbox_list_get_root_permissions(struct mailbox_list *list, + struct mailbox_permissions *permissions_r); +/* mkdir() a root directory of given type with proper permissions. The path can + be either the root itself or point to a directory under the root. */ +int mailbox_list_mkdir_root(struct mailbox_list *list, const char *path, + enum mailbox_list_path_type type); +/* Like mailbox_list_mkdir_root(), but don't log an error if it fails. */ +int mailbox_list_try_mkdir_root(struct mailbox_list *list, const char *path, + enum mailbox_list_path_type type, + const char **error_r); +/* Call mailbox_list_mkdir_root() for index, unless the index root is the + same as mailbox root. Returns 1 if ok, 0 if there are no indexes, -1 if + error. Calling this multiple times does the check only once. */ +int mailbox_list_mkdir_missing_index_root(struct mailbox_list *list); +/* Like mailbox_list_mkdir_missing_index_root(), but for mailbox list + index root. */ +int mailbox_list_mkdir_missing_list_index_root(struct mailbox_list *list); + +/* Returns TRUE if name is ok, FALSE if it can't be safely passed to + mailbox_list_*() functions */ +bool mailbox_list_is_valid_name(struct mailbox_list *list, + const char *name, const char **error_r); + +const char *mailbox_list_get_storage_name(struct mailbox_list *list, + const char *vname); +const char *mailbox_list_get_vname(struct mailbox_list *list, const char *name); + +/* Get path to specified type of files in mailbox. Returns -1 if an error + occurred (e.g. mailbox no longer exists), 0 if there are no files of this + type (in-memory index, no alt dir, storage with no files), 1 if path was + returned successfully. The path is set to NULL when returning -1/0. */ +int mailbox_list_get_path(struct mailbox_list *list, const char *name, + enum mailbox_list_path_type type, + const char **path_r); +/* Get path to the root directory for files of specified type. Returns TRUE + if path was returned, FALSE if there are no files of this type. */ +bool mailbox_list_get_root_path(struct mailbox_list *list, + enum mailbox_list_path_type type, + const char **path_r); +/* Like mailbox_list_get_root_path(), but assume that the root directory + exists (assert crash if not) */ +const char *mailbox_list_get_root_forced(struct mailbox_list *list, + enum mailbox_list_path_type type); +/* Returns mailbox's change log, or NULL if it doesn't have one. */ +struct mailbox_log *mailbox_list_get_changelog(struct mailbox_list *list); +/* Specify timestamp to use when writing mailbox changes to changelog. + The same timestamp is used until stamp is set to (time_t)-1, after which + current time is used */ +void mailbox_list_set_changelog_timestamp(struct mailbox_list *list, + time_t stamp); + +/* Returns a prefix that temporary files should use without conflicting + with the namespace. */ +const char *mailbox_list_get_temp_prefix(struct mailbox_list *list); +/* Returns prefix that's common to all get_temp_prefix() calls. + Typically this returns either "temp." or ".temp.". */ +const char *mailbox_list_get_global_temp_prefix(struct mailbox_list *list); + +/* Subscribe/unsubscribe mailbox. There should be no error when + subscribing to already subscribed mailbox. Subscribing to + unexisting mailboxes is optional. */ +int mailbox_list_set_subscribed(struct mailbox_list *list, + const char *name, bool set); + +/* Delete a non-selectable mailbox. Fail if the mailbox is selectable. */ +int mailbox_list_delete_dir(struct mailbox_list *list, const char *name); +/* Delete a symlinked mailbox. Fail if the mailbox isn't a symlink. */ +int mailbox_list_delete_symlink(struct mailbox_list *list, const char *name); + +/* Returns the error message of last occurred error. */ +const char * ATTR_NOWARN_UNUSED_RESULT +mailbox_list_get_last_error(struct mailbox_list *list, + enum mail_error *error_r); +/* Wrapper for mailbox_list_get_last_error() */ +enum mail_error mailbox_list_get_last_mail_error(struct mailbox_list *list); + +const char * ATTR_NOWARN_UNUSED_RESULT +mailbox_list_get_last_internal_error(struct mailbox_list *list, + enum mail_error *error_r); + +/* Save the last error until it's popped. This is useful for cases where the + list operation has already failed, but the cleanup code path changes the + error to something else unwanted. */ +void mailbox_list_last_error_push(struct mailbox_list *list); +void mailbox_list_last_error_pop(struct mailbox_list *list); + +/* Create a fs based on the settings in the given mailbox_list. If event_parent + is NULL, use user->event as the parent. */ +int mailbox_list_init_fs(struct mailbox_list *list, struct event *event_parent, + const char *driver, + const char *args, const char *root_dir, + struct fs **fs_r, const char **error_r); +/* Return mailbox_list that was used to create the fs via + mailbox_list_init_fs(). */ +struct mailbox_list *mailbox_list_fs_get_list(struct fs *fs); + +/* Escape/Unescape mailbox name in place. */ +void mailbox_list_name_unescape(const char **name, char escape_char); +void mailbox_list_name_escape(const char *name, const char *escape_chars, + string_t *dest); + +#endif |