NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN
mutt_header.h File Reference

Representation of the email's header. More...

+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void mutt_edit_headers (const char *editor, const char *body, struct Email *e, struct Buffer *fcc)
 Let the user edit the message header and body. More...
 
void mutt_label_hash_add (struct Mailbox *m, struct Email *e)
 Add a message's labels to the Hash Table. More...
 
void mutt_label_hash_remove (struct Mailbox *m, struct Email *e)
 Remove a message's labels from the Hash Table. More...
 
int mutt_label_message (struct Mailbox *m, struct EmailList *el)
 Let the user label a message. More...
 
void mutt_make_label_hash (struct Mailbox *m)
 Create a Hash Table to store the labels. More...
 

Detailed Description

Representation of the email's header.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file mutt_header.h.

Function Documentation

◆ mutt_edit_headers()

void mutt_edit_headers ( const char *  editor,
const char *  body,
struct Email e,
struct Buffer fcc 
)

Let the user edit the message header and body.

Parameters
editorEditor command
bodyFile containing message body
eEmail
fccBuffer for the fcc field

Definition at line 172 of file mutt_header.c.

174{
175 struct Buffer *path = mutt_buffer_pool_get();
176 mutt_buffer_mktemp(path);
177 FILE *fp_out = mutt_file_fopen(mutt_buffer_string(path), "w");
178 if (!fp_out)
179 {
181 goto cleanup;
182 }
183
186 false, false, NeoMutt->sub);
187 fputc('\n', fp_out); /* tie off the header. */
188
189 /* now copy the body of the message. */
190 FILE *fp_in = fopen(body, "r");
191 if (!fp_in)
192 {
193 mutt_perror(body);
194 mutt_file_fclose(&fp_out);
195 goto cleanup;
196 }
197
198 mutt_file_copy_stream(fp_in, fp_out);
199
200 mutt_file_fclose(&fp_in);
201 mutt_file_fclose(&fp_out);
202
203 struct stat st = { 0 };
204 if (stat(mutt_buffer_string(path), &st) == -1)
205 {
207 goto cleanup;
208 }
209
210 time_t mtime = mutt_file_decrease_mtime(mutt_buffer_string(path), &st);
211 if (mtime == (time_t) -1)
212 {
214 goto cleanup;
215 }
216
217 mutt_edit_file(editor, mutt_buffer_string(path));
218 if ((stat(mutt_buffer_string(path), &st) != 0) || (mtime == st.st_mtime))
219 {
220 mutt_debug(LL_DEBUG1, "temp file was not modified\n");
221 /* the file has not changed! */
223 goto cleanup;
224 }
225
226 mutt_file_unlink(body);
228
229 /* Read the temp file back in */
230 fp_in = fopen(mutt_buffer_string(path), "r");
231 if (!fp_in)
232 {
234 goto cleanup;
235 }
236
237 fp_out = mutt_file_fopen(body, "w");
238 if (!fp_out)
239 {
240 /* intentionally leak a possible temporary file here */
241 mutt_file_fclose(&fp_in);
242 mutt_perror(body);
243 goto cleanup;
244 }
245
246 struct Envelope *env_new = NULL;
247 char buf[1024] = { 0 };
248 env_new = mutt_rfc822_read_header(fp_in, NULL, true, false);
249 int bytes_read;
250 while ((bytes_read = fread(buf, 1, sizeof(buf), fp_in)) > 0)
251 fwrite(buf, 1, bytes_read, fp_out);
252 mutt_file_fclose(&fp_out);
253 mutt_file_fclose(&fp_in);
255
256 /* in case the user modifies/removes the In-Reply-To header with
257 * $edit_headers set, we remove References: as they're likely invalid;
258 * we can simply compare strings as we don't generate References for
259 * multiple Message-Ids in IRT anyways */
260#ifdef USE_NNTP
261 if (!OptNewsSend)
262#endif
263 {
264 if (!STAILQ_EMPTY(&e->env->in_reply_to) &&
265 (STAILQ_EMPTY(&env_new->in_reply_to) ||
266 !mutt_str_equal(STAILQ_FIRST(&env_new->in_reply_to)->data,
267 STAILQ_FIRST(&e->env->in_reply_to)->data)))
268 {
270 }
271 }
272
273 /* restore old info. */
274 mutt_list_free(&env_new->references);
275 STAILQ_SWAP(&env_new->references, &e->env->references, ListNode);
276
277 mutt_env_free(&e->env);
278 e->env = env_new;
279 env_new = NULL;
280
282
283 /* search through the user defined headers added to see if
284 * fcc: or attach: or pgp: was specified */
285
286 struct ListNode *np = NULL, *tmp = NULL;
287 STAILQ_FOREACH_SAFE(np, &e->env->userhdrs, entries, tmp)
288 {
289 bool keep = true;
290 size_t plen;
291
292 if (fcc && (plen = mutt_istr_startswith(np->data, "fcc:")))
293 {
294 const char *p = mutt_str_skip_email_wsp(np->data + plen);
295 if (*p)
296 {
297 mutt_buffer_strcpy(fcc, p);
299 }
300 keep = false;
301 }
302 else if ((plen = mutt_istr_startswith(np->data, "attach:")))
303 {
304 struct Body *body2 = NULL;
305 struct Body *parts = NULL;
306
307 const char *p = mutt_str_skip_email_wsp(np->data + plen);
308 if (*p)
309 {
310 mutt_buffer_reset(path);
311 for (; (p[0] != '\0') && (p[0] != ' ') && (p[0] != '\t'); p++)
312 {
313 if (p[0] == '\\')
314 {
315 if (p[1] == '\0')
316 break;
317 p++;
318 }
319 mutt_buffer_addch(path, *p);
320 }
322
325 if (body2)
326 {
327 body2->description = mutt_str_dup(p);
328 for (parts = e->body; parts->next; parts = parts->next)
329 ; // do nothing
330
331 parts->next = body2;
332 }
333 else
334 {
336 mutt_error(_("%s: unable to attach file"), mutt_buffer_string(path));
337 }
338 }
339 keep = false;
340 }
341 else if (((WithCrypto & APPLICATION_PGP) != 0) &&
342 (plen = mutt_istr_startswith(np->data, "pgp:")))
343 {
345 if (sec != SEC_NO_FLAGS)
346 sec |= APPLICATION_PGP;
347 if (sec != e->security)
348 {
349 e->security = sec;
351 }
352 keep = false;
353 }
354
355 if (!keep)
356 {
357 STAILQ_REMOVE(&e->env->userhdrs, np, ListNode, entries);
358 FREE(&np->data);
359 FREE(&np);
360 }
361 }
362
363cleanup:
365}
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:312
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:312
@ NT_EMAIL_CHANGE
Email has changed.
Definition: email.h:150
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:97
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope's Address fields to local format.
Definition: envelope.c:288
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:260
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
time_t mutt_file_decrease_mtime(const char *fp, struct stat *st)
Decrease a file's modification time by 1 second.
Definition: file.c:1019
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
#define mutt_error(...)
Definition: logging.h:87
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
#define mutt_perror(...)
Definition: logging.h:88
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition: header.c:572
@ MUTT_WRITE_HEADER_EDITHDRS
"light" mode (used for edit_hdrs)
Definition: header.h:43
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:43
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:679
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:599
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:76
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:77
#define WithCrypto
Definition: lib.h:116
@ NT_EMAIL
Email has changed, NotifyEmail, EventEmail.
Definition: notify_type.h:44
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:51
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition: parse.c:1158
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition: postpone.c:210
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
#define STAILQ_SWAP(head1, head2, type)
Definition: queue.h:428
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition: sendlib.c:598
The body of an email.
Definition: body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
char * description
content-description
Definition: body.h:55
struct Body * next
next attachment in the list
Definition: body.h:71
String manipulation buffer.
Definition: buffer.h:34
struct Envelope * env
Envelope information.
Definition: email.h:66
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct Body * body
List of MIME parts.
Definition: email.h:67
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition: email.h:71
The header of an Email.
Definition: envelope.h:57
struct ListHead userhdrs
user defined headers
Definition: envelope.h:87
struct ListHead references
message references (in reverse order)
Definition: envelope.h:85
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:86
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_label_hash_add()

void mutt_label_hash_add ( struct Mailbox m,
struct Email e 
)

Add a message's labels to the Hash Table.

Parameters
mMailbox
eEmail

Definition at line 383 of file mutt_header.c.

384{
385 if (!m || !m->label_hash)
386 return;
387 if (e->env->x_label)
388 label_ref_inc(m, e->env->x_label);
389}
static void label_ref_inc(struct Mailbox *m, char *label)
Increase the refcount of a label.
Definition: mutt_header.c:77
char * x_label
X-Label.
Definition: envelope.h:76
struct HashTable * label_hash
Hash Table for x-labels.
Definition: mailbox.h:125
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_label_hash_remove()

void mutt_label_hash_remove ( struct Mailbox m,
struct Email e 
)

Remove a message's labels from the Hash Table.

Parameters
mMailbox
eEmail

Definition at line 396 of file mutt_header.c.

397{
398 if (!m || !m->label_hash)
399 return;
400 if (e->env->x_label)
401 label_ref_dec(m, e->env->x_label);
402}
static void label_ref_dec(struct Mailbox *m, char *label)
Decrease the refcount of a label.
Definition: mutt_header.c:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_label_message()

int mutt_label_message ( struct Mailbox m,
struct EmailList *  el 
)

Let the user label a message.

Parameters
mMailbox
elList of Emails to label
Return values
numNumber of messages changed

Definition at line 124 of file mutt_header.c.

125{
126 if (!m || !el)
127 return 0;
128
129 int changed = 0;
130 struct Buffer *buf = mutt_buffer_pool_get();
131
132 struct EmailNode *en = STAILQ_FIRST(el);
133 if (!STAILQ_NEXT(en, entries))
134 {
135 // If there's only one email, use its label as a template
136 if (en->email->env->x_label)
138 }
139
140 if (mutt_buffer_get_field("Label: ", buf, MUTT_COMP_LABEL /* | MUTT_COMP_CLEAR */,
141 false, NULL, NULL, NULL) != 0)
142 {
143 goto done;
144 }
145
146 char *new_label = buf->data;
147 SKIPWS(new_label);
148 if (*new_label == '\0')
149 new_label = NULL;
150
151 STAILQ_FOREACH(en, el, entries)
152 {
153 if (label_message(m, en->email, new_label))
154 {
155 changed++;
157 }
158 }
159
160done:
162 return changed;
163}
void mutt_set_header_color(struct Mailbox *m, struct Email *e)
Select a colour for a message.
Definition: dlg_index.c:1366
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: window.c:180
#define MUTT_COMP_LABEL
Label completion.
Definition: mutt.h:58
static bool label_message(struct Mailbox *m, struct Email *e, char *new_label)
Add an X-Label: field.
Definition: mutt_header.c:101
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
#define SKIPWS(ch)
Definition: string2.h:46
char * data
Pointer to data.
Definition: buffer.h:35
List of Emails.
Definition: email.h:131
struct Email * email
Email in the list.
Definition: email.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_label_hash()

void mutt_make_label_hash ( struct Mailbox m)

Create a Hash Table to store the labels.

Parameters
mMailbox

Definition at line 371 of file mutt_header.c.

372{
373 /* 131 is just a rough prime estimate of how many distinct
374 * labels someone might have in a m. */
376}
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:111
+ Here is the call graph for this function:
+ Here is the caller graph for this function: