NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
header.h File Reference

Convenience wrapper for the send headers. More...

#include <stdbool.h>
#include <stdio.h>
#include "copy.h"
+ Include dependency graph for header.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  MuttWriteHeaderMode {
  MUTT_WRITE_HEADER_NORMAL , MUTT_WRITE_HEADER_FCC , MUTT_WRITE_HEADER_POSTPONE , MUTT_WRITE_HEADER_EDITHDRS ,
  MUTT_WRITE_HEADER_MIME
}
 Modes for mutt_rfc822_write_header() More...
 

Functions

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.
 
int mutt_write_mime_header (struct Body *b, FILE *fp, struct ConfigSubset *sub)
 Create a MIME header.
 
int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
 Write one header line to a file.
 
void mutt_write_references (const struct ListHead *r, FILE *fp, size_t trim)
 Add the message references to a list.
 

Detailed Description

Convenience wrapper for the send headers.

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.

Enumeration Type Documentation

◆ MuttWriteHeaderMode

Modes for mutt_rfc822_write_header()

Enumerator
MUTT_WRITE_HEADER_NORMAL 

A normal Email, write full header + MIME headers.

MUTT_WRITE_HEADER_FCC 

fcc mode, like normal mode but for Bcc header

MUTT_WRITE_HEADER_POSTPONE 

A postponed Email, just the envelope info.

MUTT_WRITE_HEADER_EDITHDRS 

"light" mode (used for edit_hdrs)

MUTT_WRITE_HEADER_MIME 

Write protected headers.

Definition at line 38 of file header.h.

39{
45};
@ MUTT_WRITE_HEADER_FCC
fcc mode, like normal mode but for Bcc header
Definition: header.h:41
@ MUTT_WRITE_HEADER_MIME
Write protected headers.
Definition: header.h:44
@ MUTT_WRITE_HEADER_NORMAL
A normal Email, write full header + MIME headers.
Definition: header.h:40
@ MUTT_WRITE_HEADER_POSTPONE
A postponed Email, just the envelope info.
Definition: header.h:42
@ MUTT_WRITE_HEADER_EDITHDRS
"light" mode (used for edit_hdrs)
Definition: header.h:43

Function Documentation

◆ mutt_rfc822_write_header()

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.

Parameters
fpFile to write to
envEnvelope of email
bAttachment
modeMode, see MuttWriteHeaderMode
privacyIf true, remove headers that might identify the user
hide_protected_subjectIf true, replace subject header
subConfig Subset
Return values
0Success
-1Failure
Note
All RFC2047 encoding should be done outside of this routine, except for the "real name." This will allow this routine to be used more than once, if necessary.

Likewise, all IDN processing should happen outside of this routine.

privacy true => will omit any headers which may identify the user. Output generated is suitable for being sent through anonymous remailer chains.

hide_protected_subject: replaces the Subject header with $crypt_protected_headers_subject in NORMAL or POSTPONE mode.

Definition at line 577 of file header.c.

580{
581 if (((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC) ||
582 (mode == MUTT_WRITE_HEADER_POSTPONE)) &&
583 !privacy)
584 {
585 struct Buffer *date = buf_pool_get();
586 mutt_date_make_date(date, cs_subset_bool(sub, "local_date_header"));
587 fprintf(fp, "Date: %s\n", buf_string(date));
588 buf_pool_release(&date);
589 }
590
591 /* UseFrom is not consulted here so that we can still write a From:
592 * field if the user sets it with the 'my_hdr' command */
593 if (!TAILQ_EMPTY(&env->from) && !privacy)
594 {
595 mutt_addrlist_write_file(&env->from, fp, "From");
596 }
597
598 if (!TAILQ_EMPTY(&env->sender) && !privacy)
599 {
600 mutt_addrlist_write_file(&env->sender, fp, "Sender");
601 }
602
603 if (!TAILQ_EMPTY(&env->to))
604 {
605 mutt_addrlist_write_file(&env->to, fp, "To");
606 }
607 else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
608 {
609 if (!OptNewsSend)
610 fputs("To:\n", fp);
611 }
612
613 if (!TAILQ_EMPTY(&env->cc))
614 {
615 mutt_addrlist_write_file(&env->cc, fp, "Cc");
616 }
617 else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
618 {
619 if (!OptNewsSend)
620 fputs("Cc:\n", fp);
621 }
622
623 if (!TAILQ_EMPTY(&env->bcc))
624 {
625 const bool c_write_bcc = cs_subset_bool(sub, "write_bcc");
626
627 if ((mode == MUTT_WRITE_HEADER_POSTPONE) ||
628 (mode == MUTT_WRITE_HEADER_EDITHDRS) || (mode == MUTT_WRITE_HEADER_FCC) ||
629 ((mode == MUTT_WRITE_HEADER_NORMAL) && c_write_bcc))
630 {
631 mutt_addrlist_write_file(&env->bcc, fp, "Bcc");
632 }
633 }
634 else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
635 {
636 if (!OptNewsSend)
637 fputs("Bcc:\n", fp);
638 }
639
640 if (env->newsgroups)
641 fprintf(fp, "Newsgroups: %s\n", env->newsgroups);
642 else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend)
643 fputs("Newsgroups:\n", fp);
644
645 if (env->followup_to)
646 fprintf(fp, "Followup-To: %s\n", env->followup_to);
647 else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend)
648 fputs("Followup-To:\n", fp);
649
650 const bool c_x_comment_to = cs_subset_bool(sub, "x_comment_to");
651 if (env->x_comment_to)
652 fprintf(fp, "X-Comment-To: %s\n", env->x_comment_to);
653 else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend && c_x_comment_to)
654 fputs("X-Comment-To:\n", fp);
655
656 if (env->subject)
657 {
658 if (hide_protected_subject &&
659 ((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC) ||
661 {
662 const char *const c_crypt_protected_headers_subject = cs_subset_string(sub, "crypt_protected_headers_subject");
663 mutt_write_one_header(fp, "Subject", c_crypt_protected_headers_subject,
664 NULL, 0, CH_NO_FLAGS, sub);
665 }
666 else
667 {
668 mutt_write_one_header(fp, "Subject", env->subject, NULL, 0, CH_NO_FLAGS, sub);
669 }
670 }
671 else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
672 {
673 fputs("Subject:\n", fp);
674 }
675
676 /* save message id if the user has set it */
677 if (env->message_id && !privacy)
678 fprintf(fp, "Message-ID: %s\n", env->message_id);
679
680 if (!TAILQ_EMPTY(&env->reply_to))
681 {
682 mutt_addrlist_write_file(&env->reply_to, fp, "Reply-To");
683 }
684 else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
685 {
686 fputs("Reply-To:\n", fp);
687 }
688
689 if (!TAILQ_EMPTY(&env->mail_followup_to))
690 {
691 if (!OptNewsSend)
692 {
693 mutt_addrlist_write_file(&env->mail_followup_to, fp, "Mail-Followup-To");
694 }
695 }
696
697 /* Add any user defined headers */
698 struct UserHdrsOverride userhdrs_overrides = write_userhdrs(fp, &env->userhdrs,
699 privacy, sub);
700
701 if ((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC) ||
703 {
704 if (!STAILQ_EMPTY(&env->references))
705 {
706 fputs("References:", fp);
707 mutt_write_references(&env->references, fp, 10);
708 fputc('\n', fp);
709 }
710
711 /* Add the MIME headers */
712 if (!userhdrs_overrides.is_overridden[USERHDRS_OVERRIDE_CONTENT_TYPE])
713 {
714 fputs("MIME-Version: 1.0\n", fp);
715 mutt_write_mime_header(b, fp, sub);
716 }
717 }
718
719 if (!STAILQ_EMPTY(&env->in_reply_to))
720 {
721 fputs("In-Reply-To:", fp);
723 fputc('\n', fp);
724 }
725
726#ifdef USE_AUTOCRYPT
727 const bool c_autocrypt = cs_subset_bool(sub, "autocrypt");
728 if (c_autocrypt)
729 {
730 if (mode == MUTT_WRITE_HEADER_NORMAL || mode == MUTT_WRITE_HEADER_FCC)
732 if (mode == MUTT_WRITE_HEADER_MIME)
734 }
735#endif
736
737 const bool c_user_agent = cs_subset_bool(sub, "user_agent");
738 if (((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC)) && !privacy &&
739 c_user_agent && !userhdrs_overrides.is_overridden[USERHDRS_OVERRIDE_USER_AGENT])
740 {
741 /* Add a vanity header */
742 fprintf(fp, "User-Agent: NeoMutt/%s%s\n", PACKAGE_VERSION, GitVer);
743 }
744
745 return (ferror(fp) == 0) ? 0 : -1;
746}
void mutt_addrlist_write_file(const struct AddressList *al, FILE *fp, const char *header)
Wrapper for mutt_write_address()
Definition: address.c:1248
int mutt_autocrypt_write_gossip_headers(struct Envelope *env, FILE *fp)
Write the Autocrypt gossip headers to a file.
Definition: autocrypt.c:801
int mutt_autocrypt_write_autocrypt_header(struct Envelope *env, FILE *fp)
Write the Autocrypt header to a file.
Definition: autocrypt.c:763
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:53
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: globals.c:68
const char * GitVer
static struct UserHdrsOverride write_userhdrs(FILE *fp, const struct ListHead *userhdrs, bool privacy, struct ConfigSubset *sub)
Write user-defined headers and keep track of the interesting ones.
Definition: header.c:364
@ USERHDRS_OVERRIDE_CONTENT_TYPE
Override the "Content-Type".
Definition: header.c:61
@ USERHDRS_OVERRIDE_USER_AGENT
Override the "User-Agent".
Definition: header.c:62
int mutt_write_mime_header(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition: header.c:756
void mutt_write_references(const struct ListHead *r, FILE *fp, size_t trim)
Add the message references to a list.
Definition: header.c:519
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
Write one header line to a file.
Definition: header.c:423
void mutt_date_make_date(struct Buffer *buf, bool local)
Write a date in RFC822 format to a buffer.
Definition: date.c:397
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define TAILQ_EMPTY(head)
Definition: queue.h:739
String manipulation buffer.
Definition: buffer.h:36
struct ListHead userhdrs
user defined headers
Definition: envelope.h:85
char *const subject
Email's subject.
Definition: envelope.h:70
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
char * followup_to
List of 'followup-to' fields.
Definition: envelope.h:80
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
char * message_id
Message ID.
Definition: envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:81
char * newsgroups
List of newsgroups.
Definition: envelope.h:78
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:65
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList sender
Email's sender.
Definition: envelope.h:63
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
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
Which headers have been overridden.
Definition: header.c:69
bool is_overridden[mutt_array_size(UserhdrsOverrideHeaders)]
Which email headers have been overridden.
Definition: header.c:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_mime_header()

int mutt_write_mime_header ( struct Body b,
FILE *  fp,
struct ConfigSubset sub 
)

Create a MIME header.

Parameters
bBody part
fpFile to write to
subConfig Subset
Return values
0Success
-1Failure

Definition at line 756 of file header.c.

757{
758 if (!b || !fp)
759 return -1;
760
761 int len;
762 int tmplen;
763 char buf[256] = { 0 };
764
765 fprintf(fp, "Content-Type: %s/%s", TYPE(b), b->subtype);
766
767 if (!TAILQ_EMPTY(&b->parameter))
768 {
769 len = 25 + mutt_str_len(b->subtype); /* approximate len. of content-type */
770
771 struct Parameter *np = NULL;
772 TAILQ_FOREACH(np, &b->parameter, entries)
773 {
774 if (!np->attribute || !np->value)
775 continue;
776
777 struct ParameterList pl_conts = TAILQ_HEAD_INITIALIZER(pl_conts);
778 rfc2231_encode_string(&pl_conts, np->attribute, np->value);
779 struct Parameter *cont = NULL;
780 TAILQ_FOREACH(cont, &pl_conts, entries)
781 {
782 fputc(';', fp);
783
784 buf[0] = 0;
785 mutt_addr_cat(buf, sizeof(buf), cont->value, MimeSpecials);
786
787 /* Dirty hack to make messages readable by Outlook Express
788 * for the Mac: force quotes around the boundary parameter
789 * even when they aren't needed. */
790 if (mutt_istr_equal(cont->attribute, "boundary") && mutt_str_equal(buf, cont->value))
791 snprintf(buf, sizeof(buf), "\"%s\"", cont->value);
792
793 tmplen = mutt_str_len(buf) + mutt_str_len(cont->attribute) + 1;
794 if ((len + tmplen + 2) > 76)
795 {
796 fputs("\n\t", fp);
797 len = tmplen + 1;
798 }
799 else
800 {
801 fputc(' ', fp);
802 len += tmplen + 1;
803 }
804
805 fprintf(fp, "%s=%s", cont->attribute, buf);
806 }
807
808 mutt_param_free(&pl_conts);
809 }
810 }
811
812 fputc('\n', fp);
813
814 if (b->content_id)
815 fprintf(fp, "Content-ID: <%s>\n", b->content_id);
816
817 if (b->language)
818 fprintf(fp, "Content-Language: %s\n", b->language);
819
820 if (b->description)
821 fprintf(fp, "Content-Description: %s\n", b->description);
822
823 if (b->disposition != DISP_NONE)
824 {
825 const char *dispstr[] = { "inline", "attachment", "form-data" };
826
827 if (b->disposition < sizeof(dispstr) / sizeof(char *))
828 {
829 fprintf(fp, "Content-Disposition: %s", dispstr[b->disposition]);
830 len = 21 + mutt_str_len(dispstr[b->disposition]);
831
832 if (b->use_disp && ((b->disposition != DISP_INLINE) || b->d_filename))
833 {
834 char *fn = b->d_filename;
835 if (!fn)
836 fn = b->filename;
837
838 if (fn)
839 {
840 /* Strip off the leading path... */
841 char *t = strrchr(fn, '/');
842 if (t)
843 t++;
844 else
845 t = fn;
846
847 struct ParameterList pl_conts = TAILQ_HEAD_INITIALIZER(pl_conts);
848 rfc2231_encode_string(&pl_conts, "filename", t);
849 struct Parameter *cont = NULL;
850 TAILQ_FOREACH(cont, &pl_conts, entries)
851 {
852 fputc(';', fp);
853 buf[0] = 0;
854 mutt_addr_cat(buf, sizeof(buf), cont->value, MimeSpecials);
855
856 tmplen = mutt_str_len(buf) + mutt_str_len(cont->attribute) + 1;
857 if ((len + tmplen + 2) > 76)
858 {
859 fputs("\n\t", fp);
860 len = tmplen + 1;
861 }
862 else
863 {
864 fputc(' ', fp);
865 len += tmplen + 1;
866 }
867
868 fprintf(fp, "%s=%s", cont->attribute, buf);
869 }
870
871 mutt_param_free(&pl_conts);
872 }
873 }
874
875 fputc('\n', fp);
876 }
877 else
878 {
879 mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n", b->disposition);
880 }
881 }
882
883 if (b->encoding != ENC_7BIT)
884 fprintf(fp, "Content-Transfer-Encoding: %s\n", ENCODING(b->encoding));
885
886 const bool c_crypt_protected_headers_write = cs_subset_bool(sub, "crypt_protected_headers_write");
887 bool c_autocrypt = false;
888#ifdef USE_AUTOCRYPT
889 c_autocrypt = cs_subset_bool(sub, "autocrypt");
890#endif
891
892 if ((c_crypt_protected_headers_write || c_autocrypt) && b->mime_headers)
893 {
895 false, false, sub);
896 }
897
898 /* Do NOT add the terminator here!!! */
899 return ferror(fp) ? -1 : 0;
900}
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:708
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
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:577
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
const char MimeSpecials[]
Characters that need special treatment in MIME.
Definition: mime.c:67
@ ENC_7BIT
7-bit text
Definition: mime.h:49
@ DISP_INLINE
Content is inline.
Definition: mime.h:62
@ DISP_NONE
No preferred disposition.
Definition: mime.h:65
#define ENCODING(x)
Definition: mime.h:92
#define TYPE(body)
Definition: mime.h:89
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:672
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:62
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:743
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:655
size_t rfc2231_encode_string(struct ParameterList *head, const char *attribute, char *value)
Encode a string to be suitable for an RFC2231 header.
Definition: rfc2231.c:355
char * language
content-language (RFC8255)
Definition: body.h:78
char * content_id
Content-Id (RFC2392)
Definition: body.h:58
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition: body.h:56
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:76
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:63
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:47
char * description
content-description
Definition: body.h:55
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:42
char * subtype
content-type subtype
Definition: body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:41
char * filename
When sending a message, this is the file to which this structure refers.
Definition: body.h:59
Attribute associated with a MIME part.
Definition: parameter.h:33
char * attribute
Parameter name.
Definition: parameter.h:34
char * value
Parameter value.
Definition: parameter.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_one_header()

int mutt_write_one_header ( FILE *  fp,
const char *  tag,
const char *  value,
const char *  pfx,
int  wraplen,
CopyHeaderFlags  chflags,
struct ConfigSubset sub 
)

Write one header line to a file.

Parameters
fpFile to write to
tagHeader key, e.g. "From"
valueHeader value
pfxPrefix for header
wraplenColumn to wrap at
chflagsFlags, see CopyHeaderFlags
subConfig Subset
Return values
0Success
-1Failure

split several headers into individual ones and call write_one_header for each one

Definition at line 423 of file header.c.

426{
427 char *last = NULL, *line = NULL;
428 int max = 0, w, rc = -1;
429 int pfxw = mutt_strwidth(pfx);
430 char *v = mutt_str_dup(value);
431 bool display = (chflags & CH_DISPLAY);
432
433 const bool c_weed = cs_subset_bool(sub, "weed");
434 if (!display || c_weed)
435 v = unfold_header(v);
436
437 /* when not displaying, use sane wrap value */
438 if (!display)
439 {
440 const short c_wrap_headers = cs_subset_number(sub, "wrap_headers");
441 if ((c_wrap_headers < 78) || (c_wrap_headers > 998))
442 wraplen = 78;
443 else
444 wraplen = c_wrap_headers;
445 }
446 else if (wraplen <= 0)
447 {
448 wraplen = 78;
449 }
450
451 const size_t vlen = mutt_str_len(v);
452 if (tag)
453 {
454 /* if header is short enough, simply print it */
455 if (!display && (mutt_strwidth(tag) + 2 + pfxw + mutt_strnwidth(v, vlen) <= wraplen))
456 {
457 mutt_debug(LL_DEBUG5, "buf[%s%s: %s] is short enough\n", NONULL(pfx), tag, v);
458 if (fprintf(fp, "%s%s: %s\n", NONULL(pfx), tag, v) <= 0)
459 goto out;
460 rc = 0;
461 goto out;
462 }
463 else
464 {
465 rc = fold_one_header(fp, tag, v, vlen, pfx, wraplen, chflags);
466 goto out;
467 }
468 }
469
470 char *p = v;
471 last = v;
472 line = v;
473 while (p && *p)
474 {
475 p = strchr(p, '\n');
476
477 /* find maximum line width in current header */
478 if (p)
479 *p = '\0';
480 w = mutt_mb_width(line, 0, display);
481 if (w > max)
482 max = w;
483 if (p)
484 *p = '\n';
485
486 if (!p)
487 break;
488
489 line = ++p;
490 if ((*p != ' ') && (*p != '\t'))
491 {
492 if (write_one_header(fp, pfxw, max, wraplen, pfx, last, p, chflags) < 0)
493 goto out;
494 last = p;
495 max = 0;
496 }
497 }
498
499 if (last && *last)
500 if (write_one_header(fp, pfxw, max, wraplen, pfx, last, p, chflags) < 0)
501 goto out;
502
503 rc = 0;
504
505out:
506 FREE(&v);
507 return rc;
508}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:143
#define CH_DISPLAY
Display result to user.
Definition: copy.h:72
size_t mutt_strnwidth(const char *s, size_t n)
Measure a string's width in screen cells.
Definition: curs_lib.c:456
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:443
static int fold_one_header(FILE *fp, const char *tag, const char *value, size_t vlen, const char *pfx, int wraplen, CopyHeaderFlags chflags)
Fold one header line.
Definition: header.c:131
static int write_one_header(FILE *fp, int pfxw, int max, int wraplen, const char *pfx, const char *start, const char *end, CopyHeaderFlags chflags)
Write out one header line.
Definition: header.c:295
static char * unfold_header(char *s)
Unfold a wrapped email header.
Definition: header.c:238
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
int mutt_mb_width(const char *str, int col, bool indent)
Measure a string's display width (in screen columns)
Definition: mbyte.c:137
#define FREE(x)
Definition: memory.h:55
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
#define NONULL(x)
Definition: string2.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_references()

void mutt_write_references ( const struct ListHead *  r,
FILE *  fp,
size_t  trim 
)

Add the message references to a list.

Parameters
rString List of references
fpFile to write to
trimTrim the list to at most this many items

Write the list in reverse because they are stored in reverse order when parsed to speed up threading.

Definition at line 519 of file header.c.

520{
521 struct ListNode *np = NULL;
522 size_t length = 0;
523
524 STAILQ_FOREACH(np, r, entries)
525 {
526 if (++length == trim)
527 break;
528 }
529
530 struct ListNode **ref = MUTT_MEM_CALLOC(length, struct ListNode *);
531
532 // store in reverse order
533 size_t tmp = length;
534 STAILQ_FOREACH(np, r, entries)
535 {
536 ref[--tmp] = np;
537 if (tmp == 0)
538 break;
539 }
540
541 for (size_t i = 0; i < length; i++)
542 {
543 fputc(' ', fp);
544 fputs(ref[i]->data, fp);
545 if (i != length - 1)
546 fputc('\n', fp);
547 }
548
549 FREE(&ref);
550}
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:40
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
A List node for strings.
Definition: list.h:37
char * data
String.
Definition: list.h:38
+ Here is the caller graph for this function: