Ejemplo n.º 1
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;

	node = array_append_space(nodes);
	node->seq = mail->seq;
	if (mail_get_date(mail, &node->date, NULL) < 0)
		node->date = 0;
	else if (node->date == 0) {
		if (mail_get_received_date(mail, &node->date) < 0)
			node->date = 0;
	}
}
Ejemplo n.º 2
0
static int
virtual_mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
{
	struct virtual_mail *vmail = (struct virtual_mail *)mail;
	int tz;

	if (timezone_r == NULL)
		timezone_r = &tz;

	if (virtual_mail_handle_lost(vmail) < 0)
		return -1;
	if (mail_get_date(vmail->backend_mail, date_r, timezone_r) < 0) {
		virtual_box_copy_error(mail->box, vmail->backend_mail->box);
		return -1;
	}
	return 0;
}
Ejemplo n.º 3
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.º 4
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.º 5
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;
	}
}