mail-storage.c revision d27fd02d50643362e6299bdc2fdafcaa8539ff04
/* append it after the list, so the autodetection order is correct */ for (i = 0; i <
count; i++) {
for (i = 0; i <
count; i++) {
for (i = 0; i <
count; i++) {
/* check if data is in driver:data format (eg. mbox:~/mail) */ if (*p ==
':' && p != *
data) {
/* no autodetection if the storage driver is given. */ /* no mail_location, autodetect */ /* explicit autodetection with "auto" driver. */ /* handle the same as with driver=NULL */ "Unknown mail storage driver %s",
driver);
/* no root directory given. is this allowed? */ /* autodetection should take care of this */ /* root not required for this storage */ /* root not required for this layout */ *
error_r =
"Root mail directory not given";
"Mail storage autodetection failed with home=%s",
home);
"Autodetection failed for %s (home=%s)",
"Ambiguous mail location setting, " "don't know what to do with it: %s " "(try prefixing it with mbox: or maildir:)",
"Root mail directory is a file: %s",
root_dir);
/* storage doesn't use directories (e.g. shared root) */ /* we don't need to verify, but since debugging is enabled, check and log if the root doesn't exist */ i_debug(
"Namespace %s: Creating storage despite: %s",
/* If the directories don't exist, we'll just autocreate them /* allow multiple independent shared namespaces */ /* if pop3_uidl_format contains %m, we want to keep the header MD5 sums stored even if we're not running POP3 /* internal shared namespace */ /* first storage for namespace */ /* using an existing storage */ /* set *_storage=NULL only after calling destroy() callback. for example mdbox wants to access ns->storage */ i_panic(
"Trying to deinit storage without freeing mailbox %s",
i_panic(
"Trying to deinit storage before freeing its objects");
/* this function doesn't set last_internal_error, so last_error_is_internal can't be TRUE. */ /* critical errors may contain sensitive data, so let user see only "Internal error" with a timestamp to make it easier to look from log files the actual error message. */ /* free the old_error and old_internal_error only after the new error is generated, because they may be one of the parameters. */ /* use the lib-index's error as our internal error string */ /* We get here only in error situations, so we have to return some error. If storage->error is NONE, it means we forgot to set it at "BUG: Unknown internal error";
/* This shouldn't happen.. */ /* debugging is enabled - admin may be debugging a (permission) problem, so return FALSE to get the caller to log the full error message. */ /* namespace prefix itself */ /* make sure INBOX shows up in uppercase everywhere. do this regardless of whether we're in inbox=yes namespace, because clients expect INBOX to be case insensitive regardless of server's internal configuration. */ "Invalid server configuration: " "Namespace prefix=%s must be uppercase INBOX",
/* do a delayed failure at mailbox_open() */ /* GUID mismatch, refresh cache and try again */ /* successfully opened the correct mailbox */ "Couldn't verify mailbox GUID: %s",
/* delivering to a namespace prefix means we actually want to deliver to the INBOX instead */ /* deliveries to INBOX must always succeed, "Failed to autocreate mailbox: %s",
"Failed to autosubscribe to mailbox: %s",
"Opening INBOX failed: %s",
/* Make sure the vname doesn't have extra separators: 1) Must not have adjacent separators. If we allow these, these could end up pointing to existing mailboxes due to kernel ignoring duplicate '/' in paths. However, this might cause us to handle some of our own checks wrong, such as skipping ACLs. 2) Must not end with separator. Similar reasoning as above. for (i = 0;
vname[i] !=
'\0'; i++) {
*
error_r =
"Has adjacent hierarchy separators";
*
error_r =
"Ends with hierarchy separator";
/* this is INBOX - don't bother with further checks */ /* User input shouldn't normally be able to get us in here. The main reason this isn't an assert is to allow any input at all to mailbox_verify_*_name() "Missing namespace prefix '%s'",
/* "namespace/" isn't a valid mailbox name. */ /* If namespace { separator } differs from the mailbox_list separator, the list separator can't actually be used in the mailbox name unless it's escaped with escape_char. For example if namespace separator is '/' and LAYOUT=Maildir++ has '.' as the separator, there's no way to use '.' in the mailbox name (without escaping) because it would end up becoming a hierarchy separator. */ "Character not allowed in mailbox name: '%c'",
list_sep));
/* vname must not begin with the hierarchy separator normally. For example we don't want to allow accessing /etc/passwd. However, if mail_full_filesystem_access=yes, we do actually want to allow "Invalid mailbox name: Begins with hierarchy separator");
/* Make sure box->_path is set, so mailbox_get_path() works from now on. Note that this may also fail with some backends if the mailbox doesn't exist. */ /* if this is an autocreated mailbox, create it now */ for (p =
name; *p !=
'\0'; p++) {
if ((
unsigned char)*p <
' ')
/* mailbox_alloc() already checks that vname is valid UTF8, so we don't need to verify that. check vname instead of storage name, because vname is what is visible to users, while storage name may be a fixed length GUID. */ "Control characters not allowed in new mailbox names");
"Mailbox name too long");
/* check individual component names, too */ "Mailbox name too long");
"Mailbox name too long");
/* if prefix has multiple hierarchies, match any of the hierarchies */ /* unsure if this exists or not */ /* the mailbox name is invalid. we don't know if it currently exists or not, but since it can never be accessed in any way report it as if it didn't exist. */ /* listable namespace prefix always exists. */ /* if this is a shared namespace with only INBOX and mail_shared_explicit_inbox=no, we'll need to mark the namespace as usable here since nothing else will. */ i_debug(
"%s: Mailbox opened because: %s",
"Storage doesn't support streamed mailboxes");
/* most importantly we don't do this because we want to avoid a loop: mdbox storage rebuild -> mailbox_open() -> mailbox_mark_index_deleted() -> mailbox_sync() -> mdbox storage rebuild. */ /* check that the storage supports stubs if require them */ "Mailbox does not support mail stubs");
/* mailbox has been marked as deleted. if this deletion started (and crashed) a long time ago, it can be confusing to user that the mailbox can't be opened. so we'll just undelete it and reopen. */ /* make sure we close the mailbox in the middle. some backends may not have fully opened the mailbox while it was being return ret;
/* error / no private indexes */ i_panic(
"Trying to close mailbox %s with open transactions",
i_panic(
"Trying to free mailbox %s with %u open attribute iterators",
/* this should be NoSelect but since inbox can never be NoSelect we use EXISTENCE_NONE to avoid creating inbox by accident */ /* we can't do much about errors here */ /* Avoid race conditions by keeping mailbox list locked during changes. This especially fixes a race during INBOX creation with LAYOUT=index because it scans for missing mailboxes if INBOX doesn't exist. The second process's scan can find a half-created INBOX and add it, causing the first process to become confused. */ /* Creation failed after (partially) opening the mailbox. It may not be in a valid state, so close it. */ /* we already marked it deleted. this allows plugins to "lock" the deletion earlier. */ /* sync the mailbox. this finishes the index deletion and it can succeed only for a single session. we do it here, so the rest of the deletion code doesn't have to worry about race "Storage root can't be deleted");
/* might be a \noselect mailbox, so continue deletion */ /* deletion failed. revert the mark so it can maybe be /* if mailbox is reopened, its path may be different with /* FIXME: should be a parameter to delete(), but since it changes API /* e.g. mdbox where all mails are in storage/ directory and they can't be easily moved from there. */ /* this can return folders with * in their name, that are not continue;
/* not our child */ /* if total length of new name exceeds the limit, fail */ "Mailbox or child name too long");
/* Check only name validity, \Noselect don't necessarily exist. */ "Can't rename mailbox root");
i_debug(
"Can't rename '%s' to '%s': %s",
"Can't rename mailboxes across specified storages.");
"Renaming not supported across non-private namespaces.");
"Can't rename mailbox to itself.");
/* It would be safer to lock both source and destination, but that could lead to deadlocks. So at least for now lets just lock only the i_panic(
"Trying to sync mailbox %s with open transactions",
/* we don't care about mailbox's current state, so we might as well fix inconsistency state */ /* Store changes temporarily so that plugins overriding transaction_commit() can look at them. */ /* either all the saved messages get UIDs or none, because a) we failed, b) MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS not set, c) backend doesn't support it (e.g. virtual plugin) */ /* decrease the transaction count only after transaction_commit(). that way if it creates and destroys transactions internally, we don't see transaction_count=0 until the parent transaction is fully /* Always have a dest_mail available. A lot of plugins make use /* make sure the mail isn't used before mail_set_seq_saving() */ /* make sure parts get parsed early on */ i_panic(
"Trying to fill in stub for nonexistent UID %u",
uid);
/* if we're filling in a stub, we must have set UID already (which in turn sets stub_seq) */ /* We're actually saving the mail. We're not being called by mail_storage_copy() because backend didn't support fast "Saving messages not supported");
/* we're finishing a save (not copy/move). Note that we could have come here also from mailbox_save_cancel(), in which case ctx->saving may be FALSE. */ /* We came from mailbox_copy(). saving==TRUE is possible here if we also came from mailbox_save_using_mail(). Don't set saving=FALSE yet in that case, because copy() is still /* we need to keep a copy of this because save_finish implementations will likely zero the data structure during cleanup */ /* Do one final continue. The caller may not have done it if the input stream's offset already matched the number of bytes that were wanted to be saved. But due to nested istreams some of the underlying ones may not have seen the EOF yet, and haven't flushed /* the dest_mail is no longer valid. if we're still saving more mails, the mail sequence may get reused. make sure the mail gets reset in between */ /* bypass virtual storage, so hard linking can be used whenever "Mailbox was deleted under us");
/* O_EXCL used, caller will handle this error */ "Mailbox doesn't allow inferior mailboxes");
"fchown(%s) failed: %m",
path);
/* mailbox root directory doesn't exist, create it */ "Mailbox doesn't allow inferior mailboxes");
/* Mailbox directory is different - create a missing dir */ /* This layout (e.g. imapc) wants to autocreate missing mailbox /* If the mailbox directory doesn't exist, the mailbox shouldn't exist at all. So just assume that it's already created and if there's a race condition just fail later. */ /* we call this function even when the directory exists, so first do a quick check to see if we need to mkdir anything */ /* Race condition - mail root directory doesn't exist anymore either. We shouldn't create this directory (
str[
2]-
'0') *
10 + (
str[
3]-
'0') -
1900;
/* update also the storage's internal error */ /* Keep this simple: Use the lock_fname with a SHA1 of the mailbox name as the suffix. The mailbox name itself could be too large as a filename and creating the full directory structure would be pretty troublesome. It would also make it more difficult to perform the automated deletion of empty