uncrustify.cfg: label indent, some known types, not, # and ##
[notmuch] / show-message.c
1 /* notmuch - Not much of an email program, (just index and search)
2  *
3  * Copyright © 2009 Carl Worth
4  * Copyright © 2009 Keith Packard
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see http://www.gnu.org/licenses/ .
18  *
19  * Authors: Carl Worth <cworth@cworth.org>
20  *          Keith Packard <keithp@keithp.com>
21  */
22
23 #include "notmuch-client.h"
24
25 typedef struct show_message_state {
26     int part_count;
27 } show_message_state_t;
28
29 static void
30 show_message_part (mime_node_t *node,
31                    show_message_state_t *state,
32                    const notmuch_show_format_t *format,
33                    int first)
34 {
35     /* Formatters expect the envelope for embedded message parts */
36     GMimeObject *part = node->envelope_part ?
37         GMIME_OBJECT (node->envelope_part) : node->part;
38     int i;
39
40     if (!first)
41         fputs (format->part_sep, stdout);
42
43     /* Format this part */
44     if (format->part_start)
45         format->part_start (part, &(state->part_count));
46
47     if (node->decrypt_attempted && format->part_encstatus)
48         format->part_encstatus (node->decrypt_success);
49
50     if (node->verify_attempted && format->part_sigstatus)
51 #ifdef GMIME_ATLEAST_26
52         format->part_sigstatus (node->sig_list);
53 #else
54         format->part_sigstatus (node->sig_validity);
55 #endif
56
57     format->part_content (part);
58
59     if (node->envelope_part) {
60         fputs (format->header_start, stdout);
61         if (format->header_message_part)
62             format->header_message_part (GMIME_MESSAGE (node->part));
63         fputs (format->header_end, stdout);
64
65         fputs (format->body_start, stdout);
66     }
67
68     /* Recurse over the children */
69     state->part_count += 1;
70     for (i = 0; i < node->nchildren; i++)
71         show_message_part (mime_node_child (node, i), state, format, i == 0);
72
73     /* Finish this part */
74     if (node->envelope_part)
75         fputs (format->body_end, stdout);
76
77     if (format->part_end)
78         format->part_end (part);
79 }
80
81 notmuch_status_t
82 show_message_body (notmuch_message_t *message,
83                    const notmuch_show_format_t *format,
84                    notmuch_show_params_t *params)
85 {
86     notmuch_status_t ret;
87     show_message_state_t state;
88     mime_node_t *root, *part;
89
90     ret = mime_node_open (NULL, message, params->cryptoctx, params->decrypt,
91                           &root);
92     if (ret)
93         return ret;
94
95     /* The caller of show_message_body has already handled the
96      * outermost envelope, so skip it. */
97     state.part_count = MAX (params->part, 1);
98
99     part = mime_node_seek_dfs (root, state.part_count);
100     if (part)
101         show_message_part (part, &state, format, TRUE);
102
103     talloc_free (root);
104
105     return NOTMUCH_STATUS_SUCCESS;
106 }