NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
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.
void mutt_label_hash_add (struct Mailbox *m, struct Email *e)
 Add a message's labels to the Hash Table.
void mutt_label_hash_remove (struct Mailbox *m, struct Email *e)
 Remove a message's labels from the Hash Table.
int mutt_label_message (struct MailboxView *mv, struct EmailArray *ea)
 Let the user label a message.
void mutt_make_label_hash (struct Mailbox *m)
 Create a Hash Table to store the labels.

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 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 181 of file header.c.

183{
184 struct Buffer *path = buf_pool_get();
185 buf_mktemp_draft(path);
186 FILE *fp_out = mutt_file_fopen(buf_string(path), "w");
187 if (!fp_out)
188 {
189 mutt_perror("%s", buf_string(path));
190 goto cleanup;
191 }
192
195 false, false, NeoMutt->sub);
196 fputc('\n', fp_out); /* tie off the header. */
197
198 /* now copy the body of the message. */
199 FILE *fp_in = mutt_file_fopen(body, "r");
200 if (!fp_in)
201 {
202 mutt_perror("%s", body);
203 mutt_file_fclose(&fp_out);
205 goto cleanup;
206 }
207
208 mutt_file_copy_stream(fp_in, fp_out);
209
210 mutt_file_fclose(&fp_in);
211 mutt_file_fclose(&fp_out);
212
213 struct stat st = { 0 };
214 if (stat(buf_string(path), &st) == -1)
215 {
216 mutt_perror("%s", buf_string(path));
217 goto cleanup;
218 }
219
220 time_t mtime = mutt_file_decrease_mtime(buf_string(path), &st);
221 if (mtime == (time_t) -1)
222 {
223 mutt_perror("%s", buf_string(path));
224 goto cleanup;
225 }
226
227 mutt_edit_file(editor, buf_string(path));
228 if ((stat(buf_string(path), &st) != 0) || (mtime == st.st_mtime))
229 {
230 mutt_debug(LL_DEBUG1, "temp file was not modified\n");
231 /* the file has not changed! */
233 goto cleanup;
234 }
235
236 mutt_file_unlink(body);
238
239 /* Read the temp file back in */
240 fp_in = mutt_file_fopen(buf_string(path), "r");
241 if (!fp_in)
242 {
243 mutt_perror("%s", buf_string(path));
245 goto cleanup;
246 }
247
248 fp_out = mutt_file_fopen(body, "w");
249 if (!fp_out)
250 {
251 mutt_file_fclose(&fp_in);
253 mutt_perror("%s", body);
254 goto cleanup;
255 }
256
257 struct Envelope *env_new = NULL;
258 char buf[1024] = { 0 };
259 env_new = mutt_rfc822_read_header(fp_in, NULL, true, false);
260 int bytes_read;
261 while ((bytes_read = fread(buf, 1, sizeof(buf), fp_in)) > 0)
262 fwrite(buf, 1, bytes_read, fp_out);
263 mutt_file_fclose(&fp_out);
264 mutt_file_fclose(&fp_in);
266
267 /* in case the user modifies/removes the In-Reply-To header with
268 * $edit_headers set, we remove References: as they're likely invalid;
269 * we can simply compare strings as we don't generate References for
270 * multiple Message-IDs in IRT anyways */
271 if (!OptNewsSend)
272 {
273 if (!STAILQ_EMPTY(&e->env->in_reply_to) &&
274 (STAILQ_EMPTY(&env_new->in_reply_to) ||
275 !mutt_str_equal(STAILQ_FIRST(&env_new->in_reply_to)->data,
276 STAILQ_FIRST(&e->env->in_reply_to)->data)))
277 {
279 }
280 }
281
282 /* restore old info. */
283 mutt_list_free(&env_new->references);
284 STAILQ_SWAP(&env_new->references, &e->env->references, ListNode);
285
286 mutt_env_free(&e->env);
287 e->env = env_new;
288 env_new = NULL;
289
291
292 /* search through the user defined headers added to see if
293 * fcc: or attach: or pgp: or smime: was specified */
294
295 struct ListNode *np = NULL;
296 struct ListNode *tmp = NULL;
297 STAILQ_FOREACH_SAFE(np, &e->env->userhdrs, entries, tmp)
298 {
299 bool keep = true;
300 size_t plen = 0;
301
302 // Check for header names: most specific first
303 if (fcc && ((plen = mutt_istr_startswith(np->data, "X-Mutt-Fcc:")) ||
304 (plen = mutt_istr_startswith(np->data, "Mutt-Fcc:")) ||
305 (plen = mutt_istr_startswith(np->data, "fcc:"))))
306 {
307 const char *p = mutt_str_skip_email_wsp(np->data + plen);
308 if (*p)
309 {
310 buf_strcpy(fcc, p);
311 pretty_mailbox(fcc);
312 }
313 keep = false;
314 }
315 // Check for header names: most specific first
316 else if ((plen = mutt_istr_startswith(np->data, "X-Mutt-Attach:")) ||
317 (plen = mutt_istr_startswith(np->data, "Mutt-Attach:")) ||
318 (plen = mutt_istr_startswith(np->data, "attach:")))
319 {
320 struct Body *body2 = NULL;
321 struct Body *parts = NULL;
322
323 const char *p = mutt_str_skip_email_wsp(np->data + plen);
324 if (*p)
325 {
326 buf_reset(path);
327 for (; (p[0] != '\0') && (p[0] != ' ') && (p[0] != '\t'); p++)
328 {
329 if (p[0] == '\\')
330 {
331 if (p[1] == '\0')
332 break;
333 p++;
334 }
335 buf_addch(path, *p);
336 }
338
339 expand_path(path, false);
341 if (body2)
342 {
343 body2->description = mutt_str_dup(p);
344 for (parts = e->body; parts->next; parts = parts->next)
345 ; // do nothing
346
347 parts->next = body2;
348 }
349 else
350 {
351 pretty_mailbox(path);
352 mutt_error(_("%s: unable to attach file"), buf_string(path));
353 }
354 }
355 keep = false;
356 }
357 // Check for header names: most specific first
358 else if (((WithCrypto & APPLICATION_PGP) != 0) &&
359 ((plen = mutt_istr_startswith(np->data, "X-Mutt-PGP:")) ||
360 (plen = mutt_istr_startswith(np->data, "Mutt-PGP:")) ||
361 (plen = mutt_istr_startswith(np->data, "pgp:"))))
362 {
363 SecurityFlags sec = mutt_parse_crypt_hdr(np->data + plen, false, APPLICATION_PGP);
364 if (sec != SEC_NONE)
365 sec |= APPLICATION_PGP;
366 if (sec != e->security)
367 {
368 e->security = sec;
370 }
371 keep = false;
372 }
373 // Check for header names: most specific first
374 else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
375 ((plen = mutt_istr_startswith(np->data, "X-Mutt-SMIME:")) ||
376 (plen = mutt_istr_startswith(np->data, "Mutt-SMIME:")) ||
377 (plen = mutt_istr_startswith(np->data, "smime:"))))
378 {
380 if (sec != SEC_NONE)
381 sec |= APPLICATION_SMIME;
382 if (sec != e->security)
383 {
384 e->security = sec;
386 }
387 keep = false;
388 }
389
390 if (!keep)
391 {
392 STAILQ_REMOVE(&e->env->userhdrs, np, ListNode, entries);
393 FREE(&np->data);
394 FREE(&np);
395 }
396 }
397
398cleanup:
399 buf_pool_release(&path);
400}
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition alias.c:311
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition curs_lib.c:117
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition parse.c:1358
@ NT_EMAIL_CHANGE
Email has changed.
Definition email.h:186
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition envelope.c:125
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope's Address fields to local format.
Definition envelope.c:316
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition file.c:224
time_t mutt_file_decrease_mtime(const char *fp, struct stat *st)
Decrease a file's modification time by 1 second.
Definition file.c:898
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition file.c:156
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition globals.c:54
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define mutt_perror(...)
Definition logging2.h:95
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#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:173
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition string.c:614
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:246
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:431
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
uint16_t SecurityFlags
Definition lib.h:104
@ SEC_NONE
No flags are set.
Definition lib.h:91
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:107
#define WithCrypto
Definition lib.h:132
@ NT_EMAIL
Email has changed, NotifyEmail, EventEmail.
Definition notify_type.h:44
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition postpone.c:199
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FIRST(head)
Definition queue.h:388
#define STAILQ_EMPTY(head)
Definition queue.h:382
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
#define STAILQ_SWAP(head1, head2, type)
Definition queue.h:467
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *b, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject, struct ConfigSubset *sub)
Write out one RFC822 header line.
Definition header.c:584
@ MUTT_WRITE_HEADER_EDITHDRS
"light" mode (used for edit_hdrs)
Definition header.h:41
struct Body * mutt_make_file_attach(const char *path, struct ConfigSubset *sub)
Create a file attachment.
Definition sendlib.c:618
The body of an email.
Definition body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
char * description
content-description
Definition body.h:55
struct Body * next
next attachment in the list
Definition body.h:72
String manipulation buffer.
Definition buffer.h:36
struct Envelope * env
Envelope information.
Definition email.h:68
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct Body * body
List of MIME parts.
Definition email.h:69
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
The header of an Email.
Definition envelope.h:57
struct ListHead userhdrs
user defined headers
Definition envelope.h:85
struct ListHead references
message references (in reverse order)
Definition envelope.h:83
struct ListHead in_reply_to
in-reply-to header content
Definition envelope.h:84
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
#define buf_mktemp_draft(buf)
Definition tmp.h:34
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 418 of file header.c.

419{
420 if (!m || !m->label_hash)
421 return;
422 if (e->env->x_label)
423 label_ref_inc(m, e->env->x_label);
424}
static void label_ref_inc(struct Mailbox *m, char *label)
Increase the refcount of a label.
Definition header.c:83
char * x_label
X-Label.
Definition envelope.h:76
struct HashTable * label_hash
Hash Table: "X-Label" -> Email.
Definition mailbox.h:127
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 431 of file header.c.

432{
433 if (!m || !m->label_hash)
434 return;
435 if (e->env->x_label)
436 label_ref_dec(m, e->env->x_label);
437}
static void label_ref_dec(struct Mailbox *m, char *label)
Decrease the refcount of a label.
Definition header.c:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_label_message()

int mutt_label_message ( struct MailboxView * mv,
struct EmailArray * ea )

Let the user label a message.

Parameters
mvMailbox
eaArray of Emails to label
Return values
numNumber of messages changed

Definition at line 130 of file header.c.

131{
132 if (!mv || !mv->mailbox || !ea)
133 return 0;
134
135 struct Mailbox *m = mv->mailbox;
136
137 int changed = 0;
138 struct Buffer *buf = buf_pool_get();
139
140 struct Email **ep = ARRAY_GET(ea, 0);
141 if (ARRAY_SIZE(ea) == 1)
142 {
143 // If there's only one email, use its label as a template
144 struct Email *e = *ep;
145 if (e->env->x_label)
146 buf_strcpy(buf, e->env->x_label);
147 }
148
149 if (mw_get_field("Label: ", buf, MUTT_COMP_NONE, HC_OTHER, &CompleteLabelOps, NULL) != 0)
150 {
151 goto done;
152 }
153
154 char *new_label = buf->data;
155 SKIPWS(new_label);
156 if (*new_label == '\0')
157 new_label = NULL;
158
159 ARRAY_FOREACH(ep, ea)
160 {
161 struct Email *e = *ep;
162 if (label_message(m, e, new_label))
163 {
164 changed++;
165 email_set_color(m, e);
166 }
167 }
168
169done:
170 buf_pool_release(&buf);
171 return changed;
172}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
const struct CompleteOps CompleteLabelOps
Auto-Completion of Labels.
Definition helpers.c:541
void email_set_color(struct Mailbox *m, struct Email *e)
Select an Index colour for an Email.
Definition dlg_index.c:1431
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
static bool label_message(struct Mailbox *m, struct Email *e, char *new_label)
Add an X-Label: field.
Definition header.c:107
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:502
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:61
#define SKIPWS(ch)
Definition string2.h:52
char * data
Pointer to data.
Definition buffer.h:37
The envelope/body of an email.
Definition email.h:39
bool changed
Email has been edited.
Definition email.h:77
struct Mailbox * mailbox
Current Mailbox.
Definition mview.h:51
A mailbox.
Definition mailbox.h:81
bool changed
Mailbox has been modified.
Definition mailbox.h:112
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 406 of file header.c.

407{
408 /* 131 is just a rough prime estimate of how many distinct
409 * labels someone might have in a mailbox. */
411}
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys).
Definition hash.c:262
@ MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition hash.h:117
Here is the call graph for this function:
Here is the caller graph for this function: