]>
diplodocus.org Git - nmh/blob - sbr/message_id.c
1 /* message_id.c -- construct the body of a Message-ID or Content-ID
4 * This code is Copyright (c) 2012, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
11 #include "message_id.h"
12 #include <sys/time.h> /* for gettimeofday() */
16 NMH_MESSAGE_ID_LOCALNAME
,
18 } message_id_style
= NMH_MESSAGE_ID_LOCALNAME
;
19 static char message_id_
[BUFSIZ
];
22 /* Convert name of message id style to integer value and store it. */
24 save_message_id_style (const char *value
) {
25 if (! strcasecmp (value
, "localname")) {
26 message_id_style
= NMH_MESSAGE_ID_LOCALNAME
;
29 if (! strcasecmp (value
, "random")) {
30 message_id_style
= NMH_MESSAGE_ID_RANDOM
;
38 message_id (time_t tclock
, int content_id
) {
39 switch (message_id_style
) {
40 case NMH_MESSAGE_ID_LOCALNAME
: {
41 char *format
= content_id
? "<%d.%ld.%%d@%s>" : "<%d.%ld@%s>";
43 snprintf (message_id_
, sizeof message_id_
, format
,
44 (int) getpid (), (long) tclock
, LocalName (1));
49 case NMH_MESSAGE_ID_RANDOM
: {
50 char *format
= content_id
51 ? "<%d-%ld.%06ld%%d@%.*s.%.*s.%.*s>"
52 : "<%d-%ld.%06ld@%.*s.%.*s.%.*s>";
53 /* Use a sequence of digits divisible by 3 because that will
54 expand to base64 without any waste. Must be shorter than 58,
57 /* The part after the '@' is divided into thirds. The base64
58 encoded string will be 4/3 the size of rnd. */
59 size_t one_third
= sizeof rnd
* 4/3/3;
61 if (m_rand (rnd
, sizeof rnd
) == 0) {
63 /* All we really need is 4 * [sizeof rnd/3] + 2, as long as
64 the base64 encoding stays shorter than 76 bytes so embedded
65 newlines aren't necessary. But use double the sizeof rnd
67 unsigned char rnd_base64
[2 * sizeof rnd
];
71 writeBase64 (rnd
, sizeof rnd
, rnd_base64
);
73 for (i
= strlen ((const char *) rnd_base64
) - 1;
74 i
> 0 && iscntrl (rnd_base64
[i
]);
76 /* Remove trailing newline. rnd_base64 had better be
77 shorter than 76 characters, so don't bother to look for
82 /* Try to make the base64 string look a little more like a
83 hostname by replacing + with - and / with _. */
84 for (cp
= rnd_base64
; *cp
; ++cp
) {
87 } else if (*cp
== '/') {
92 /* gettimeofday() and getpid() shouldn't fail on POSIX platforms. */
93 gettimeofday (&now
, 0);
95 /* The format string inserts a couple of dots, for the benefit
96 of spam filters that want to see a message id with a final
97 part that resembles a hostname. */
98 snprintf (message_id_
, sizeof message_id_
, format
,
99 getpid (), (long) now
.tv_sec
, (long) now
.tv_usec
,
100 one_third
, rnd_base64
,
101 one_third
, &rnd_base64
[one_third
],
102 one_third
, &rnd_base64
[2*one_third
]);