diff options
author | Philip Hazel <ph10@hermes.cam.ac.uk> | 2006-02-28 11:25:40 +0000 |
---|---|---|
committer | Philip Hazel <ph10@hermes.cam.ac.uk> | 2006-02-28 11:25:40 +0000 |
commit | 30dba1e609d941013dc8421de5104dad387ac5b1 (patch) | |
tree | 03360092d0a084fef98cc6392464a294b21b6ece /src | |
parent | 8e3e25cac127659fa8b15f1ead18e1a39642f66b (diff) |
Add References: support to autoreply.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/functions.h | 3 | ||||
-rw-r--r-- | src/src/parse.c | 84 | ||||
-rw-r--r-- | src/src/transports/autoreply.c | 57 |
3 files changed, 138 insertions, 6 deletions
diff --git a/src/src/functions.h b/src/src/functions.h index fdcfd55d2..9b8bfacf2 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/functions.h,v 1.22 2006/02/22 14:46:44 ph10 Exp $ */ +/* $Cambridge: exim/src/src/functions.h,v 1.23 2006/02/28 11:25:40 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -175,6 +175,7 @@ extern int parse_forward_list(uschar *, int, address_item **, uschar **, extern uschar *parse_find_address_end(uschar *, BOOL); extern uschar *parse_find_at(uschar *); extern uschar *parse_fix_phrase(uschar *, int, uschar *, int); +extern uschar *parse_message_id(uschar *, uschar **, uschar **); extern uschar *parse_quote_2047(uschar *, int, uschar *, uschar *, int); extern BOOL queue_action(uschar *, int, uschar **, int, int); diff --git a/src/src/parse.c b/src/src/parse.c index 67d9e148c..182df8026 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/parse.c,v 1.7 2006/02/07 11:19:00 ph10 Exp $ */ +/* $Cambridge: exim/src/src/parse.c,v 1.8 2006/02/28 11:25:40 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1656,6 +1656,68 @@ for (;;) } + +/************************************************* +* Extract a Message-ID * +*************************************************/ + +/* This function is used to extract message ids from In-Reply-To: and +References: header lines. + +Arguments: + str pointer to the start of the message-id + yield put pointer to the message id (in dynamic memory) here + error put error message here on failure + +Returns: points after the processed message-id or NULL on error +*/ + +uschar * +parse_message_id(uschar *str, uschar **yield, uschar **error) +{ +uschar *domain = NULL; +uschar *id; + +str = skip_comment(str); +if (*str != '<') + { + *error = US"Missing '<' before message-id"; + return NULL; + } + +/* Getting a block the size of the input string will definitely be sufficient +for the answer, but it may also be very long if we are processing a header +line. Therefore, take care to release unwanted store afterwards. */ + +id = *yield = store_get(Ustrlen(str) + 1); +*id++ = *str++; + +str = read_addr_spec(str, id, '>', error, &domain); + +if (*error == NULL) + { + if (*str != '>') *error = US"Missing '>' after message-id"; + else if (domain == NULL) *error = US"domain missing in message-id"; + } + +if (*error != NULL) + { + store_reset(*yield); + return NULL; + } + +while (*id != 0) id++; +*id++ = *str++; +*id++ = 0; +store_reset(id); + +str = skip_comment(str); +return str; +} + + + + /************************************************* ************************************************** * Stand-alone test program * @@ -1788,6 +1850,26 @@ while (Ufgets(buffer, sizeof(buffer), stdin) != NULL) else printf("Failed: %d %s\n", extracted, errmess); } +printf("Testing parse_message_id\n"); + +while (Ufgets(buffer, sizeof(buffer), stdin) != NULL) + { + uschar *s, *t, *errmess; + buffer[Ustrlen(buffer) - 1] = 0; + if (buffer[0] == 0) break; + s = buffer; + while (*s != 0) + { + s = parse_message_id(s, &t, &errmess); + if (errmess != NULL) + { + printf("Failed: %s\n", errmess); + break; + } + printf("%s\n", t); + } + } + return 0; } diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 719e358af..c16cf6e2f 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/autoreply.c,v 1.8 2006/02/07 11:19:03 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/autoreply.c,v 1.9 2006/02/28 11:25:40 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -277,6 +277,7 @@ uschar *from, *reply_to, *to, *cc, *bcc, *subject, *headers, *text, *file; uschar *logfile, *oncelog; uschar *cache_buff = NULL; uschar *cache_time = NULL; +uschar *message_id = NULL; header_line *h; time_t now = time(NULL); time_t once_repeat_sec = 0; @@ -590,9 +591,57 @@ for (h = header_list; h != NULL; h = h->next) if (h != NULL) { - uschar *s = Ustrchr(h->text, ':') + 1; - while (isspace(*s)) s++; - fprintf(f, "In-Reply-To: %s", s); + message_id = Ustrchr(h->text, ':') + 1; + while (isspace(*message_id)) message_id++; + fprintf(f, "In-Reply-To: %s", message_id); + } + +/* Generate a References header if there is at least one of Message-ID:, +References:, or In-Reply-To: (see RFC 2822). */ + +for (h = header_list; h != NULL; h = h->next) + if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0) + break; + +if (h == NULL) + for (h = header_list; h != NULL; h = h->next) + if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0) + break; + +/* We limit the total length of references. Although there is no fixed +limit, some systems do not like headers growing beyond recognition. +Keep the first message ID for the thread root and the last few for +the position inside the thread, up to a maximum of 12 altogether. */ + +if (h != NULL || message_id != NULL) + { + fprintf(f, "References:"); + if (h != NULL) + { + uschar *s, *id, *error; + uschar *referenced_ids[12]; + int reference_count = 0; + int i; + + s = Ustrchr(h->text, ':') + 1; + parse_allow_group = FALSE; + while (*s != 0 && (s = parse_message_id(s, &id, &error)) != NULL) + { + if (reference_count == sizeof(referenced_ids)/sizeof(uschar *)) + { + memmove(referenced_ids + 1, referenced_ids + 2, + sizeof(referenced_ids) - 2*sizeof(uschar *)); + referenced_ids[reference_count - 1] = id; + } + else referenced_ids[reference_count++] = id; + } + for (i = 0; i < reference_count; ++i) fprintf(f, " %s", referenced_ids[i]); + } + + /* The message id will have a newline on the end of it. */ + + if (message_id != NULL) fprintf(f, " %s", message_id); + else fprintf(f, "\n"); } /* Add an Auto-Submitted: header */ |