Ejemplo n.º 1
0
int mail_save_copy_default_metadata(struct mail_save_context *ctx,
				    struct mail *mail)
{
	const char *from_envelope, *guid;
	time_t received_date;

	if (ctx->data.received_date == (time_t)-1) {
		if (mail_get_received_date(mail, &received_date) < 0) {
			mail_copy_set_failed(ctx, mail, "received-date");
			return -1;
		}
		mailbox_save_set_received_date(ctx, received_date, 0);
	}
	if (ctx->data.from_envelope == NULL) {
		if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE,
				     &from_envelope) < 0) {
			mail_copy_set_failed(ctx, mail, "from-envelope");
			return -1;
		}
		if (*from_envelope != '\0')
			mailbox_save_set_from_envelope(ctx, from_envelope);
	}
	if (ctx->data.guid == NULL) {
		if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) < 0) {
			mail_copy_set_failed(ctx, mail, "guid");
			return -1;
		}
		if (*guid != '\0')
			mailbox_save_set_guid(ctx, guid);
	}
	return 0;
}
Ejemplo n.º 2
0
static void
index_sort_list_add_arrival(struct mail_search_sort_program *program,
			    struct mail *mail)
{
	ARRAY_TYPE(mail_sort_node_date) *nodes = program->context;
	struct mail_sort_node_date *node;

	node = array_append_space(nodes);
	node->seq = mail->seq;
	if (mail_get_received_date(mail, &node->date) < 0)
		node->date = 0;
}
Ejemplo n.º 3
0
static int virtual_mail_get_received_date(struct mail *mail, time_t *date_r)
{
	struct virtual_mail *vmail = (struct virtual_mail *)mail;

	if (virtual_mail_handle_lost(vmail) < 0)
		return -1;
	if (mail_get_received_date(vmail->backend_mail, date_r) < 0) {
		virtual_box_copy_error(mail->box, vmail->backend_mail->box);
		return -1;
	}
	return 0;
}
Ejemplo n.º 4
0
static void
index_sort_list_add_date(struct mail_search_sort_program *program,
			 struct mail *mail)
{
	ARRAY_TYPE(mail_sort_node_date) *nodes = program->context;
	struct mail_sort_node_date *node;
	int tz;

	node = array_append_space(nodes);
	node->seq = mail->seq;
	if (mail_get_date(mail, &node->date, &tz) < 0)
		node->date = index_sort_program_set_date_failed(program, mail);
	else if (node->date == 0) {
		if (mail_get_received_date(mail, &node->date) < 0)
			node->date = index_sort_program_set_date_failed(program, mail);
	}
}
Ejemplo n.º 5
0
int dsync_mail_fill(struct mail *mail, struct dsync_mail *dmail_r,
		    const char **error_field_r)
{
	const char *guid, *str;

	memset(dmail_r, 0, sizeof(*dmail_r));

	if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) < 0) {
		*error_field_r = "GUID";
		return -1;
	}
	dmail_r->guid = guid;
	dmail_r->uid = mail->uid;

	dmail_r->input_mail = mail;
	dmail_r->input_mail_uid = mail->uid;
	if (mail_get_stream(mail, NULL, NULL, &dmail_r->input) < 0) {
		*error_field_r = "body";
		return -1;
	}

	if (mail_get_special(mail, MAIL_FETCH_UIDL_BACKEND, &dmail_r->pop3_uidl) < 0) {
		*error_field_r = "pop3-uidl";
		return -1;
	}
	if (mail_get_special(mail, MAIL_FETCH_POP3_ORDER, &str) < 0) {
		*error_field_r = "pop3-order";
		return -1;
	}
	if (*str != '\0') {
		if (str_to_uint(str, &dmail_r->pop3_order) < 0)
			i_unreached();
	}
	if (mail_get_received_date(mail, &dmail_r->received_date) < 0) {
		*error_field_r = "received-date";
		return -1;
	}
	return 0;
}
Ejemplo n.º 6
0
int index_sort_node_cmp_type(struct mail *mail,
			     const enum mail_sort_type *sort_program,
			     uint32_t seq1, uint32_t seq2)
{
	enum mail_sort_type sort_type;
	time_t time1, time2;
	uoff_t size1, size2;
	float float1, float2;
	int tz, ret = 0;

	sort_type = *sort_program & MAIL_SORT_MASK;
	switch (sort_type) {
	case MAIL_SORT_CC:
	case MAIL_SORT_FROM:
	case MAIL_SORT_TO:
	case MAIL_SORT_SUBJECT:
	case MAIL_SORT_DISPLAYFROM:
	case MAIL_SORT_DISPLAYTO:
		T_BEGIN {
			string_t *str1, *str2;

			str1 = t_str_new(256);
			str2 = t_str_new(256);
			(void)index_sort_header_get(mail, seq1, sort_type, str1);
			(void)index_sort_header_get(mail, seq2, sort_type, str2);

			ret = strcmp(str_c(str1), str_c(str2));
		} T_END;
		break;
	case MAIL_SORT_ARRIVAL:
		mail_set_seq(mail, seq1);
		if (mail_get_received_date(mail, &time1) < 0)
			time1 = 0;

		mail_set_seq(mail, seq2);
		if (mail_get_received_date(mail, &time2) < 0)
			time1 = 0;

		ret = time1 < time2 ? -1 :
			(time1 > time2 ? 1 : 0);
		break;
	case MAIL_SORT_DATE:
		mail_set_seq(mail, seq1);
		if (mail_get_date(mail, &time1, &tz) < 0)
			time1 = 0;
		else if (time1 == 0) {
			if (mail_get_received_date(mail, &time1) < 0)
				time1 = 0;
		}

		mail_set_seq(mail, seq2);
		if (mail_get_date(mail, &time2, &tz) < 0)
			time2 = 0;
		else if (time2 == 0) {
			if (mail_get_received_date(mail, &time2) < 0)
				time2 = 0;
		}

		ret = time1 < time2 ? -1 :
			(time1 > time2 ? 1 : 0);
		break;
	case MAIL_SORT_SIZE:
		mail_set_seq(mail, seq1);
		if (mail_get_virtual_size(mail, &size1) < 0)
			size1 = 0;

		mail_set_seq(mail, seq2);
		if (mail_get_virtual_size(mail, &size2) < 0)
			size2 = 0;

		ret = size1 < size2 ? -1 :
			(size1 > size2 ? 1 : 0);
		break;
	case MAIL_SORT_RELEVANCY:
		mail_set_seq(mail, seq1);
		float1 = index_sort_get_relevancy(mail);
		mail_set_seq(mail, seq2);
		float2 = index_sort_get_relevancy(mail);

		/* NOTE: higher relevancy is returned first, unlike with all
		   other number based sort keys */
		ret = float1 < float2 ? 1 :
			(float1 > float2 ? -1 : 0);
		break;
	case MAIL_SORT_POP3_ORDER:
		/* 32bit numbers would be enough, but since there is already
		   existing code for uoff_t in sizes, just use them. */
		mail_set_seq(mail, seq1);
		size1 = index_sort_get_pop3_order(mail);
		mail_set_seq(mail, seq2);
		size2 = index_sort_get_pop3_order(mail);

		ret = size1 < size2 ? -1 :
			(size1 > size2 ? 1 : 0);
		break;
	case MAIL_SORT_END:
		return seq1 < seq2 ? -1 :
			(seq1 > seq2 ? 1 : 0);
	case MAIL_SORT_MASK:
	case MAIL_SORT_FLAG_REVERSE:
		i_unreached();
	}

	if (ret == 0) {
		return index_sort_node_cmp_type(mail, sort_program+1,
						seq1, seq2);
	}

	if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0)
		ret = ret < 0 ? 1 : -1;
	return ret;
}
Ejemplo n.º 7
0
int index_sort_node_cmp_type(struct mail *mail,
			     const enum mail_sort_type *sort_program,
			     uint32_t seq1, uint32_t seq2)
{
	enum mail_sort_type sort_type;
	time_t time1, time2;
	uoff_t size1, size2;
	float float1, float2;
	int ret = 0;

	sort_type = *sort_program & MAIL_SORT_MASK;
	switch (sort_type) {
	case MAIL_SORT_CC:
	case MAIL_SORT_FROM:
	case MAIL_SORT_TO:
	case MAIL_SORT_SUBJECT:
	case MAIL_SORT_DISPLAYFROM:
	case MAIL_SORT_DISPLAYTO:
		T_BEGIN {
			string_t *str1, *str2;

			str1 = t_str_new(256);
			str2 = t_str_new(256);
			index_sort_header_get(mail, seq1, sort_type, str1);
			index_sort_header_get(mail, seq2, sort_type, str2);

			ret = strcmp(str_c(str1), str_c(str2));
		} T_END;
		break;
	case MAIL_SORT_ARRIVAL:
		mail_set_seq(mail, seq1);
		if (mail_get_received_date(mail, &time1) < 0)
			time1 = 0;

		mail_set_seq(mail, seq2);
		if (mail_get_received_date(mail, &time2) < 0)
			time1 = 0;

		ret = time1 < time2 ? -1 :
			(time1 > time2 ? 1 : 0);
		break;
	case MAIL_SORT_DATE:
		mail_set_seq(mail, seq1);
		if (mail_get_date(mail, &time1, NULL) < 0)
			time1 = 0;
		else if (time1 == 0) {
			if (mail_get_received_date(mail, &time1) < 0)
				time1 = 0;
		}

		mail_set_seq(mail, seq2);
		if (mail_get_date(mail, &time2, NULL) < 0)
			time2 = 0;
		else if (time2 == 0) {
			if (mail_get_received_date(mail, &time2) < 0)
				time2 = 0;
		}

		ret = time1 < time2 ? -1 :
			(time1 > time2 ? 1 : 0);
		break;
	case MAIL_SORT_SIZE:
		mail_set_seq(mail, seq1);
		if (mail_get_virtual_size(mail, &size1) < 0)
			size1 = 0;

		mail_set_seq(mail, seq2);
		if (mail_get_virtual_size(mail, &size2) < 0)
			size2 = 0;

		ret = size1 < size2 ? -1 :
			(size1 > size2 ? 1 : 0);
		break;
	case MAIL_SORT_SEARCH_SCORE:
		mail_set_seq(mail, seq1);
		float1 = index_sort_get_score(mail);
		mail_set_seq(mail, seq2);
		float2 = index_sort_get_score(mail);

		ret = float1 < float2 ? -1 :
			(float1 > float2 ? 1 : 0);
		break;
	case MAIL_SORT_END:
		return seq1 < seq2 ? -1 :
			(seq1 > seq2 ? 1 : 0);
	case MAIL_SORT_MASK:
	case MAIL_SORT_FLAG_REVERSE:
		i_unreached();
	}

	if (ret == 0) {
		return index_sort_node_cmp_type(mail, sort_program+1,
						seq1, seq2);
	}

	if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0)
		ret = ret < 0 ? 1 : -1;
	return ret;
}
Ejemplo n.º 8
0
/* Returns >0 = matched, 0 = not matched, -1 = unknown */
static int search_arg_match_cached(struct index_search_context *ctx,
				   struct mail_search_arg *arg)
{
	const char *str;
	struct tm *tm;
	uoff_t virtual_size;
	time_t date;
	int tz_offset;
	bool have_tz_offset;

	switch (arg->type) {
	/* internal dates */
	case SEARCH_BEFORE:
	case SEARCH_ON:
	case SEARCH_SINCE:
		have_tz_offset = FALSE; tz_offset = 0; date = (time_t)-1;
		switch (arg->value.date_type) {
		case MAIL_SEARCH_DATE_TYPE_SENT:
			if (mail_get_date(ctx->mail, &date, &tz_offset) < 0)
				return -1;
			have_tz_offset = TRUE;
			break;
		case MAIL_SEARCH_DATE_TYPE_RECEIVED:
			if (mail_get_received_date(ctx->mail, &date) < 0)
				return -1;
			break;
		case MAIL_SEARCH_DATE_TYPE_SAVED:
			if (mail_get_save_date(ctx->mail, &date) < 0)
				return -1;
			break;
		}

		if ((arg->value.search_flags &
		     MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) {
			if (!have_tz_offset) {
				tm = localtime(&date);
				tz_offset = utc_offset(tm, date);
			}
			date += tz_offset * 60;
		}

		switch (arg->type) {
		case SEARCH_BEFORE:
			return date < arg->value.time;
		case SEARCH_ON:
			return date >= arg->value.time &&
				date < arg->value.time + 3600*24;
		case SEARCH_SINCE:
			return date >= arg->value.time;
		default:
			/* unreachable */
			break;
		}

	/* sizes */
	case SEARCH_SMALLER:
	case SEARCH_LARGER:
		if (mail_get_virtual_size(ctx->mail, &virtual_size) < 0)
			return -1;

		if (arg->type == SEARCH_SMALLER)
			return virtual_size < arg->value.size;
		else
			return virtual_size > arg->value.size;

	case SEARCH_GUID:
		if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &str) < 0)
			return -1;
		return strcmp(str, arg->value.str) == 0;
	default:
		return -1;
	}
}