Beispiel #1
0
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;
}
Beispiel #3
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);
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #7
0
Datei: mail.c Projekt: 91D2/pvpgn
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;
   }
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
0
Datei: mail.c Projekt: 91D2/pvpgn
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;
}
Beispiel #15
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);
}
Beispiel #16
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);
}
Beispiel #17
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
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;
}
Beispiel #22
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;
}
Beispiel #25
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;
}
Beispiel #26
0
Datei: mail.c Projekt: 91D2/pvpgn
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);
}
Beispiel #27
0
Datei: mail.c Projekt: 91D2/pvpgn
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;
}
Beispiel #29
0
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, &copy_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;
	}
}
Beispiel #30
0
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;
}