static void acl_mailbox_fail_not_found(struct mailbox *box) { int ret; ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP); if (ret > 0) { mail_storage_set_error(box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); } else if (ret == 0) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); } }
static int pop3c_mail_get_received_date(struct mail *_mail, time_t *date_r) { mail_storage_set_error(_mail->box->storage, MAIL_ERROR_NOTPOSSIBLE, "POP3 has no received date"); *date_r = (time_t)-1; return -1; }
static int do_hardlink(struct maildir_mailbox *mbox, const char *path, struct hardlink_ctx *ctx) { int ret; if (mbox->storage->storage.set->mail_nfs_storage) ret = nfs_safe_link(path, ctx->dest_path, FALSE); else ret = link(path, ctx->dest_path); if (ret < 0) { if (errno == ENOENT) return 0; if (ENOQUOTA(errno)) { mail_storage_set_error(&mbox->storage->storage, MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA); return -1; } /* we could handle the EEXIST condition by changing the filename, but it practically never happens so just fallback to standard copying for the rare cases when it does. */ if (errno == EACCES || ECANTLINK(errno) || errno == EEXIST) return 1; mail_storage_set_critical(&mbox->storage->storage, "link(%s, %s) failed: %m", path, ctx->dest_path); return -1; } ctx->success = TRUE; return 1; }
int tfsignature_extract(struct mailbox_transaction_context *t, struct mail *mail, const char **signature) { const char *const *signatures; signatures = get_mail_headers(mail, tfsignature_hdr); if (!signatures || !signatures[0]) { if (!tfsignature_nosig_ignore) { mail_storage_set_error(t->box->storage, ME(NOTPOSSIBLE) "antispam signature not found"); return -1; } else { *signature = NULL; return 0; } } while (signatures[1]) signatures++; *signature = signatures[0]; return 0; }
static int acl_have_attribute_rights(struct mailbox *box) { int ret; /* RFC 5464: When the ACL extension [RFC4314] is present, users can only set and retrieve private or shared mailbox annotations on a mailbox on which they have the "l" right and any one of the "r", "s", "w", "i", or "p" rights. */ ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP); if (ret <= 0) { if (ret < 0) return -1; mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname)); return -1; } if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_READ) > 0) return 0; if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) > 0) return 0; if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0) return 0; if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_INSERT) > 0) return 0; if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_POST) > 0) return 0; return -1; }
static int sieve_attribute_set_default(struct mail_storage *storage, struct sieve_storage *svstorage, const struct mail_attribute_value *value) { const unsigned char *data; size_t size; ssize_t ret; char type; if (value->value != NULL) { type = value->value[0]; } else if (value->value_stream != NULL) { ret = i_stream_read_data(value->value_stream, &data, &size, 0); if (ret == -1) { mail_storage_set_critical(storage, "read(%s) failed: %m", i_stream_get_name(value->value_stream)); return -1; } i_assert(ret > 0); type = data[0]; } else { type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT; } if (type == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK) return sieve_attribute_set_active(storage, svstorage, value); if (type == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT) return sieve_attribute_set_active_script(storage, svstorage, value); mail_storage_set_error(storage, MAIL_ERROR_PARAMS, "Invalid value for default sieve attribute"); return -1; }
static int fts_transaction_commit(struct mailbox_transaction_context *t, struct mail_transaction_commit_changes *changes_r) { struct fts_transaction_context *ft = FTS_CONTEXT(t); struct fts_mailbox *fbox = FTS_CONTEXT(t->box); struct mailbox *box = t->box; bool autoindex; int ret = 0; autoindex = ft->mails_saved && mail_user_plugin_getenv(box->storage->user, "fts_autoindex") != NULL; if (fts_transaction_end(t) < 0) { mail_storage_set_error(t->box->storage, MAIL_ERROR_TEMP, "FTS transaction commit failed"); ret = -1; } if (fbox->module_ctx.super.transaction_commit(t, changes_r) < 0) ret = -1; if (ret < 0) return -1; if (autoindex) fts_queue_index(box); return 0; }
static int acl_mailbox_rename(struct mailbox *src, struct mailbox *dest) { struct acl_mailbox *abox = ACL_CONTEXT(src); int ret; /* renaming requires rights to delete the old mailbox */ ret = acl_mailbox_right_lookup(src, ACL_STORAGE_RIGHT_DELETE); if (ret <= 0) { if (ret == 0) acl_mailbox_fail_not_found(src); return -1; } /* and create the new one under the parent mailbox */ T_BEGIN { ret = acl_mailbox_list_have_right(dest->list, dest->name, TRUE, ACL_STORAGE_RIGHT_CREATE, NULL); } T_END; if (ret <= 0) { if (ret == 0) { /* Note that if the mailbox didn't have LOOKUP permission, this now reveals to user the mailbox's existence. Can't help it. */ mail_storage_set_error(src->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); } else { mail_storage_set_internal_error(src->storage); } return -1; } return abox->module_ctx.super.rename_box(src, dest); }
static int acl_mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) { struct acl_mailbox *abox = ACL_CONTEXT(box); int ret; /* we're looking up CREATE permission from our parent's rights */ ret = acl_mailbox_list_have_right(box->list, box->name, TRUE, ACL_STORAGE_RIGHT_CREATE, NULL); if (ret <= 0) { if (ret < 0) { mail_storage_set_internal_error(box->storage); return -1; } /* Note that if user didn't have LOOKUP permission to parent mailbox, this may reveal the mailbox's existence to user. Can't help it. */ mail_storage_set_error(box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); return -1; } /* ignore ACLs in this mailbox until creation is complete, because super.create() may call e.g. mailbox_open() which will fail since we haven't yet copied ACLs to this mailbox. */ abox->skip_acl_checks = TRUE; ret = abox->module_ctx.super.create_box(box, update, directory); abox->skip_acl_checks = FALSE; if (ret == 0) acl_mailbox_copy_acls_from_parent(box); return ret; }
static int index_storage_get_dict(struct mailbox *box, enum mail_attribute_type type, struct dict **dict_r, const char **mailbox_prefix_r) { struct mail_storage *storage = box->storage; struct mail_namespace *ns; struct mailbox_metadata metadata; struct dict_settings set; const char *error; if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) return -1; *mailbox_prefix_r = guid_128_to_string(metadata.guid); ns = mailbox_get_namespace(box); if (type == MAIL_ATTRIBUTE_TYPE_PRIVATE) { /* private attributes are stored in user's own dict */ return index_storage_get_user_dict(storage, storage->user, dict_r); } else if (ns->user == ns->owner) { /* user owns the mailbox. shared attributes are stored in the same dict. */ return index_storage_get_user_dict(storage, storage->user, dict_r); } else if (ns->owner != NULL) { /* accessing shared attribute of a shared mailbox. use the owner's dict. */ return index_storage_get_user_dict(storage, ns->owner, dict_r); } /* accessing shared attributes of a public mailbox. no user owns it, so use the storage's dict. */ if (storage->_shared_attr_dict != NULL) { *dict_r = storage->_shared_attr_dict; return 0; } if (*storage->set->mail_attribute_dict == '\0') { mail_storage_set_error(storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox attributes not enabled"); return -1; } if (storage->shared_attr_dict_failed) { mail_storage_set_internal_error(storage); return -1; } memset(&set, 0, sizeof(set)); set.username = storage->user->username; set.base_dir = storage->user->set->base_dir; if (mail_user_get_home(storage->user, &set.home_dir) <= 0) set.home_dir = NULL; if (dict_init_full(storage->set->mail_attribute_dict, &set, &storage->_shared_attr_dict, &error) < 0) { mail_storage_set_critical(storage, "mail_attribute_dict: dict_init(%s) failed: %s", storage->set->mail_attribute_dict, error); storage->shared_attr_dict_failed = TRUE; return -1; } *dict_r = storage->_shared_attr_dict; return 0; }
static int mbox_mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) { int fd, ret; if (directory && (box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) == 0) return 0; if (box->inbox_any) { if (create_inbox(box) < 0) return -1; } else { /* create the mbox file */ ret = mailbox_create_fd(box, box->path, O_RDWR | O_CREAT | O_EXCL, &fd); if (ret < 0) return -1; if (ret == 0) { mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS, "Mailbox already exists"); return -1; } (void)close(fd); } return update == NULL ? 0 : mbox_mailbox_update(box, update); }
static int create_inbox(struct mailbox *box) { const char *inbox_path; int fd; inbox_path = mailbox_get_path(box); fd = open(inbox_path, O_RDWR | O_CREAT | O_EXCL, 0660); if (fd == -1 && errno == EACCES) { /* try again with increased privileges */ (void)restrict_access_use_priv_gid(); fd = open(inbox_path, O_RDWR | O_CREAT | O_EXCL, 0660); restrict_access_drop_priv_gid(); } if (fd != -1) { i_close_fd(&fd); return 0; } else if (errno == EACCES) { mail_storage_set_critical(box->storage, "%s", mail_error_create_eacces_msg("open", inbox_path)); return -1; } else if (errno == EEXIST) { mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS, "Mailbox already exists"); return -1; } else { mail_storage_set_critical(box->storage, "open(%s, O_CREAT) failed: %m", inbox_path); return -1; } }
static int pop3_migration_get_special(struct mail *_mail, enum mail_fetch_field field, const char **value_r) { struct mail_private *mail = (struct mail_private *)_mail; union mail_module_context *mmail = POP3_MIGRATION_MAIL_CONTEXT(mail); struct pop3_migration_mailbox *mbox = POP3_MIGRATION_CONTEXT(_mail->box); struct imap_msg_map map_key, *map; if (field == MAIL_FETCH_UIDL_BACKEND || field == MAIL_FETCH_POP3_ORDER) { if (mbox->uidl_sync_failed || pop3_migration_uidl_sync(_mail->box) < 0) { mbox->uidl_sync_failed = TRUE; mail_storage_set_error(_mail->box->storage, MAIL_ERROR_TEMP, "POP3 UIDLs couldn't be synced"); return -1; } memset(&map_key, 0, sizeof(map_key)); map_key.uid = _mail->uid; map = array_bsearch(&mbox->imap_msg_map, &map_key, imap_msg_map_uid_cmp); if (map != NULL && map->pop3_uidl != NULL) { if (field == MAIL_FETCH_UIDL_BACKEND) *value_r = map->pop3_uidl; else *value_r = t_strdup_printf("%u", map->pop3_seq); return 0; } /* not found from POP3 server, fallback to default */ } return mmail->super.get_special(_mail, field, value_r); }
static int sieve_attribute_get_sieve(struct mail_storage *storage, const char *key, struct mail_attribute_value *value_r) { struct sieve_storage *svstorage; struct sieve_script *script; const char *scriptname, *errstr; int ret; if ((ret = mail_sieve_user_init(storage->user, &svstorage)) <= 0) return ret; if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT) == 0) return sieve_attribute_get_default(storage, svstorage, value_r); if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) return 0; if ((value_r->flags & MAIL_ATTRIBUTE_VALUE_FLAG_INT_STREAMS) == 0) { mail_storage_set_error(storage, MAIL_ERROR_PARAMS, "Sieve attributes are available only as streams"); return -1; } scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES); script = sieve_storage_open_script(svstorage, scriptname, NULL); if ((ret=sieve_attribute_retrieve_script (storage, svstorage, script, FALSE, value_r, &errstr)) < 0) { mail_storage_set_critical(storage, "Failed to access sieve script '%s': %s", scriptname, errstr); } return ret; }
static int mbox_mailbox_create(struct mailbox *box, const struct mailbox_update *update, bool directory) { int fd, ret; if ((ret = index_storage_mailbox_create(box, directory)) <= 0) return ret; if (box->inbox_any) { if (create_inbox(box) < 0) return -1; } else { /* create the mbox file */ ret = mailbox_create_fd(box, mailbox_get_path(box), O_RDWR | O_CREAT | O_EXCL, &fd); if (ret < 0) return -1; if (ret == 0) { mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS, "Mailbox already exists"); return -1; } i_close_fd(&fd); } return update == NULL ? 0 : mbox_mailbox_update(box, update); }
static int index_storage_get_user_dict(struct mail_storage *err_storage, struct mail_user *user, struct dict **dict_r) { struct dict_settings dict_set; struct mail_namespace *ns; struct mail_storage *attr_storage; const char *error; if (user->_attr_dict != NULL) { *dict_r = user->_attr_dict; return 0; } if (user->attr_dict_failed) { mail_storage_set_internal_error(err_storage); return -1; } ns = mail_user_find_attribute_namespace(user); if (ns == NULL) { /* probably never happens? */ mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox attributes not available for this mailbox"); return -1; } attr_storage = mail_namespace_get_default_storage(ns); if (*attr_storage->set->mail_attribute_dict == '\0') { mail_storage_set_error(err_storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox attributes not enabled"); return -1; } memset(&dict_set, 0, sizeof(dict_set)); dict_set.username = user->username; dict_set.base_dir = user->set->base_dir; if (dict_init(attr_storage->set->mail_attribute_dict, &dict_set, &user->_attr_dict, &error) < 0) { mail_storage_set_critical(err_storage, "mail_attribute_dict: dict_init(%s) failed: %s", attr_storage->set->mail_attribute_dict, error); user->attr_dict_failed = TRUE; return -1; } *dict_r = user->_attr_dict; return 0; }
int pop3c_sync_get_uidls(struct pop3c_mailbox *mbox) { ARRAY_TYPE(const_string) uidls; struct istream *input; const char *error, *cline; char *line, *p; unsigned int seq, line_seq; if (mbox->msg_uidls != NULL) return 0; if ((pop3c_client_get_capabilities(mbox->client) & POP3C_CAPABILITY_UIDL) == 0) { mail_storage_set_error(mbox->box.storage, MAIL_ERROR_NOTPOSSIBLE, "UIDLs not supported by server"); return -1; } if (pop3c_client_cmd_stream(mbox->client, "UIDL\r\n", &input, &error) < 0) { mail_storage_set_critical(mbox->box.storage, "UIDL failed: %s", error); return -1; } mbox->uidl_pool = pool_alloconly_create("POP3 UIDLs", 1024*32); p_array_init(&uidls, mbox->uidl_pool, 64); seq = 0; while ((line = i_stream_read_next_line(input)) != NULL) { seq++; p = strchr(line, ' '); if (p == NULL) { mail_storage_set_critical(mbox->box.storage, "Invalid UIDL line: %s", line); break; } *p++ = '\0'; if (str_to_uint(line, &line_seq) < 0 || line_seq != seq) { mail_storage_set_critical(mbox->box.storage, "Unexpected UIDL seq: %s != %u", line, seq); break; } cline = p_strdup(mbox->uidl_pool, p); array_append(&uidls, &cline, 1); } i_stream_destroy(&input); if (line != NULL) { pool_unref(&mbox->uidl_pool); return -1; } if (seq == 0) { /* make msg_uidls non-NULL */ array_append_zero(&uidls); } mbox->msg_uidls = array_idx(&uidls, 0); mbox->msg_count = seq; return 0; }
static int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir, const char **fname_r) { struct mailbox *box = &mbox->box; const struct mailbox_permissions *perm = mailbox_get_permissions(box); unsigned int prefix_len; const char *tmp_fname; string_t *path; mode_t old_mask; int fd; path = t_str_new(256); str_append(path, dir); str_append_c(path, '/'); prefix_len = str_len(path); do { tmp_fname = maildir_filename_generate(); str_truncate(path, prefix_len); str_append(path, tmp_fname); /* the generated filename is unique. the only reason why it might return an existing filename is if the time moved backwards. so we'll use O_EXCL anyway, although it's mostly useless. */ old_mask = umask(0777 & ~perm->file_create_mode); fd = open(str_c(path), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0777); umask(old_mask); } while (fd == -1 && errno == EEXIST); *fname_r = tmp_fname; if (fd == -1) { if (ENOQUOTA(errno)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA); } else { mail_storage_set_critical(box->storage, "open(%s) failed: %m", str_c(path)); } } else if (perm->file_create_gid != (gid_t)-1) { if (fchown(fd, (uid_t)-1, perm->file_create_gid) < 0) { if (errno == EPERM) { mail_storage_set_critical(box->storage, "%s", eperm_error_get_chgrp("fchown", str_c(path), perm->file_create_gid, perm->file_create_gid_origin)); } else { mail_storage_set_critical(box->storage, "fchown(%s) failed: %m", str_c(path)); } } } return fd; }
static int acl_attribute_get_acl(struct mailbox *box, const char *key, struct mail_attribute_value *value_r) { struct acl_object *aclobj = acl_mailbox_get_aclobj(box); struct acl_object_list_iter *iter; struct acl_rights rights, wanted_rights; const char *id; int ret; memset(value_r, 0, sizeof(*value_r)); if (!box->storage->user->dsyncing) { mail_storage_set_error(box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); return -1; } /* set last_change for all ACL objects, even if they don't exist (because they could have been removed by the last change, and dsync can use this information) */ (void)acl_object_last_changed(aclobj, &value_r->last_change); memset(&wanted_rights, 0, sizeof(wanted_rights)); id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); if (acl_identifier_parse(id, &wanted_rights) < 0) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, t_strdup_printf("Invalid ID: %s", id)); return -1; } iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (!rights.global && rights.id_type == wanted_rights.id_type && null_strcmp(rights.identifier, wanted_rights.identifier) == 0) { value_r->value = acl_rights_export(&rights); break; } } if (ret < 0) mail_storage_set_internal_error(box->storage); acl_object_list_deinit(&iter); return ret; }
static int mbox_mailbox_get_guid(struct mbox_mailbox *mbox, guid_128_t guid_r) { const char *errstr; if (mail_index_is_in_memory(mbox->box.index)) { errstr = "Mailbox GUIDs are not permanent without index files"; if (mbox->storage->set->mbox_min_index_size != 0) { errstr = t_strconcat(errstr, " (mbox_min_index_size is non-zero)", NULL); } mail_storage_set_error(mbox->box.storage, MAIL_ERROR_NOTPOSSIBLE, errstr); return -1; } if (mbox_sync_header_refresh(mbox) < 0) return -1; if (!guid_128_is_empty(mbox->mbox_hdr.mailbox_guid)) { /* we have the GUID */ } else if (mbox_file_open(mbox) < 0) return -1; else if (mbox->backend_readonly) { mail_storage_set_error(mbox->box.storage, MAIL_ERROR_PERM, "Can't set mailbox GUID to a read-only mailbox"); return -1; } else { /* create another mailbox and sync */ struct mailbox *box2; struct mbox_mailbox *mbox2; int ret; i_assert(mbox->mbox_lock_type == F_UNLCK); box2 = mailbox_alloc(mbox->box.list, mbox->box.vname, 0); ret = mailbox_sync(box2, 0); mbox2 = (struct mbox_mailbox *)box2; memcpy(guid_r, mbox2->mbox_hdr.mailbox_guid, GUID_128_SIZE); mailbox_free(&box2); return ret; } memcpy(guid_r, mbox->mbox_hdr.mailbox_guid, GUID_128_SIZE); return 0; }
void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src) { const char *name, *str; enum mail_error error; name = get_user_visible_mailbox_name(src); str = mail_storage_get_last_error(src->storage, &error); str = t_strdup_printf("%s (for backend mailbox %s)", str, name); mail_storage_set_error(dest->storage, error, str); }
static int pop3c_mail_get_stream(struct mail *_mail, bool get_body, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct pop3c_mailbox *mbox = (struct pop3c_mailbox *)_mail->box; enum pop3c_capability capa; const char *name, *cmd, *error; struct istream *input; if (get_body && mail->data.stream != NULL) { name = i_stream_get_name(mail->data.stream); if (strncmp(name, "RETR", 4) == 0) { /* we've fetched the body */ } else if (strncmp(name, "TOP", 3) == 0) { /* we've fetched the header, but we need the body now too */ index_mail_close_streams(mail); } else { i_panic("Unexpected POP3 stream name: %s", name); } } if (mail->data.stream == NULL) { capa = pop3c_client_get_capabilities(mbox->client); if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) { cmd = t_strdup_printf("RETR %u\r\n", _mail->seq); get_body = TRUE; } else { cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq); } if (pop3c_client_cmd_stream(mbox->client, cmd, &input, &error) < 0) { mail_storage_set_error(mbox->box.storage, !pop3c_client_is_connected(mbox->client) ? MAIL_ERROR_TEMP : MAIL_ERROR_EXPUNGED, error); return -1; } mail->data.stream = input; if (mail->mail.v.istream_opened != NULL) { if (mail->mail.v.istream_opened(_mail, &mail->data.stream) < 0) { index_mail_close_streams(mail); return -1; } } i_stream_set_name(mail->data.stream, t_strcut(cmd, '\r')); if (get_body) pop3c_mail_cache_size(mail); } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); }
static void mail_copy_set_failed(struct mail_save_context *ctx, struct mail *mail, const char *func) { const char *errstr; enum mail_error error; if (ctx->transaction->box->storage == mail->box->storage) return; errstr = mail_storage_get_last_error(mail->box->storage, &error); mail_storage_set_error(ctx->transaction->box->storage, error, t_strdup_printf("%s (%s)", errstr, func)); }
void mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function) { i_assert(function != NULL); if (ENOQUOTA(errno)) { mail_storage_set_error(&mbox->storage->storage, MAIL_ERROR_NOQUOTA, MAIL_ERRSTR_NO_QUOTA); } else { const char *toobig_error = errno != EFBIG ? "" : " (process was started with ulimit -f limit)"; mailbox_set_critical(&mbox->box, "%s failed with mbox: %m%s", function, toobig_error); } }
int mailbox_keywords_create(struct mailbox *box, const char *const keywords[], struct mail_keywords **keywords_r) { const char *error, *empty_keyword_list = NULL; i_assert(box->opened); if (keywords == NULL) keywords = &empty_keyword_list; if (!mailbox_keywords_are_valid(box, keywords, &error)) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, error); return -1; } *keywords_r = mail_index_keywords_create(box->index, keywords); return 0; }
static int mbox_mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE]) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; if (mail_index_is_in_memory(box->index)) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox GUIDs are not permanent without index files"); return -1; } if (mail_guid_128_is_empty(mbox->mbox_hdr.mailbox_guid)) { if (mailbox_sync(&mbox->box, 0) < 0) return -1; } memcpy(guid, mbox->mbox_hdr.mailbox_guid, MAIL_GUID_128_SIZE); return 0; }
int mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function) { i_assert(function != NULL); if (ENOSPACE(errno)) { mail_storage_set_error(&mbox->storage->storage, MAIL_ERROR_NOSPACE, MAIL_ERRSTR_NO_SPACE); } else { const char *toobig_error = errno != EFBIG ? "" : " (process was started with ulimit -f limit)"; mail_storage_set_critical(&mbox->storage->storage, "%s failed with mbox file %s: %m%s", function, mbox->box.path, toobig_error); } return -1; }
static void index_sort_program_set_mail_failed(struct mail_search_sort_program *program, struct mail *mail) { switch (mailbox_get_last_mail_error(mail->box)) { case MAIL_ERROR_EXPUNGED: break; case MAIL_ERROR_LOOKUP_ABORTED: /* just change the error message */ i_assert(program->slow_mails_left == 0); mail_storage_set_error(program->t->box->storage, MAIL_ERROR_LIMIT, "Requested sort would have taken too long."); /* fall through */ default: program->failed = TRUE; break; } }
int mbox_file_seek(struct mbox_mailbox *mbox, struct mail_index_view *view, uint32_t seq, bool *deleted_r) { uoff_t offset; int ret; ret = mbox_file_lookup_offset(mbox, view, seq, &offset); if (ret <= 0) { *deleted_r = ret < 0; return ret; } *deleted_r = FALSE; if (istream_raw_mbox_seek(mbox->mbox_stream, offset) < 0) { if (offset == 0) { mbox->invalid_mbox_file = TRUE; mail_storage_set_error(&mbox->storage->storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox isn't a valid mbox file"); return -1; } if (mbox->mbox_hdr.dirty_flag != 0) return 0; mail_storage_set_critical(&mbox->storage->storage, "Cached message offset %s is invalid for mbox file %s", dec2str(offset), mailbox_get_path(&mbox->box)); mbox->mbox_hdr.dirty_flag = 1; mbox->mbox_broken_offsets = TRUE; return 0; } if (mbox->mbox_hdr.dirty_flag != 0) { /* we're dirty - make sure this is the correct mail */ if (!mbox_sync_parse_match_mail(mbox, view, seq)) return 0; ret = istream_raw_mbox_seek(mbox->mbox_stream, offset); i_assert(ret == 0); } return 1; }
static int zlib_mail_save_finish(struct mail_save_context *ctx) { struct mailbox *box = ctx->transaction->box; union mailbox_module_context *zbox = ZLIB_CONTEXT(box); struct istream *input; if (zbox->super.save_finish(ctx) < 0) return -1; if (mail_get_stream(ctx->dest_mail, NULL, NULL, &input) < 0) return -1; if (compression_detect_handler(input) != NULL) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE, "Saving mails compressed by client isn't supported"); return -1; } return 0; }