예제 #1
0
static int
cmd_deduplicate_box(struct doveadm_mail_cmd_context *_ctx,
		    const struct mailbox_info *info,
		    struct mail_search_args *search_args)
{
	struct deduplicate_cmd_context *ctx =
		(struct deduplicate_cmd_context *)_ctx;
	struct doveadm_mail_iter *iter;
	struct mailbox *box;
	struct mail *mail;
	enum mail_error error;
	pool_t pool;
	HASH_TABLE(const char *, struct uidlist *) hash;
	const char *key, *errstr;
	struct uidlist *value;
	int ret = 0;

	if (doveadm_mail_iter_init(_ctx, info, search_args, 0, NULL,
				   &iter) < 0)
		return -1;

	pool = pool_alloconly_create("deduplicate", 10240);
	hash_table_create(&hash, pool, 0, str_hash, strcmp);
	while (doveadm_mail_iter_next(iter, &mail)) {
		if (ctx->by_msgid) {
			if (mail_get_first_header(mail, "Message-ID", &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup Message-ID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		} else {
			if (mail_get_special(mail, MAIL_FETCH_GUID, &key) < 0) {
				errstr = mailbox_get_last_error(mail->box, &error);
				if (error == MAIL_ERROR_NOTFOUND)
					continue;
				i_error("Couldn't lookup GUID: for UID=%u: %s",
					mail->uid, errstr);
				doveadm_mail_failed_error(_ctx, error);
				ret = -1;
				break;
			}
		}
		if (key != NULL && *key != '\0') {
			value = p_new(pool, struct uidlist, 1);
			value->uid = mail->uid;
			value->next = hash_table_lookup(hash, key);

			if (value->next == NULL) {
				key = p_strdup(pool, key);
				hash_table_insert(hash, key, value);
			} else {
				hash_table_update(hash, key, value);
			}
		}
	}
예제 #2
0
파일: str-table.c 프로젝트: bdraco/core
const char *str_table_ref(struct str_table *table, const char *str)
{
	char *key;
	void *value;
	unsigned int ref;

	if (!hash_table_lookup_full(table->hash, str, &key, &value)) {
		key = i_strdup(str);
		ref = 1;
	} else {
		ref = POINTER_CAST_TO(value, unsigned int);
		i_assert(ref > 0);
		ref++;
	}
	hash_table_update(table->hash, key, POINTER_CAST(ref));
	return key;
}
예제 #3
0
파일: str-table.c 프로젝트: bdraco/core
void str_table_unref(struct str_table *table, const char **str)
{
	char *key;
	void *value;
	unsigned int ref;

	if (!hash_table_lookup_full(table->hash, *str, &key, &value))
		i_unreached();

	ref = POINTER_CAST_TO(value, unsigned int);
	i_assert(ref > 0);
	if (--ref > 0)
		hash_table_update(table->hash, key, POINTER_CAST(ref));
	else {
		hash_table_remove(table->hash, key);
		i_free(key);
	}
	*str = NULL;
}
예제 #4
0
static void stats_read(struct top_context *ctx)
{
	struct top_line *old_line, *line;
	unsigned int i;
	char **args;

	/* read lines */
	while ((args = p_read_next_line(ctx->cur_pool, ctx->input)) != NULL) {
		if (args[0] == NULL) {
			/* end of stats */
			return;
		}
		if (str_array_length((void *)args) != ctx->headers_count)
			i_fatal("read(%s): invalid stats line", ctx->path);

		line = p_new(ctx->cur_pool, struct top_line, 1);
		line->id = args[0];
		line->flip = ctx->flip;
		line->cur_values = p_new(ctx->cur_pool, const char *, ctx->headers_count);
		for (i = 0; i < ctx->headers_count; i++)
			line->cur_values[i] = args[i];

		old_line = hash_table_lookup(ctx->sessions, line->id);
		if (old_line != NULL) {
			stats_line_set_prev_values(ctx, old_line, line);
			array_append(&ctx->lines, &line, 1);
		}
		hash_table_update(ctx->sessions, line->id, line);
	}

	if (ctx->input->stream_errno != 0) {
		i_fatal("read(%s) failed: %s", ctx->path,
			i_stream_get_error(ctx->input));
	}
	i_fatal("read(%s): unexpected EOF", ctx->path);
}