mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 10:58:10 +01:00
Make Received: header special in notmuch_message_file_get_header
With this patch the Received: header becomes special in the way we treat headers - this is the only header for which we concatenate all the instances we find (instead of just returning the first one). This will be used in the From guessing code for replies as we need to be able to walk ALL of the Received: headers in a message to have a good chance to guess which mailbox this email was delivered to. Signed-off-by: Dirk Hohndel <hohndel@infradead.org>
This commit is contained in:
parent
4b34effca5
commit
5b8b0377cb
2 changed files with 48 additions and 13 deletions
|
@ -209,17 +209,24 @@ copy_header_unfolding (header_value_closure_t *value,
|
||||||
|
|
||||||
/* As a special-case, a value of NULL for header_desired will force
|
/* As a special-case, a value of NULL for header_desired will force
|
||||||
* the entire header to be parsed if it is not parsed already. This is
|
* the entire header to be parsed if it is not parsed already. This is
|
||||||
* used by the _notmuch_message_file_get_headers_end function. */
|
* used by the _notmuch_message_file_get_headers_end function.
|
||||||
|
* Another special case is the Received: header. For this header we
|
||||||
|
* want to concatenate all instances of the header instead of just
|
||||||
|
* hashing the first instance as we use this when analyzing the path
|
||||||
|
* the mail has taken from sender to recipient.
|
||||||
|
*/
|
||||||
const char *
|
const char *
|
||||||
notmuch_message_file_get_header (notmuch_message_file_t *message,
|
notmuch_message_file_get_header (notmuch_message_file_t *message,
|
||||||
const char *header_desired)
|
const char *header_desired)
|
||||||
{
|
{
|
||||||
int contains;
|
int contains;
|
||||||
char *header, *decoded_value;
|
char *header, *decoded_value, *header_sofar, *combined_header;
|
||||||
const char *s, *colon;
|
const char *s, *colon;
|
||||||
int match;
|
int match, newhdr, hdrsofar, is_received;
|
||||||
static int initialized = 0;
|
static int initialized = 0;
|
||||||
|
|
||||||
|
is_received = (strcmp(header_desired,"received") == 0);
|
||||||
|
|
||||||
if (! initialized) {
|
if (! initialized) {
|
||||||
g_mime_init (0);
|
g_mime_init (0);
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
|
@ -312,22 +319,39 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,
|
||||||
|
|
||||||
NEXT_HEADER_LINE (&message->value);
|
NEXT_HEADER_LINE (&message->value);
|
||||||
|
|
||||||
if (header_desired == 0)
|
if (header_desired == NULL)
|
||||||
match = 0;
|
match = 0;
|
||||||
else
|
else
|
||||||
match = (strcasecmp (header, header_desired) == 0);
|
match = (strcasecmp (header, header_desired) == 0);
|
||||||
|
|
||||||
decoded_value = g_mime_utils_header_decode_text (message->value.str);
|
decoded_value = g_mime_utils_header_decode_text (message->value.str);
|
||||||
if (g_hash_table_lookup (message->headers, header) == NULL) {
|
header_sofar = (char *)g_hash_table_lookup (message->headers, header);
|
||||||
/* Only insert if we don't have a value for this header, yet.
|
/* we treat the Received: header special - we want to concat ALL of
|
||||||
* This way we always return the FIRST instance of any header
|
* the Received: headers we encounter.
|
||||||
* we search for
|
* for everything else we return the first instance of a header */
|
||||||
* FIXME: we should be returning ALL instances of a header
|
if (is_received) {
|
||||||
* or at least provide a way to iterate over them
|
if (header_sofar == NULL) {
|
||||||
*/
|
/* first Received: header we encountered; just add it */
|
||||||
|
g_hash_table_insert (message->headers, header, decoded_value);
|
||||||
|
} else {
|
||||||
|
/* we need to add the header to those we already collected */
|
||||||
|
newhdr = strlen(decoded_value);
|
||||||
|
hdrsofar = strlen(header_sofar);
|
||||||
|
combined_header = xmalloc(hdrsofar + newhdr + 2);
|
||||||
|
strncpy(combined_header,header_sofar,hdrsofar);
|
||||||
|
*(combined_header+hdrsofar) = ' ';
|
||||||
|
strncpy(combined_header+hdrsofar+1,decoded_value,newhdr+1);
|
||||||
|
g_hash_table_insert (message->headers, header, combined_header);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (header_sofar == NULL) {
|
||||||
|
/* Only insert if we don't have a value for this header, yet. */
|
||||||
g_hash_table_insert (message->headers, header, decoded_value);
|
g_hash_table_insert (message->headers, header, decoded_value);
|
||||||
}
|
}
|
||||||
if (match)
|
}
|
||||||
|
/* if we found a match we can bail - unless of course we are
|
||||||
|
* collecting all the Received: headers */
|
||||||
|
if (match && !is_received)
|
||||||
return decoded_value;
|
return decoded_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +371,14 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,
|
||||||
message->value.len = 0;
|
message->value.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For the Received: header we actually might end up here even
|
||||||
|
* though we found the header (as we force continued parsing
|
||||||
|
* in that case). So let's check if that's the header we were
|
||||||
|
* looking for and return the value that we found (if any)
|
||||||
|
*/
|
||||||
|
if (is_received)
|
||||||
|
return (char *)g_hash_table_lookup (message->headers, "received");
|
||||||
|
|
||||||
/* We've parsed all headers and never found the one we're looking
|
/* We've parsed all headers and never found the one we're looking
|
||||||
* for. It's probably just not there, but let's check that we
|
* for. It's probably just not there, but let's check that we
|
||||||
* didn't make a mistake preventing us from seeing it. */
|
* didn't make a mistake preventing us from seeing it. */
|
||||||
|
|
|
@ -344,6 +344,9 @@ notmuch_message_file_restrict_headersv (notmuch_message_file_t *message,
|
||||||
*
|
*
|
||||||
* The header name is case insensitive.
|
* The header name is case insensitive.
|
||||||
*
|
*
|
||||||
|
* The Received: header is special - for it all Received: headers in
|
||||||
|
* the message are concatenated
|
||||||
|
*
|
||||||
* The returned value is owned by the notmuch message and is valid
|
* The returned value is owned by the notmuch message and is valid
|
||||||
* only until the message is closed. The caller should copy it if
|
* only until the message is closed. The caller should copy it if
|
||||||
* needing to modify the value or to hold onto it for longer.
|
* needing to modify the value or to hold onto it for longer.
|
||||||
|
|
Loading…
Reference in a new issue