Parse an email header.
Process a line from an email header. Each line that is recognised is parsed and the information put in the Envelope or Header.
686{
687 if (!env || !name)
688 return 0;
689
690 bool matched = false;
691
692 switch (name[0] | 0x20)
693 {
694 case 'a':
695 if ((name_len == 13) &&
eqi12(name + 1,
"pparently-to"))
696 {
698 matched = true;
699 }
700 else if ((name_len == 15) &&
eqi14(name + 1,
"pparently-from"))
701 {
703 matched = true;
704 }
705#ifdef USE_AUTOCRYPT
706 else if ((name_len == 9) &&
eqi8(name + 1,
"utocrypt"))
707 {
709 if (c_autocrypt)
710 {
712 matched = true;
713 }
714 }
715 else if ((name_len == 16) &&
eqi15(name + 1,
"utocrypt-gossip"))
716 {
718 if (c_autocrypt)
719 {
721 matched = true;
722 }
723 }
724#endif
725 break;
726
727 case 'b':
728 if ((name_len == 3) &&
eqi2(name + 1,
"cc"))
729 {
731 matched = true;
732 }
733 break;
734
735 case 'c':
736 if ((name_len == 2) &&
eqi1(name + 1,
"c"))
737 {
739 matched = true;
740 }
741 else
742 {
743 if ((name_len >= 12) &&
eqi8(name,
"content-"))
744 {
745 if ((name_len == 12) &&
eqi4(name + 8,
"type"))
746 {
747 if (e)
749 matched = true;
750 }
751 else if ((name_len == 16) &&
eqi8(name + 8,
"language"))
752 {
753 if (e)
755 matched = true;
756 }
757 else if ((name_len == 25) &&
eqi17(name + 8,
"transfer-encoding"))
758 {
759 if (e)
761 matched = true;
762 }
763 else if ((name_len == 14) &&
eqi8(name + 6,
"t-length"))
764 {
765 if (e)
766 {
767 unsigned long len = 0;
769 }
770 matched = true;
771 }
772 else if ((name_len == 19) &&
eqi11(name + 8,
"description"))
773 {
774 if (e)
775 {
778 }
779 matched = true;
780 }
781 else if ((name_len == 19) &&
eqi11(name + 8,
"disposition"))
782 {
783 if (e)
785 matched = true;
786 }
787 }
788 }
789 break;
790
791 case 'd':
792 if ((name_len != 4) || !
eqi4(name,
"date"))
793 break;
794
796 if (e)
797 {
798 struct Tz tz = { 0 };
799
802 {
806 }
807 }
808 matched = true;
809 break;
810
811 case 'e':
812 if ((name_len == 7) &&
eqi6(name + 1,
"xpires") && e)
813 {
816 {
818 }
819 }
820 break;
821
822 case 'f':
823 if ((name_len == 4) &&
eqi4(name,
"from"))
824 {
826 matched = true;
827 }
828 else if ((name_len == 11) &&
eqi10(name + 1,
"ollowup-to"))
829 {
831 {
834 }
835 matched = true;
836 }
837 break;
838
839 case 'i':
840 if ((name_len != 11) || !
eqi10(name + 1,
"n-reply-to"))
841 break;
842
848 matched = true;
849 break;
850
851 case 'l':
852 if ((name_len == 5) &&
eqi4(name + 1,
"ines"))
853 {
854 if (e)
855 {
856 unsigned int ui = 0;
859 }
860
861 matched = true;
862 }
863 else if ((name_len == 9) &&
eqi8(name + 1,
"ist-post"))
864 {
865
867 {
869 if (mailto)
870 {
874 if (c_auto_subscribe)
876 }
877 }
878 matched = true;
879 }
880 else if ((name_len == 14) &&
eqi13(name + 1,
"ist-subscribe"))
881 {
882
884 if (mailto)
885 {
888 }
889 matched = true;
890 }
891 else if ((name_len == 16) &&
eqi15(name + 1,
"ist-unsubscribe"))
892 {
893
895 if (mailto)
896 {
899 }
900 matched = true;
901 }
902 break;
903
904 case 'm':
905 if ((name_len == 12) &&
eqi11(name + 1,
"ime-version"))
906 {
907 if (e)
909 matched = true;
910 }
911 else if ((name_len == 10) &&
eqi9(name + 1,
"essage-id"))
912 {
913
916 matched = true;
917 }
918 else
919 {
920 if ((name_len >= 13) &&
eqi4(name + 1,
"ail-"))
921 {
922 if ((name_len == 13) &&
eqi8(name + 5,
"reply-to"))
923 {
924
927 matched = true;
928 }
929 else if ((name_len == 16) &&
eqi11(name + 5,
"followup-to"))
930 {
932 matched = true;
933 }
934 }
935 }
936 break;
937
938 case 'n':
939 if ((name_len == 10) &&
eqi9(name + 1,
"ewsgroups"))
940 {
944 matched = true;
945 }
946 break;
947
948 case 'o':
949
950 if ((name_len == 12) &&
eqi11(name + 1,
"rganization"))
951 {
954 }
955 break;
956
957 case 'r':
958 if ((name_len == 10) &&
eqi9(name + 1,
"eferences"))
959 {
962 matched = true;
963 }
964 else if ((name_len == 8) &&
eqi8(name,
"reply-to"))
965 {
967 matched = true;
968 }
969 else if ((name_len == 11) &&
eqi10(name + 1,
"eturn-path"))
970 {
972 matched = true;
973 }
974 else if ((name_len == 8) &&
eqi8(name,
"received"))
975 {
977 {
978 char *d = strrchr(body, ';');
979 if (d)
980 {
982
984 }
985 }
986 }
987 break;
988
989 case 's':
990 if ((name_len == 7) &&
eqi6(name + 1,
"ubject"))
991 {
994 matched = true;
995 }
996 else if ((name_len == 6) &&
eqi5(name + 1,
"ender"))
997 {
999 matched = true;
1000 }
1001 else if ((name_len == 6) &&
eqi5(name + 1,
"tatus"))
1002 {
1003 if (e)
1004 {
1005 while (*body)
1006 {
1007 switch (*body)
1008 {
1009 case 'O':
1010 {
1012 break;
1013 }
1014 case 'R':
1016 break;
1017 case 'r':
1019 break;
1020 }
1021 body++;
1022 }
1023 }
1024 matched = true;
1025 }
1026 else if (e && (name_len == 10) &&
eqi1(name + 1,
"u") &&
1027 (
eqi8(name + 2,
"persedes") ||
eqi8(name + 2,
"percedes")))
1028 {
1031 }
1032 break;
1033
1034 case 't':
1035 if ((name_len == 2) &&
eqi1(name + 1,
"o"))
1036 {
1038 matched = true;
1039 }
1040 break;
1041
1042 case 'x':
1043 if ((name_len == 8) &&
eqi8(name,
"x-status"))
1044 {
1045 if (e)
1046 {
1047 while (*body)
1048 {
1049 switch (*body)
1050 {
1051 case 'A':
1053 break;
1054 case 'D':
1056 break;
1057 case 'F':
1059 break;
1060 default:
1061 break;
1062 }
1063 body++;
1064 }
1065 }
1066 matched = true;
1067 }
1068 else if ((name_len == 7) &&
eqi6(name + 1,
"-label"))
1069 {
1072 matched = true;
1073 }
1074 else if ((name_len == 12) &&
eqi11(name + 1,
"-comment-to"))
1075 {
1078 matched = true;
1079 }
1080 else if ((name_len == 4) &&
eqi4(name,
"xref"))
1081 {
1084 matched = true;
1085 }
1086 else if ((name_len == 13) &&
eqi12(name + 1,
"-original-to"))
1087 {
1089 matched = true;
1090 }
1091 break;
1092
1093 default:
1094 break;
1095 }
1096
1097
1098 if (!matched && user_hdrs)
1099 {
1101 char *dup = NULL;
1103
1105 {
1107 if (do_2047)
1108 {
1110 }
1111 }
1112 else
1113 {
1115 }
1116 }
1117
1118 return matched;
1119}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
const char * mutt_str_atoul(const char *str, unsigned long *dst)
Convert ASCII string to an unsigned long.
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
void mutt_parse_content_type(const char *s, struct Body *b)
Parse a content type.
void mutt_auto_subscribe(const char *mailto)
Check if user is subscribed to mailing list.
static struct AutocryptHeader * parse_autocrypt(struct AutocryptHeader *head, const char *s)
Parse an Autocrypt header line.
static void parse_references(struct ListHead *head, const char *s)
Parse references from an email header.
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
static char * rfc2369_first_mailto(const char *body)
Extract the first mailto: URL from a RFC2369 list.
static void parse_content_language(const char *s, struct Body *b)
Read the content's language.
static void parse_content_disposition(const char *s, struct Body *b)
Parse a content disposition.
void mutt_filter_commandline_header_value(char *header)
Sanitise characters in a header value.
#define CONTENT_TOO_BIG
Maximum reasonable Content-Length value (1 GiB) to prevent overflow.
void mutt_env_set_subject(struct Envelope *env, const char *subj)
Set both subject and real_subj to subj.
static bool eqi17(const char *a, const char b[17])
eqi17 - Compare two 17-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi9(const char *a, const char b[9])
eqi9 - Compare two 9-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi10(const char *a, const char b[10])
eqi10 - Compare two 10-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi8(const char *a, const char b[8])
Compare two 8-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons.
static bool eqi11(const char *a, const char b[11])
eqi11 - Compare two 11-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi6(const char *a, const char b[6])
eqi6 - Compare two 6-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi14(const char *a, const char b[14])
eqi14 - Compare two 14-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi13(const char *a, const char b[13])
eqi13 - Compare two 13-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi4(const char *a, const char b[4])
Compare two 4-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons.
static bool eqi5(const char *a, const char b[5])
eqi5 - Compare two 5-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi12(const char *a, const char b[12])
eqi12 - Compare two 12-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi15(const char *a, const char b[15])
eqi15 - Compare two 15-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons
static bool eqi1(const char *a, const char b[1])
Compare two 1-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons.
static bool eqi2(const char *a, const char b[2])
Compare two 2-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons.
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
#define MIN(a, b)
Return the minimum of two values.
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
time_t mutt_date_parse_date(const char *s, struct Tz *tz_out)
Parse a date string in RFC822 format.
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
int mutt_str_asprintf(char **strp, const char *fmt,...)
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
char * description
content-description
unsigned int zminutes
Minutes away from UTC.
bool mime
Has a MIME-Version header?
int lines
How many lines in the body of this message?
bool old
Email is seen, but unread.
bool zoccident
True, if west of UTC, False if east.
bool flagged
Marked important?
unsigned int zhours
Hours away from UTC.
time_t date_sent
Time when the message was sent (UTC)
bool replied
Email has been replied to.
bool expired
Already expired?
bool deleted
Email is deleted.
time_t received
Time when the message was placed in the mailbox.
struct ListHead userhdrs
user defined headers
char * supersedes
Supersedes header.
char * list_subscribe
This stores a mailto URL, or nothing.
struct AddressList return_path
Return path for the Email.
char *const subject
Email's subject.
char * followup_to
List of 'followup-to' fields.
struct AddressList reply_to
Email's 'reply-to'.
char * message_id
Message ID.
char * x_comment_to
List of 'X-comment-to' fields.
struct AddressList x_original_to
Email's 'X-Original-to'.
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
char * newsgroups
List of newsgroups.
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
struct AddressList cc
Email's 'Cc' list.
struct AddressList sender
Email's sender.
struct ListHead references
message references (in reverse order)
struct AutocryptHeader * autocrypt
Autocrypt header.
struct ListHead in_reply_to
in-reply-to header content
struct AddressList bcc
Email's 'Bcc' list.
char * xref
List of cross-references.
char * organization
Organisation header.
char * list_post
This stores a mailto URL, or nothing.
char * list_unsubscribe
This stores a mailto URL, or nothing.
struct AddressList from
Email's 'From' list.
struct ConfigSubset * sub
Inherited config items.
List of recognised Timezones.
unsigned char zminutes
Minutes away from UTC.
bool zoccident
True if west of UTC, False if East.
unsigned char zhours
Hours away from UTC.