+/*************************************************
+* Write References: line for DSN *
+*************************************************/
+
+/* Generate a References: header if there is in the header_list
+at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
+
+Arguments: f the FILE to write to
+ message_id optional already-found message-id, or NULL
+
+Returns: nothing
+*/
+
+void
+moan_write_references(FILE * fp, uschar * message_id)
+{
+header_line * h;
+
+if (!message_id)
+ for (h = header_list; h; h = h->next)
+ if (h->type == htype_id)
+ {
+ message_id = Ustrchr(h->text, ':') + 1;
+ Uskip_whitespace(&message_id);
+ }
+
+for (h = header_list; h; h = h->next)
+ if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
+ break;
+
+if (!h)
+ for (h = header_list; h; 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.
+Also apply the max line length limit from RFC 2822 2.1.1
+
+XXX preferably we would get any limit from the outbound transport,
+passed in here for a limit value.
+*/
+
+if (h || message_id)
+ {
+ unsigned use = fprintf(fp, "References:");
+ if (message_id) use += Ustrlen(message_id) + 1;
+ if (h)
+ {
+ const uschar * s;
+ uschar * id, * error;
+ uschar * referenced_ids[12];
+ int reference_count = 0;
+
+ s = Ustrchr(h->text, ':') + 1;
+ f.parse_allow_group = FALSE;
+ while (*s && (s = parse_message_id(s, &id, &error)))
+ {
+ unsigned this = Ustrlen(id);
+ if ( reference_count == nelem(referenced_ids)
+ || use + this + reference_count > 998
+ )
+ {
+ if (reference_count > 1)
+ {
+ /* drop position 1 and shuffle down */
+ use -= Ustrlen(referenced_ids + 1);
+ memmove(referenced_ids + 1, referenced_ids + 2,
+ sizeof(referenced_ids) - 2*sizeof(*referenced_ids));
+
+ /* append new one */
+ referenced_ids[reference_count - 1] = id;
+ }
+ }
+ else
+ referenced_ids[reference_count++] = id;
+ use += this;
+ }
+
+ for (int i = 0; i < reference_count; ++i)
+ fprintf(fp, " %s", referenced_ids[i]);
+ }
+
+ /* The message id will have a newline on the end of it. */
+
+ if (message_id) fprintf(fp, " %s", message_id);
+ else fprintf(fp, "\n");
+ }
+}
+
+
+