int index_storage_mailbox_update(struct mailbox *box, const struct mailbox_update *update) { const struct mail_index_header *hdr; struct mail_index_view *view; struct mail_index_transaction *trans; int ret; if (mailbox_open(box) < 0) return -1; /* make sure we get the latest index info */ mail_index_refresh(box->index); view = mail_index_view_open(box->index); hdr = mail_index_get_header(view); trans = mail_index_transaction_begin(view, MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); if (update->uid_validity != 0 && hdr->uid_validity != update->uid_validity) { uint32_t uid_validity = update->uid_validity; if (hdr->uid_validity != 0) { /* UIDVALIDITY change requires index to be reset */ mail_index_reset(trans); } mail_index_update_header(trans, offsetof(struct mail_index_header, uid_validity), &uid_validity, sizeof(uid_validity), TRUE); }
raw_mailbox_alloc_common(struct mail_user *user, struct istream *input, const char *path, time_t received_time, const char *envelope_sender, struct mailbox **box_r) { struct mail_namespace *ns = user->namespaces; struct mailbox *box; struct raw_mailbox *raw_box; const char *name; name = path != NULL ? path : i_stream_get_name(input); box = *box_r = mailbox_alloc(ns->list, name, MAILBOX_FLAG_NO_INDEX_FILES); if (input != NULL) { if (mailbox_open_stream(box, input) < 0) return -1; } else { if (mailbox_open(box) < 0) return -1; } if (mailbox_sync(box, 0) < 0) return -1; i_assert(strcmp(box->storage->name, RAW_STORAGE_NAME) == 0); raw_box = (struct raw_mailbox *)box; raw_box->envelope_sender = envelope_sender; raw_box->mtime = received_time; return 0; }
struct mailbox_sync_context * mdbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box; enum mdbox_sync_flags mdbox_sync_flags = 0; int ret = 0; if (!box->opened) { if (mailbox_open(box) < 0) ret = -1; } if (box->opened) { if (mail_index_reset_fscked(box->index)) mdbox_storage_set_corrupted(mbox->storage); } if (ret == 0 && (index_mailbox_want_full_sync(&mbox->box, flags) || mbox->storage->corrupted)) { if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0) mdbox_sync_flags |= MDBOX_SYNC_FLAG_FORCE_REBUILD; ret = mdbox_sync(mbox, mdbox_sync_flags); } return index_mailbox_sync_init(box, flags, ret < 0); }
static int cmd_acl_mailbox_open(struct mail_user *user, const char *mailbox, struct mailbox **box_r) { struct acl_user *auser = ACL_USER_CONTEXT(user); struct mail_namespace *ns; struct mailbox *box; const char *storage_name; if (auser == NULL) { i_error("ACL not enabled for %s", user->username); return -1; } storage_name = mailbox; ns = mail_namespace_find(user->namespaces, &storage_name); if (ns == NULL) { i_error("No namespace found for mailbox %s", mailbox); return -1; } box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_READONLY | MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_IGNORE_ACLS); if (mailbox_open(box) < 0) { i_error("Can't open mailbox %s: %s", mailbox, mail_storage_get_last_error(box->storage, NULL)); mailbox_free(&box); return -1; } *box_r = box; return 0; }
static bool cmd_setmetadata_mailbox(struct imap_setmetadata_context *ctx, const char *mailbox) { struct client_command_context *cmd = ctx->cmd; struct client *client = cmd->client; struct mail_namespace *ns; ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) return TRUE; if (client->mailbox != NULL && !client->mailbox_examined && mailbox_equals(client->mailbox, ns, mailbox)) ctx->box = client->mailbox; else { ctx->box = mailbox_alloc(ns->list, mailbox, 0); if (mailbox_open(ctx->box) < 0) { client_send_box_error(cmd, ctx->box); mailbox_free(&ctx->box); return TRUE; } } ctx->trans = imap_metadata_transaction_begin(ctx->box); return cmd_setmetadata_start(ctx); }
int index_mailbox_get_metadata(struct mailbox *box, enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r) { if (!box->opened) { if (mailbox_open(box) < 0) return -1; } if (!box->synced && (items & MAILBOX_METADATA_SYNC_ITEMS) != 0) { if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0) return -1; } if ((items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) { if (get_metadata_virtual_size(box, metadata_r) < 0) return -1; } if ((items & MAILBOX_METADATA_CACHE_FIELDS) != 0) get_metadata_cache_fields(box, metadata_r); if ((items & MAILBOX_METADATA_PRECACHE_FIELDS) != 0) get_metadata_precache_fields(box, metadata_r); if ((items & MAILBOX_METADATA_BACKEND_NAMESPACE) != 0) { metadata_r->backend_ns_prefix = ""; metadata_r->backend_ns_type = mailbox_list_get_namespace(box->list)->type; } return 0; }
extern char const * check_mail(t_connection const * c) { t_account * user; t_mailbox * mailbox; static char tmp[64]; int count; if (!(c)) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return ""; } if (!(user=conn_get_account(c))) return ""; mailbox=mailbox_open(user, mbox_mode_read); count = mailbox_count(mailbox); mailbox_close(mailbox); if (count == 0) { return "You have no mail."; } else { sprintf(tmp,"You have %d message(s) in your mailbox.",count); return tmp; } }
int fts_backend_reset_last_uids(struct fts_backend *backend) { struct mailbox_list_iterate_context *iter; const struct mailbox_info *info; struct mailbox *box; int ret = 0; iter = mailbox_list_iter_init(backend->ns->list, "*", MAILBOX_LIST_ITER_SKIP_ALIASES | MAILBOX_LIST_ITER_NO_AUTO_BOXES); while ((info = mailbox_list_iter_next(iter)) != NULL) { if ((info->flags & (MAILBOX_NONEXISTENT | MAILBOX_NOSELECT)) != 0) continue; box = mailbox_alloc(info->ns->list, info->vname, 0); if (mailbox_open(box) == 0) { if (fts_index_set_last_uid(box, 0) < 0) ret = -1; } mailbox_free(&box); } if (mailbox_list_iter_deinit(&iter) < 0) ret = -1; return ret; }
static int cmd_acl_mailbox_open(struct doveadm_mail_cmd_context *ctx, struct mail_user *user, const char *mailbox, struct mailbox **box_r) { struct acl_user *auser = ACL_USER_CONTEXT(user); struct mail_namespace *ns; struct mailbox *box; if (auser == NULL) { i_error("ACL not enabled for %s", user->username); doveadm_mail_failed_error(ctx, MAIL_ERROR_NOTFOUND); return -1; } ns = mail_namespace_find(user->namespaces, mailbox); box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_READONLY | MAILBOX_FLAG_IGNORE_ACLS); if (mailbox_open(box) < 0) { i_error("Can't open mailbox %s: %s", mailbox, mailbox_get_last_error(box, NULL)); doveadm_mail_failed_mailbox(ctx, box); mailbox_free(&box); return -1; } *box_r = box; return 0; }
static int cmd_save_to_mailbox(struct save_cmd_context *ctx, struct mailbox *box, struct istream *input) { struct mail_storage *storage = mailbox_get_storage(box); struct mailbox_transaction_context *trans; struct mail_save_context *save_ctx; ssize_t ret; bool save_failed = FALSE; if (mailbox_open(box) < 0) { i_error("Failed to open mailbox %s: %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); return -1; } trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); save_ctx = mailbox_save_alloc(trans); if (mailbox_save_begin(&save_ctx, input) < 0) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); mailbox_transaction_rollback(&trans); return -1; } while ((ret = i_stream_read(input)) > 0 || ret == -2) { if (mailbox_save_continue(save_ctx) < 0) { save_failed = TRUE; ret = -1; break; } } i_assert(ret == -1); if (input->stream_errno != 0) { i_error("read(msg input) failed: %s", i_stream_get_error(input)); doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_TEMP); } else if (save_failed) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else if (mailbox_save_finish(&save_ctx) < 0) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else if (mailbox_transaction_commit(&trans) < 0) { i_error("Save transaction commit failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else { ret = 0; } if (save_ctx != NULL) mailbox_save_cancel(&save_ctx); if (trans != NULL) mailbox_transaction_rollback(&trans); i_assert(input->eof); return ret < 0 ? -1 : 0; }
static int imap_metadata_get_mailbox_transaction(struct imap_metadata_transaction *imtrans) { if (imtrans->trans != NULL) return 0; if (imtrans->box == NULL || mailbox_open(imtrans->box) < 0) return -1; imtrans->trans = mailbox_transaction_begin(imtrans->box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); return 0; }
static int imap_metadata_get_mailbox_transaction(struct imap_metadata_transaction *imtrans) { if (imtrans->trans != NULL) return 0; if (imtrans->box == NULL || mailbox_open(imtrans->box) < 0) return -1; imtrans->trans = mailbox_transaction_begin(imtrans->box, 0); return 0; }
static void mail_func_send(t_connection * c, const char * str) { int i; char *dest; char const *p,*myname; t_account * recv; t_mailbox * mailbox; if (c==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return; } if (str==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command string"); return; } for(i=0;str[i]==' ';i++); /* skip any spaces */ if (str[i]=='\0') { /* the %mail send command has no receiver */ message_send_text(c,message_type_error,c,"You must specify the receiver"); message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>"); return; } p=str+i; /* set ip at the start of receiver string */ for(i=1;p[i]!=' ' && p[i]!='\0';i++); /* skip the receiver string */ if (p[i]=='\0') { /* it seems user forgot to write any message */ message_send_text(c,message_type_error,c,"Your message is empty!"); message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>"); return; } dest=xmalloc(i+1); memmove(dest,p,i); dest[i]='\0'; /* copy receiver in his separate string */ if ((recv=accountlist_find_account(dest))==NULL) { /* is dest a valid account on this server ? */ message_send_text(c,message_type_error,c,"Receiver UNKNOWN!"); xfree(dest); return; } xfree(dest); /* free dest here, the sooner the better */ if ((mailbox=mailbox_open(recv, mbox_mode_write))==NULL) { message_send_text(c,message_type_error,c,"There was an error completing your request!"); return; } if (get_mail_quota(recv)<=mailbox_count(mailbox)) { /* check quota */ message_send_text(c,message_type_error,c,"Receiver has reached his mail quota. Your message will NOT be sent."); mailbox_close(mailbox); return; } myname=conn_get_username(c); /* who am i ? */ if (mailbox_deliver(mailbox,myname,p+i+1)<0) message_send_text(c,message_type_error,c,"There was an error completing your request!"); else message_send_text(c,message_type_info,c,"Your mail has been sent successfully."); mailbox_close(mailbox); }
int index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { if (!box->opened) { if (mailbox_open(box) < 0) return -1; if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0) return -1; } index_storage_get_open_status(box, items, status_r); return 0; }
struct mailbox_sync_context * raw_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct raw_mailbox *mbox = (struct raw_mailbox *)box; int ret = 0; if (!box->opened) { if (mailbox_open(box) < 0) ret = -1; } if (!mbox->synced && ret == 0) ret = raw_sync(mbox); return index_mailbox_sync_init(box, flags, ret < 0); }
struct mailbox_sync_context * cydir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct cydir_mailbox *mbox = (struct cydir_mailbox *)box; int ret = 0; if (!box->opened) { if (mailbox_open(box) < 0) ret = -1; } if (index_mailbox_want_full_sync(&mbox->box, flags) && ret == 0) ret = cydir_sync(mbox); return index_mailbox_sync_init(box, flags, ret < 0); }
static int mbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; int ret; if (!box->opened) { if (mailbox_open(box) < 0) return -1; } mbox->sync_hdr_update = update; ret = mbox_sync(mbox, MBOX_SYNC_HEADER | MBOX_SYNC_FORCE_SYNC | MBOX_SYNC_REWRITE); mbox->sync_hdr_update = NULL; return ret; }
static int cmd_copy_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { struct copy_cmd_context *ctx = (struct copy_cmd_context *)_ctx; const enum mailbox_list_iter_flags iter_flags = MAILBOX_LIST_ITER_NO_AUTO_BOXES | MAILBOX_LIST_ITER_RETURN_NO_FLAGS; struct doveadm_mailbox_list_iter *iter; struct mail_user *src_user; struct mail_namespace *ns; struct mailbox *destbox; const struct mailbox_info *info; int ret = 0; if (ctx->source_username != NULL && ctx->source_user == NULL) cmd_copy_alloc_source_user(ctx); ns = mail_namespace_find(user->namespaces, ctx->destname); destbox = mailbox_alloc(ns->list, ctx->destname, MAILBOX_FLAG_SAVEONLY); if (mailbox_open(destbox) < 0) { i_error("Can't open mailbox '%s': %s", ctx->destname, mailbox_get_last_error(destbox, NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, destbox); mailbox_free(&destbox); return -1; } src_user = ctx->source_user != NULL ? ctx->source_user : user; iter = doveadm_mailbox_list_iter_init(_ctx, src_user, _ctx->search_args, iter_flags); while ((info = doveadm_mailbox_list_iter_next(iter)) != NULL) T_BEGIN { if (cmd_copy_box(ctx, destbox, info) < 0) ret = -1; } T_END; if (doveadm_mailbox_list_iter_deinit(&iter) < 0) ret = -1; if (mailbox_sync(destbox, 0) < 0) { i_error("Syncing mailbox '%s' failed: %s", ctx->destname, mailbox_get_last_error(destbox, NULL)); doveadm_mail_failed_mailbox(&ctx->ctx, destbox); ret = -1; } mailbox_free(&destbox); return ret; }
int imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl, struct mailbox **box_r, enum mail_error *error_code_r, const char **error_r) { struct mailbox_status box_status; enum mailbox_flags flags = MAILBOX_FLAG_READONLY; struct mail_namespace *ns; struct mailbox *box; if (mpurl->box != NULL) { *box_r = mpurl->box; *error_code_r = MAIL_ERROR_NONE; return 1; } /* find mailbox namespace */ ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox); /* open mailbox */ if (mpurl->selected_box != NULL && mailbox_equals(mpurl->selected_box, ns, mpurl->mailbox)) box = mpurl->selected_box; else box = mailbox_alloc(ns->list, mpurl->mailbox, flags); if (mailbox_open(box) < 0) { *error_r = mail_storage_get_last_error(mailbox_get_storage(box), error_code_r); if (box != mpurl->selected_box) mailbox_free(&box); return *error_code_r == MAIL_ERROR_TEMP ? -1 : 0; } /* verify UIDVALIDITY */ mailbox_get_open_status(box, STATUS_UIDVALIDITY, &box_status); if (mpurl->uidvalidity > 0 && box_status.uidvalidity != mpurl->uidvalidity) { *error_r = "Invalid UIDVALIDITY"; *error_code_r = MAIL_ERROR_EXPUNGED; if (box != mpurl->selected_box) mailbox_free(&box); return 0; } mpurl->box = box; *box_r = box; return 1; }
int index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { if (items == 0) { /* caller could have wanted only e.g. mailbox_status.have_* flags */ return 0; } if (!box->opened) { if (mailbox_open(box) < 0) return -1; if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0) return -1; } index_storage_get_open_status(box, items, status_r); return 0; }
int index_mailbox_get_metadata(struct mailbox *box, enum mailbox_metadata_items items, struct mailbox_metadata *metadata_r) { /* handle items that don't require opening the mailbox */ if ((items & MAILBOX_METADATA_BACKEND_NAMESPACE) != 0) { metadata_r->backend_ns_prefix = ""; metadata_r->backend_ns_type = mailbox_list_get_namespace(box->list)->type; items &= ~MAILBOX_METADATA_BACKEND_NAMESPACE; } if (items == 0) return 0; /* handle items that require opening the mailbox */ if (!box->opened) { if (mailbox_open(box) < 0) return -1; } if (!box->synced && (items & MAILBOX_METADATA_SYNC_ITEMS) != 0) { if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0) return -1; } if ((items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0) { if (index_mailbox_get_virtual_size(box, metadata_r) < 0) return -1; } if ((items & MAILBOX_METADATA_PHYSICAL_SIZE) != 0) { if (index_mailbox_get_physical_size(box, metadata_r) < 0) return -1; } if ((items & MAILBOX_METADATA_FIRST_SAVE_DATE) != 0) { if (index_mailbox_get_first_save_date(box, metadata_r) < 0) return -1; } if ((items & MAILBOX_METADATA_CACHE_FIELDS) != 0) get_metadata_cache_fields(box, metadata_r); if ((items & MAILBOX_METADATA_PRECACHE_FIELDS) != 0) get_metadata_precache_fields(box, metadata_r); return 0; }
static int mbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; int ret = 0; if (!box->opened) { if (mailbox_open(box) < 0) return -1; } if (update->uid_validity != 0 || update->min_next_uid != 0 || !guid_128_is_empty(update->mailbox_guid)) { mbox->sync_hdr_update = update; ret = mbox_sync(mbox, MBOX_SYNC_HEADER | MBOX_SYNC_FORCE_SYNC | MBOX_SYNC_REWRITE); mbox->sync_hdr_update = NULL; } if (ret == 0) ret = index_storage_mailbox_update(box, update); return ret; }
int client_open_save_dest_box(struct client_command_context *cmd, const char *name, struct mailbox **destbox_r) { struct mail_namespace *ns; struct mailbox *box; const char *error_string; enum mail_error error; ns = client_find_namespace(cmd, &name); if (ns == NULL) return -1; if (cmd->client->mailbox != NULL && mailbox_equals(cmd->client->mailbox, ns, name)) { *destbox_r = cmd->client->mailbox; return 0; } box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY); if (mailbox_open(box) < 0) { error_string = mailbox_get_last_error(box, &error); if (error == MAIL_ERROR_NOTFOUND) { client_send_tagline(cmd, t_strdup_printf( "NO [TRYCREATE] %s", error_string)); } else { client_send_box_error(cmd, box); } mailbox_free(&box); return -1; } if (cmd->client->enabled_features != 0) { if (mailbox_enable(box, cmd->client->enabled_features) < 0) { client_send_box_error(cmd, box); mailbox_free(&box); return -1; } } *destbox_r = box; return 0; }
static int cmd_mailbox_metadata_open_mailbox(struct metadata_cmd_context *mctx, struct mail_user *user, const char *op, struct mail_namespace **ns_r, struct mailbox **box_r) { mctx->empty_mailbox_name = mctx->mailbox[0] == '\0'; if (mctx->empty_mailbox_name) { if (!mctx->ctx.allow_empty_mailbox_name) { i_error("Failed to %s: %s", op, "mailbox name cannot be empty"); mctx->ctx.exit_code = EX_USAGE; return -1; } /* server attribute */ *ns_r = mail_namespace_find_inbox(user->namespaces); *box_r = mailbox_alloc((*ns_r)->list, "INBOX", 0); mctx->key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER, mctx->key, NULL); } else { /* mailbox attributes */ *ns_r = mail_namespace_find(user->namespaces, mctx->mailbox); *box_r = mailbox_alloc((*ns_r)->list, mctx->mailbox, 0); } if (mailbox_open(*box_r) < 0) { i_error("Failed to open mailbox: %s", mailbox_get_last_error(*box_r, NULL)); doveadm_mail_failed_mailbox(&mctx->ctx, *box_r); mailbox_free(box_r); return -1; } return 0; }
static int index_mailbox(struct master_connection *conn, struct mail_user *user, const char *mailbox, unsigned int max_recent_msgs, const char *what) { struct mail_namespace *ns; struct mailbox *box; struct mailbox_status status; const char *path, *errstr; enum mail_error error; enum mailbox_sync_flags sync_flags = MAILBOX_SYNC_FLAG_FULL_READ; int ret; ns = mail_namespace_find(user->namespaces, mailbox); box = mailbox_alloc(ns->list, mailbox, 0); mailbox_set_reason(box, "indexing"); ret = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, &path); if (ret < 0) { i_error("Getting path to mailbox %s failed: %s", mailbox, mailbox_get_last_internal_error(box, NULL)); mailbox_free(&box); return -1; } if (ret == 0) { i_info("Indexes disabled for mailbox %s, skipping", mailbox); mailbox_free(&box); return 0; } ret = 0; if (max_recent_msgs != 0) { /* index only if there aren't too many recent messages. don't bother syncing the mailbox, that alone can take a while with large maildirs. */ if (mailbox_open(box) < 0) { i_error("Opening mailbox %s failed: %s", mailbox, mailbox_get_last_internal_error(box, NULL)); ret = -1; } else { mailbox_get_open_status(box, STATUS_RECENT, &status); } if (ret < 0 || status.recent > max_recent_msgs) { mailbox_free(&box); return ret; } } if (strchr(what, 'o') != NULL) sync_flags |= MAILBOX_SYNC_FLAG_OPTIMIZE; if (mailbox_sync(box, sync_flags) < 0) { errstr = mailbox_get_last_internal_error(box, &error); if (error != MAIL_ERROR_NOTFOUND) { i_error("Syncing mailbox %s failed: %s", mailbox, errstr); } else if (user->mail_debug) { i_debug("Syncing mailbox %s failed: %s", mailbox, errstr); } ret = -1; } else if (strchr(what, 'i') != NULL) { if (index_mailbox_precache(conn, box) < 0) ret = -1; } mailbox_free(&box); return ret; }
static void mail_func_delete(t_connection * c, const char * str) { t_account * user; t_mailbox * mailbox; const char * p; char tmp[256]; /* that should be enough */ int i; if (c==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return; } if (str==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command string"); return; } for(i=0;str[i]==' ';i++); p=str+i; if (*p=='\0') { message_send_text(c,message_type_error,c,"Please specify which message to delete. Use the following syntax: /mail delete {<index>|all} ."); return; } if ((user=conn_get_account(c))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL account"); return; } if ((mailbox=mailbox_open(user, mbox_mode_write))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return; } if (strcmp(p,"all")==0) { int rez; if ((rez=mailbox_delete_all(mailbox))<0) { message_send_text(c,message_type_error,c,"There was an error completing your request."); mailbox_close(mailbox); return; } sprintf(tmp,"Successfuly deleted %d messages.",rez); message_send_text(c,message_type_info,c,tmp); } else { int idx; for(i=0;p[i]>='0' && p[i]<='9' && p[i]!='\0';i++); if (p[i]!='\0' && p[i]!=' ') { message_send_text(c,message_type_error,c,"Invalid index. Please use /mail delete {<index>|all} where <index> is a number."); mailbox_close(mailbox); return; } idx=atoi(p); if (idx<1 || idx>mailbox_count(mailbox)) { message_send_text(c,message_type_error,c,"That index is out of range."); mailbox_close(mailbox); return; } if (mailbox_delete(mailbox,idx)<0) { message_send_text(c,message_type_error,c,"There was an error completing your request."); mailbox_close(mailbox); return; } sprintf(tmp,"Succesfully deleted message #%02d.",idx); message_send_text(c,message_type_info,c,tmp); } mailbox_close(mailbox); }
static void mail_func_read(t_connection * c, const char * str) { t_account * user; t_mailbox * mailbox; const char *p; char tmp[256]; int i; if (c==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return; } if (str==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command string"); return; } for(i=0;str[i]==' ';i++); p=str+i; if ((user=conn_get_account(c))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL account"); return; } mailbox=mailbox_open(user, mbox_mode_read); if (*p=='\0') { /* user wants to see the mail summary */ struct maillist_struct *maill, *mp; unsigned int idx; if (!mailbox_count(mailbox)) { message_send_text(c,message_type_info,c,"You have no mail."); mailbox_close(mailbox); return; } if ((maill=mailbox_get_list(mailbox))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maillist"); mailbox_close(mailbox); return; } sprintf(tmp,"You have %d messages. Your mail qouta is set to %d.",mailbox_count(mailbox),get_mail_quota(user)); message_send_text(c,message_type_info,c,tmp); message_send_text(c,message_type_info,c,"ID Sender Date"); message_send_text(c,message_type_info,c,"-------------------------------------"); for(mp=maill,idx=1;mp!=NULL;mp=mp->next,idx++) { sprintf(tmp,"%02u %-14s %s",idx,mp->sender,ctime(&mp->timestamp)); clean_str(tmp); /* ctime() appends an newline that we get cleaned */ message_send_text(c,message_type_info,c,tmp); } message_send_text(c,message_type_info,c,"Use /mail read <ID> to read the content of any message"); mailbox_unget_list(maill); } else { /* user wants to read a message */ int idx; t_mail * mail; for(i=0;p[i]>='0' && p[i]<='9' && p[i]!='\0';i++); if (p[i]!='\0' && p[i]!=' ') { message_send_text(c,message_type_error,c,"Invalid index. Please use /mail read <index> where <index> is a number."); mailbox_close(mailbox); return; } idx=atoi(p); if (idx<1 || idx>mailbox_count(mailbox)) { message_send_text(c,message_type_error,c,"That index is out of range."); mailbox_close(mailbox); return; } if ((mail=mailbox_read(mailbox,idx))==NULL) { message_send_text(c,message_type_error,c,"There was an error completing your request."); mailbox_close(mailbox); return; } sprintf(tmp,"Message #%d from %s on %s:",idx,mail->sender,clean_str(ctime(&mail->timestamp))); message_send_text(c,message_type_info,c,tmp); message_send_text(c,message_type_info,c,mail->message); mailbox_unread(mail); } mailbox_close(mailbox); }
static int tst_mailboxexists_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { struct sieve_stringlist *mailbox_names; string_t *mailbox_item; bool trace = FALSE; bool all_exist = TRUE; int ret; /* * Read operands */ /* Read notify uris */ if ( (ret=sieve_opr_stringlist_read (renv, address, "mailbox-names", &mailbox_names)) <= 0 ) return ret; /* * Perform operation */ if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_TESTS) ) { sieve_runtime_trace(renv, 0, "mailboxexists test"); sieve_runtime_trace_descend(renv); trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); } if ( renv->scriptenv->user != NULL ) { int ret; mailbox_item = NULL; while ( (ret=sieve_stringlist_next_item(mailbox_names, &mailbox_item)) > 0 ) { struct mail_namespace *ns; const char *mailbox = str_c(mailbox_item); struct mailbox *box; /* Find the namespace */ ns = mail_namespace_find(renv->scriptenv->user->namespaces, mailbox); if ( ns == NULL) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' not found", str_sanitize(mailbox, 80)); } all_exist = FALSE; break; } /* Open the box */ box = mailbox_alloc(ns->list, mailbox, 0); if ( mailbox_open(box) < 0 ) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' cannot be opened", str_sanitize(mailbox, 80)); } all_exist = FALSE; mailbox_free(&box); break; } /* Also fail when it is readonly */ if ( mailbox_is_readonly(box) ) { if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' is read-only", str_sanitize(mailbox, 80)); } all_exist = FALSE; mailbox_free(&box); break; } /* FIXME: check acl for 'p' or 'i' ACL permissions as required by RFC */ if ( trace ) { sieve_runtime_trace(renv, 0, "mailbox `%s' exists", str_sanitize(mailbox, 80)); } /* Close mailbox */ mailbox_free(&box); } if ( ret < 0 ) { sieve_runtime_trace_error(renv, "invalid mailbox name item"); return SIEVE_EXEC_BIN_CORRUPT; } } if ( trace ) { if ( all_exist ) sieve_runtime_trace(renv, 0, "all mailboxes are available"); else sieve_runtime_trace(renv, 0, "some mailboxes are unavailable"); } sieve_interpreter_set_test_result(renv->interp, all_exist); return SIEVE_EXEC_OK; }
bool cmd_copy(struct client_command_context *cmd) { struct client *client = cmd->client; struct mail_namespace *dest_ns; struct mail_storage *dest_storage; struct mailbox *destbox; struct mailbox_transaction_context *t; struct mail_search_args *search_args; const char *messageset, *mailbox, *storage_name, *src_uidset; enum mailbox_name_status status; enum mailbox_sync_flags sync_flags = 0; enum imap_sync_flags imap_flags = 0; struct mail_transaction_commit_changes changes; unsigned int copy_count; string_t *msg; int ret; /* <message set> <mailbox> */ if (!client_read_string_args(cmd, 2, &messageset, &mailbox)) return FALSE; if (!client_verify_open_mailbox(cmd)) return TRUE; ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args); if (ret <= 0) return ret < 0; /* open the destination mailbox */ dest_ns = client_find_namespace(cmd, mailbox, &storage_name, &status); if (dest_ns == NULL) { mail_search_args_unref(&search_args); return TRUE; } switch (status) { case MAILBOX_NAME_EXISTS_MAILBOX: break; case MAILBOX_NAME_EXISTS_DIR: status = MAILBOX_NAME_VALID; /* fall through */ case MAILBOX_NAME_VALID: case MAILBOX_NAME_INVALID: case MAILBOX_NAME_NOINFERIORS: client_fail_mailbox_name_status(cmd, mailbox, "TRYCREATE", status); mail_search_args_unref(&search_args); return TRUE; } if (mailbox_equals(client->mailbox, dest_ns, storage_name)) destbox = client->mailbox; else { destbox = mailbox_alloc(dest_ns->list, storage_name, MAILBOX_FLAG_SAVEONLY | MAILBOX_FLAG_KEEP_RECENT); if (mailbox_open(destbox) < 0) { client_send_storage_error(cmd, mailbox_get_storage(destbox)); mailbox_free(&destbox); mail_search_args_unref(&search_args); return TRUE; } if (client->enabled_features != 0) mailbox_enable(destbox, client->enabled_features); } t = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL | MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS); ret = fetch_and_copy(client, t, search_args, &src_uidset, ©_count); mail_search_args_unref(&search_args); msg = t_str_new(256); if (ret <= 0) mailbox_transaction_rollback(&t); else if (mailbox_transaction_commit_get_changes(&t, &changes) < 0) ret = -1; else if (copy_count == 0) { str_append(msg, "OK No messages copied."); pool_unref(&changes.pool); } else if (seq_range_count(&changes.saved_uids) == 0) { /* not supported by backend (virtual) */ str_append(msg, "OK Copy completed."); pool_unref(&changes.pool); } else { i_assert(copy_count == seq_range_count(&changes.saved_uids)); str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity, src_uidset); imap_write_seq_range(msg, &changes.saved_uids); str_append(msg, "] Copy completed."); pool_unref(&changes.pool); } dest_storage = mailbox_get_storage(destbox); if (destbox != client->mailbox) { sync_flags |= MAILBOX_SYNC_FLAG_FAST; imap_flags |= IMAP_SYNC_FLAG_SAFE; mailbox_free(&destbox); } if (ret > 0) return cmd_sync(cmd, sync_flags, imap_flags, str_c(msg)); else if (ret == 0) { /* some messages were expunged, sync them */ return cmd_sync(cmd, 0, 0, "NO ["IMAP_RESP_CODE_EXPUNGEISSUED"] " "Some of the requested messages no longer exist."); } else { client_send_storage_error(cmd, dest_storage); return TRUE; } }
static int snarf(struct mailbox *srcbox, struct mailbox *destbox) { struct mail_search_args *search_args; struct mail_search_context *search_ctx; struct mailbox_transaction_context *src_trans, *dest_trans; struct mail_save_context *save_ctx; struct mail *mail; enum mail_error error; int ret; /* make sure the destination mailbox has been opened. note that this locks the mailbox. */ if (mailbox_open(destbox) < 0) return -1; if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0) return -1; src_trans = mailbox_transaction_begin(srcbox, 0); dest_trans = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL); search_args = mail_search_build_init(); mail_search_build_add_all(search_args); search_ctx = mailbox_search_init(src_trans, search_args, NULL, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); mail_search_args_unref(&search_args); ret = 0; while (mailbox_search_next(search_ctx, &mail)) { if (mail->expunged) continue; save_ctx = mailbox_save_alloc(dest_trans); if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) { error = mailbox_get_last_mail_error(destbox); /* if we failed because of out of disk space, just move those messages we managed to move so far. */ if (error != MAIL_ERROR_NOQUOTA) ret = -1; break; } mail_expunge(mail); } if (mailbox_search_deinit(&search_ctx) < 0) ret = -1; /* commit the copied messages to the destination mailbox. if we crash between that and between expunging the messages from the source mailbox, we're left with duplicates. */ if (ret < 0) mailbox_transaction_rollback(&dest_trans); else if (mailbox_transaction_commit(&dest_trans) < 0) ret = -1; if (ret < 0) mailbox_transaction_rollback(&src_trans); else { if (mailbox_transaction_commit(&src_trans) < 0) ret = -1; } if (ret == 0) { if (mailbox_sync(srcbox, 0) < 0) ret = -1; } return ret; }