From 8518fe25efade712e3590e5b13537fb0021d4073 Mon Sep 17 00:00:00 2001 From: ak1 Date: Sat, 5 Feb 2005 13:43:59 +0000 Subject: [PATCH] Andreas Krennmair: make localpart of message ID configurable. git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@50 e385b8ad-14ed-0310-8656-cc95a2468c6d --- globals.h | 1 + init.h | 30 ++++++++++++++-- sendlib.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 127 insertions(+), 6 deletions(-) diff --git a/globals.h b/globals.h index 6d3571d..b781d87 100644 --- a/globals.h +++ b/globals.h @@ -75,6 +75,7 @@ WHERE char *MhFlagged; WHERE char *MhReplied; WHERE char *MhUnseen; WHERE char *MsgFmt; +WHERE char *MsgIdFormat; #ifdef USE_SOCKET WHERE char *Preconnect INITVAL (NULL); diff --git a/init.h b/init.h index 0ab2405..6082311 100644 --- a/init.h +++ b/init.h @@ -927,8 +927,8 @@ struct option_t MuttVars[] = { { "imap_reconnect", DT_QUAD, R_NONE, OPT_IMAPRECONNECT, M_ASKYES }, /* ** .pp - ** Controls whether or not Mutt will try to reconnect to IMAP server when - ** connection lost. + ** Controls whether or not Mutt-ng will try to reconnect to IMAP server when + ** the connection is lost. */ { "imap_servernoise", DT_BOOL, R_NONE, OPTIMAPSERVERNOISE, 1 }, /* @@ -1328,6 +1328,32 @@ struct option_t MuttVars[] = { { "msg_format", DT_SYN, R_NONE, UL "message_format", 0 }, /* */ + { "msgid_format", DT_STR, R_NONE, UL &MsgIdFormat, UL "%Y%m%d%h%M%s.G%P%p" }, + /* + ** .pp + ** This is the format for the ``local part'' of the message-IDs generated + ** by Mutt-ng. The format string contains of one or more characters. The '%' + ** character marks that certain data will be added to the string, similar to + ** printf(). The following characters are allowed: + ** .pp + ** .dl + ** .dt %d .dd the current day of month + ** .dt %h .dd the current hour + ** .dt %m .dd the current month + ** .dt %M .dd the current minute + ** .dt %O .dd the current UNIX timestamp (octal) + ** .dt %p .dd the process ID + ** .dt %P .dd the current message-ID prefix (a character rotating with + ** every message-ID being generated) + ** .dt %r .dd a random integer value (decimal) + ** .dt %R .dd a random integer value (hexadecimal) + ** .dt %s .dd the current second + ** .dt %T .dd the current UNIX timestamp (decimal) + ** .dt %X .dd the current UNIX timestamp (hexadecimal) + ** .dt %Y .dd the current year (Y2K compliant) + ** .dt %% .dd the '%' character + ** .de + */ { "narrow_tree", DT_BOOL, R_TREE|R_INDEX, OPTNARROWTREE, 0 }, /* ** .pp diff --git a/sendlib.c b/sendlib.c index a77b6d0..61b8a39 100644 --- a/sendlib.c +++ b/sendlib.c @@ -1810,9 +1810,102 @@ const char *mutt_fqdn(short may_hide_host) return p; } +static char mutt_normalized_char(char c) { + if (isalnum(c)) + return c; + if (strchr(".!#$%&'*+-/=?^_`{|}~",c)) + return c; + return '.'; /* normalized character (we're stricter than RFC2822, 3.6.4) */ +} + +static void mutt_gen_localpart(char * buf, unsigned int len, char * fmt) { + time_t now; + struct tm *tm; + char tmp[SHORT_STRING]; + + *buf = '\0'; + + now = time (NULL); + tm = gmtime (&now); + + for (;*fmt;++fmt) { + if (*fmt == '%') { + switch (fmt[1]) { + case 0: + return; + case 'd': + snprintf(tmp,sizeof(tmp),"%02d",tm->tm_mday); + safe_strncat(buf,len,tmp,2); + break; + case 'h': + snprintf(tmp,sizeof(tmp),"%02d",tm->tm_hour); + safe_strncat(buf,len,tmp,2); + break; + case 'm': + snprintf(tmp,sizeof(tmp),"%02d",tm->tm_mon+1); + safe_strncat(buf,len,tmp,2); + break; + case 'M': + snprintf(tmp,sizeof(tmp),"%02d",tm->tm_min); + safe_strncat(buf,len,tmp,2); + break; + case 'O': + snprintf(tmp,sizeof(tmp),"%lo",(unsigned long)now); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 'p': + snprintf(tmp,sizeof(tmp),"%u",(unsigned int)getpid()); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 'P': + snprintf(tmp,sizeof(tmp),"%c",MsgIdPfx); + MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1; + safe_strncat(buf,len,tmp,1); + break; + case 'r': + snprintf(tmp,sizeof(tmp),"%u",(unsigned int)rand()); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 'R': + snprintf(tmp,sizeof(tmp),"%x",(unsigned int)rand()); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 's': + snprintf(tmp,sizeof(tmp),"%02d",tm->tm_sec); + safe_strncat(buf,len,tmp,2); + break; + case 'T': + snprintf(tmp,sizeof(tmp),"%u",(unsigned int)now); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 'X': + snprintf(tmp,sizeof(tmp),"%x",(unsigned int)now); + safe_strncat(buf,len,tmp,strlen(tmp)); + break; + case 'Y': + snprintf(tmp,sizeof(tmp),"%04d",tm->tm_year+1900); /* this will break in the year 10000 ;-) */ + safe_strncat(buf,len,tmp,4); + break; + case '%': + safe_strncat(buf,len,"%",1); + break; + default: + safe_strncat(buf,len,".",1); /* invalid formats are replaced by '.' */ + } /* switch */ + ++fmt; + } else { + char c; + c = mutt_normalized_char(*fmt); /* @todo: filter out invalid characters */ + safe_strncat(buf,len,&c,1); + } + } +} + char *mutt_gen_msgid (void) { char buf[SHORT_STRING]; + char localpart[SHORT_STRING]; + unsigned int localpart_length; time_t now; struct tm *tm; const char *fqdn; @@ -1822,10 +1915,11 @@ char *mutt_gen_msgid (void) if(!(fqdn = mutt_fqdn(0))) fqdn = NONULL(Hostname); - snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.G%c%u@%s>", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, - tm->tm_min, tm->tm_sec, MsgIdPfx, (unsigned int)getpid (), fqdn); - MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1; + localpart_length = sizeof(buf) - strlen(fqdn) - 4; /* the 4 characters are '<', '@', '>' and '\0' */ + + mutt_gen_localpart(localpart,localpart_length,MsgIdFormat); + + snprintf(buf,sizeof(buf),"<%s@%s>",localpart,fqdn); return (safe_strdup (buf)); } -- 2.20.1