Ejemplo n.º 1
0
static void
get_metadata_cache_fields(struct mailbox *box,
			  struct mailbox_metadata *metadata_r)
{
	const struct mail_cache_field *fields;
	enum mail_cache_decision_type dec;
	ARRAY_TYPE(mailbox_cache_field) *cache_fields;
	struct mailbox_cache_field *cf;
	unsigned int i, count;

	if (box->metadata_pool == NULL) {
		box->metadata_pool =
			pool_alloconly_create("mailbox metadata", 1024*3);
	}

	fields = mail_cache_register_get_list(box->cache,
					      box->metadata_pool, &count);

	cache_fields = p_new(box->metadata_pool,
			     ARRAY_TYPE(mailbox_cache_field), 1);
	p_array_init(cache_fields, box->metadata_pool, count);
	for (i = 0; i < count; i++) {
		dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
		if (dec != MAIL_CACHE_DECISION_NO) {
			cf = array_append_space(cache_fields);
			cf->name = fields[i].name;
			cf->decision = fields[i].decision;
			cf->last_used = fields[i].last_used;
		}
	}
	metadata_r->cache_fields = cache_fields;
}
Ejemplo n.º 2
0
static void
index_storage_mailbox_update_cache(struct mailbox *box,
				   const struct mailbox_update *update)
{
	const struct mailbox_cache_field *updates = update->cache_updates;
	ARRAY(struct mail_cache_field) new_fields;
	const struct mail_cache_field *old_fields;
	struct mail_cache_field field;
	unsigned int i, j, old_count;

	old_fields = mail_cache_register_get_list(box->cache,
						  pool_datastack_create(),
						  &old_count);

	/* There shouldn't be many fields, so don't worry about O(n^2). */
	t_array_init(&new_fields, 32);
	for (i = 0; updates[i].name != NULL; i++) {
		/* see if it's an existing field */
		for (j = 0; j < old_count; j++) {
			if (strcmp(updates[i].name, old_fields[j].name) == 0)
				break;
		}
		if (j != old_count) {
			field = old_fields[j];
		} else if (strncmp(updates[i].name, "hdr.", 4) == 0) {
			/* new header */
			memset(&field, 0, sizeof(field));
			field.name = updates[i].name;
			field.type = MAIL_CACHE_FIELD_HEADER;
		} else {
			/* new unknown field. we can't do anything about
			   this since we don't know its type */
			continue;
		}
		field.decision = updates[i].decision;
		if (updates[i].last_used != (time_t)-1)
			field.last_used = updates[i].last_used;
		array_append(&new_fields, &field, 1);
	}
	if (array_count(&new_fields) > 0) {
		mail_cache_register_fields(box->cache,
					   array_idx_modifiable(&new_fields, 0),
					   array_count(&new_fields));
	}
}
Ejemplo n.º 3
0
static void get_metadata_precache_fields(struct mailbox *box,
					 struct mailbox_metadata *metadata_r)
{
	const struct mail_cache_field *fields;
	unsigned int i, count;
	enum mail_fetch_field cache = 0;

	fields = mail_cache_register_get_list(box->cache,
					      pool_datastack_create(), &count);
	for (i = 0; i < count; i++) {
		const char *name = fields[i].name;

		if (strncmp(name, "hdr.", 4) == 0 ||
		    strcmp(name, "date.sent") == 0 ||
		    strcmp(name, "imap.envelope") == 0)
			cache |= MAIL_FETCH_STREAM_HEADER;
		else if (strcmp(name, "mime.parts") == 0 ||
			 strcmp(name, "binary.parts") == 0 ||
			 strcmp(name, "imap.body") == 0 ||
			 strcmp(name, "imap.bodystructure") == 0 ||
			 strcmp(name, "body.snippet") == 0)
			cache |= MAIL_FETCH_STREAM_BODY;
		else if (strcmp(name, "date.received") == 0)
			cache |= MAIL_FETCH_RECEIVED_DATE;
		else if (strcmp(name, "date.save") == 0)
			cache |= MAIL_FETCH_SAVE_DATE;
		else if (strcmp(name, "size.virtual") == 0)
			cache |= MAIL_FETCH_VIRTUAL_SIZE;
		else if (strcmp(name, "size.physical") == 0)
			cache |= MAIL_FETCH_PHYSICAL_SIZE;
		else if (strcmp(name, "pop3.uidl") == 0)
			cache |= MAIL_FETCH_UIDL_BACKEND;
		else if (strcmp(name, "pop3.order") == 0)
			cache |= MAIL_FETCH_POP3_ORDER;
		else if (strcmp(name, "guid") == 0)
			cache |= MAIL_FETCH_GUID;
		else if (strcmp(name, "flags") == 0) {
			/* just ignore for now at least.. */
		} else if (box->storage->set->mail_debug)
			i_debug("Ignoring unknown cache field: %s", name);
	}
	metadata_r->precache_fields = cache;
}
static void index_mail_parse_header_register_all_wanted(struct index_mail *mail)
{
	struct mail *_mail = &mail->mail.mail;
	const struct mail_cache_field *all_cache_fields;
	unsigned int i, count;

	all_cache_fields =
		mail_cache_register_get_list(_mail->box->cache,
					     pool_datastack_create(), &count);
	for (i = 0; i < count; i++) {
		if (strncasecmp(all_cache_fields[i].name, "hdr.", 4) != 0)
			continue;
		if (!mail_cache_field_want_add(_mail->transaction->cache_trans,
					       _mail->seq, i))
			continue;

		array_idx_set(&mail->header_match, all_cache_fields[i].idx,
			      &mail->header_match_value);
	}
}
Ejemplo n.º 5
0
static void
index_storage_get_status_cache_fields(struct mailbox *box,
				      struct mailbox_status *status_r)
{
	const struct mail_cache_field *fields;
	enum mail_cache_decision_type dec;
	ARRAY_TYPE(const_string) *cache_fields;
	unsigned int i, count;

	fields = mail_cache_register_get_list(box->cache,
					      pool_datastack_create(), &count);

	cache_fields = t_new(ARRAY_TYPE(const_string), 1);
	t_array_init(cache_fields, count);
	for (i = 0; i < count; i++) {
		dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
		if (dec != MAIL_CACHE_DECISION_NO)
			array_append(cache_fields, &fields[i].name, 1);
	}
	status_r->cache_fields = cache_fields;
}
Ejemplo n.º 6
0
static int maildir_get_pop3_state(struct index_mail *mail)
{
	struct mailbox *box = mail->mail.mail.box;
	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
	const struct mail_cache_field *fields;
	unsigned int i, count, psize_idx, vsize_idx;
	enum mail_cache_decision_type dec, vsize_dec;
	enum mail_fetch_field allowed_pop3_fields;
	bool not_pop3_only = FALSE;

	if (mail->pop3_state_set)
		return mail->pop3_state;

	/* if this mail itself has non-pop3 fields we know we're not
	   pop3-only */
	allowed_pop3_fields = MAIL_FETCH_FLAGS | MAIL_FETCH_STREAM_HEADER |
		MAIL_FETCH_STREAM_BODY | MAIL_FETCH_STORAGE_ID |
		MAIL_FETCH_VIRTUAL_SIZE;

	if (mail->data.wanted_headers != NULL ||
	    (mail->data.wanted_fields & ~allowed_pop3_fields) != 0)
		not_pop3_only = TRUE;

	/* get vsize decisions */
	psize_idx = ibox->cache_fields[MAIL_CACHE_PHYSICAL_FULL_SIZE].idx;
	vsize_idx = ibox->cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
	if (not_pop3_only) {
		vsize_dec = mail_cache_field_get_decision(box->cache,
							  vsize_idx);
		vsize_dec &= ~MAIL_CACHE_DECISION_FORCED;
	} else {
		/* also check if there are any non-[pv]size cached fields */
		vsize_dec = MAIL_CACHE_DECISION_NO;
		fields = mail_cache_register_get_list(box->cache,
						      pool_datastack_create(),
						      &count);
		for (i = 0; i < count; i++) {
			dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
			if (fields[i].idx == vsize_idx)
				vsize_dec = dec;
			else if (dec != MAIL_CACHE_DECISION_NO &&
				 fields[i].idx != psize_idx)
				not_pop3_only = TRUE;
		}
	}

	if (!not_pop3_only) {
		/* either nothing is cached, or only vsize is cached. */
		mail->pop3_state = 1;
	} else if (vsize_dec != MAIL_CACHE_DECISION_YES &&
		   (box->flags & MAILBOX_FLAG_POP3_SESSION) == 0) {
		/* if virtual size isn't cached permanently,
		   POP3 isn't being used */
		mail->pop3_state = -1;
	} else {
		/* possibly a mixed pop3/imap */
		mail->pop3_state = 0;
	}
	mail->pop3_state_set = TRUE;
	return mail->pop3_state;
}