summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-28 11:25:40 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-28 11:25:40 +0000
commit30dba1e609d941013dc8421de5104dad387ac5b1 (patch)
tree03360092d0a084fef98cc6392464a294b21b6ece /src
parent8e3e25cac127659fa8b15f1ead18e1a39642f66b (diff)
Add References: support to autoreply.
Diffstat (limited to 'src')
-rw-r--r--src/src/functions.h3
-rw-r--r--src/src/parse.c84
-rw-r--r--src/src/transports/autoreply.c57
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 */