Пример #1
0
/* Return the number of files matching the query, or -1 for an error */
static int
count_files (notmuch_query_t *query)
{
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    notmuch_filenames_t *filenames;
    notmuch_status_t status;
    int count = 0;

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch count", query, status))
        return -1;

    for (;
            notmuch_messages_valid (messages);
            notmuch_messages_move_to_next (messages)) {
        message = notmuch_messages_get (messages);
        filenames = notmuch_message_get_filenames (message);

        for (;
                notmuch_filenames_valid (filenames);
                notmuch_filenames_move_to_next (filenames))
            count++;

        notmuch_filenames_destroy (filenames);
        notmuch_message_destroy (message);
    }

    notmuch_messages_destroy (messages);

    return count;
}
Пример #2
0
static int
notmuch_reply_format_sprinter(void *ctx,
			      notmuch_config_t *config,
			      notmuch_query_t *query,
			      notmuch_show_params_t *params,
			      notmuch_bool_t reply_all,
			      sprinter_t *sp)
{
    GMimeMessage *reply;
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    mime_node_t *node;
    unsigned count;
    notmuch_status_t status;

    status = notmuch_query_count_messages_st (query, &count);
    if (print_status_query ("notmuch reply", query, status))
	return 1;

    if (count != 1) {
	fprintf (stderr, "Error: search term did not match precisely one message.\n");
	return 1;
    }

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch reply", query, status))
	return 1;

    message = notmuch_messages_get (messages);
    if (mime_node_open (ctx, message, &(params->crypto), &node) != NOTMUCH_STATUS_SUCCESS)
	return 1;

    reply = create_reply_message (ctx, config, message, reply_all);
    if (!reply)
	return 1;

    sp->begin_map (sp);

    /* The headers of the reply message we've created */
    sp->map_key (sp, "reply-headers");
    format_headers_sprinter (sp, reply, TRUE);
    g_object_unref (G_OBJECT (reply));
    reply = NULL;

    /* Start the original */
    sp->map_key (sp, "original");
    format_part_sprinter (ctx, sp, node, TRUE, TRUE, FALSE);

    /* End */
    sp->end (sp);
    notmuch_message_destroy (message);

    return 0;
}
Пример #3
0
static int
do_search_tags (const search_context_t *ctx)
{
    notmuch_messages_t *messages = NULL;
    notmuch_tags_t *tags;
    const char *tag;
    sprinter_t *format = ctx->format;
    notmuch_query_t *query = ctx->query;
    notmuch_database_t *notmuch = ctx->notmuch;

    /* should the following only special case if no excluded terms
     * specified? */

    /* Special-case query of "*" for better performance. */
    if (strcmp (notmuch_query_get_query_string (query), "*") == 0) {
	tags = notmuch_database_get_all_tags (notmuch);
    } else {
	notmuch_status_t status;
	status = notmuch_query_search_messages_st (query, &messages);
	if (print_status_query ("notmuch search", query, status))
	    return 1;

	tags = notmuch_messages_collect_tags (messages);
    }
    if (tags == NULL)
	return 1;

    format->begin_list (format);

    for (;
	 notmuch_tags_valid (tags);
	 notmuch_tags_move_to_next (tags))
    {
	tag = notmuch_tags_get (tags);

	format->string (format, tag);
	format->separator (format);

    }

    notmuch_tags_destroy (tags);

    if (messages)
	notmuch_messages_destroy (messages);

    format->end (format);

    return 0;
}
Пример #4
0
static int
notmuch_reply_format_default(void *ctx,
			     notmuch_config_t *config,
			     notmuch_query_t *query,
			     notmuch_show_params_t *params,
			     notmuch_bool_t reply_all,
			     unused (sprinter_t *sp))
{
    GMimeMessage *reply;
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    mime_node_t *root;
    notmuch_status_t status;

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch reply", query, status))
	return 1;

    for (;
	 notmuch_messages_valid (messages);
	 notmuch_messages_move_to_next (messages))
    {
	message = notmuch_messages_get (messages);

	reply = create_reply_message (ctx, config, message, reply_all);

	/* If reply creation failed, we're out of memory, so don't
	 * bother trying any more messages.
	 */
	if (!reply) {
	    notmuch_message_destroy (message);
	    return 1;
	}

	show_reply_headers (reply);

	g_object_unref (G_OBJECT (reply));
	reply = NULL;

	if (mime_node_open (ctx, message, &(params->crypto), &root) == NOTMUCH_STATUS_SUCCESS) {
	    format_part_reply (root);
	    talloc_free (root);
	}

	notmuch_message_destroy (message);
    }
    return 0;
}
Пример #5
0
/* Formatted output of single message */
static int
do_show_single (void *ctx,
		notmuch_query_t *query,
		const notmuch_show_format_t *format,
		sprinter_t *sp,
		notmuch_show_params_t *params)
{
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    notmuch_status_t status;
    unsigned int count;

    status = notmuch_query_count_messages_st (query, &count);
    if (print_status_query ("notmuch show", query, status))
	return 1;

    if (count != 1) {
	fprintf (stderr, "Error: search term did not match precisely one message.\n");
	return 1;
    }

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch show", query, status))
	return 1;

    message = notmuch_messages_get (messages);

    if (message == NULL) {
	fprintf (stderr, "Error: Cannot find matching message.\n");
	return 1;
    }

    notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH, 1);

    return show_message (ctx, format, sp, message, 0, params)
	!= NOTMUCH_STATUS_SUCCESS;
}
Пример #6
0
/* This format is currently tuned for a git send-email --notmuch hook */
static int
notmuch_reply_format_headers_only(void *ctx,
				  notmuch_config_t *config,
				  notmuch_query_t *query,
				  unused (notmuch_show_params_t *params),
				  notmuch_bool_t reply_all,
				  unused (sprinter_t *sp))
{
    GMimeMessage *reply;
    notmuch_messages_t *messages;
    notmuch_message_t *message;
    const char *in_reply_to, *orig_references, *references;
    char *reply_headers;
    notmuch_status_t status;

    status = notmuch_query_search_messages_st (query, &messages);
    if (print_status_query ("notmuch reply", query, status))
	return 1;

    for (;
	 notmuch_messages_valid (messages);
	 notmuch_messages_move_to_next (messages))
    {
	message = notmuch_messages_get (messages);

	/* The 0 means we do not want headers in a "pretty" order. */
	reply = g_mime_message_new (0);
	if (reply == NULL) {
	    fprintf (stderr, "Out of memory\n");
	    return 1;
	}

	in_reply_to = talloc_asprintf (ctx, "<%s>",
			     notmuch_message_get_message_id (message));

        g_mime_object_set_header (GMIME_OBJECT (reply),
				  "In-Reply-To", in_reply_to);


	orig_references = notmuch_message_get_header (message, "references");

	/* We print In-Reply-To followed by References because git format-patch treats them
         * specially.  Git does not interpret the other headers specially
	 */
	references = talloc_asprintf (ctx, "%s%s%s",
				      orig_references ? orig_references : "",
				      orig_references ? " " : "",
				      in_reply_to);
	g_mime_object_set_header (GMIME_OBJECT (reply),
				  "References", references);

	(void)add_recipients_from_message (reply, config, message, reply_all);

	reply_headers = g_mime_object_to_string (GMIME_OBJECT (reply));
	printf ("%s", reply_headers);
	free (reply_headers);

	g_object_unref (G_OBJECT (reply));
	reply = NULL;

	notmuch_message_destroy (message);
    }
    return 0;
}
Пример #7
0
static int
do_search_messages (search_context_t *ctx)
{
    notmuch_message_t *message;
    notmuch_messages_t *messages;
    notmuch_filenames_t *filenames;
    sprinter_t *format = ctx->format;
    int i;
    notmuch_status_t status;

    if (ctx->offset < 0) {
	unsigned count;
	notmuch_status_t status;
	status = notmuch_query_count_messages_st (ctx->query, &count);
	if (print_status_query ("notmuch search", ctx->query, status))
	    return 1;

	ctx->offset += count;
	if (ctx->offset < 0)
	    ctx->offset = 0;
    }

    status = notmuch_query_search_messages_st (ctx->query, &messages);
    if (print_status_query ("notmuch search", ctx->query, status))
	return 1;

    format->begin_list (format);

    for (i = 0;
	 notmuch_messages_valid (messages) && (ctx->limit < 0 || i < ctx->offset + ctx->limit);
	 notmuch_messages_move_to_next (messages), i++)
    {
	if (i < ctx->offset)
	    continue;

	message = notmuch_messages_get (messages);

	if (ctx->output == OUTPUT_FILES) {
	    int j;
	    filenames = notmuch_message_get_filenames (message);

	    for (j = 1;
		 notmuch_filenames_valid (filenames);
		 notmuch_filenames_move_to_next (filenames), j++)
	    {
		if (ctx->dupe < 0 || ctx->dupe == j) {
		    format->string (format, notmuch_filenames_get (filenames));
		    format->separator (format);
		}
	    }
	    
	    notmuch_filenames_destroy( filenames );

	} else if (ctx->output == OUTPUT_MESSAGES) {
            /* special case 1 for speed */
            if (ctx->dupe <= 1 || ctx->dupe <= _count_filenames (message)) {
                format->set_prefix (format, "id");
                format->string (format,
                                notmuch_message_get_message_id (message));
                format->separator (format);
            }
	} else {
	    if (ctx->output & OUTPUT_SENDER) {
		const char *addrs;

		addrs = notmuch_message_get_header (message, "from");
		process_address_header (ctx, addrs);
	    }

	    if (ctx->output & OUTPUT_RECIPIENTS) {
		const char *hdrs[] = { "to", "cc", "bcc" };
		const char *addrs;
		size_t j;

		for (j = 0; j < ARRAY_SIZE (hdrs); j++) {
		    addrs = notmuch_message_get_header (message, hdrs[j]);
		    process_address_header (ctx, addrs);
		}
	    }
	}

	notmuch_message_destroy (message);
    }

    if (ctx->addresses &&
	(ctx->output & OUTPUT_COUNT || ctx->dedup == DEDUP_ADDRESS))
	g_hash_table_foreach (ctx->addresses, print_hash_value, ctx);

    notmuch_messages_destroy (messages);

    format->end (format);

    return 0;
}