summaryrefslogtreecommitdiffstats
path: root/imap/msgenvelope.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /imap/msgenvelope.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'imap/msgenvelope.c')
-rw-r--r--imap/msgenvelope.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/imap/msgenvelope.c b/imap/msgenvelope.c
new file mode 100644
index 0000000..60564df
--- /dev/null
+++ b/imap/msgenvelope.c
@@ -0,0 +1,310 @@
+/*
+** Copyright 1998 - 2009 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "rfc822/rfc822.h"
+#include "rfc822/rfc2047.h"
+#include "rfc2045/rfc2045.h"
+#include "imapwrite.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define MAX_HEADER_SIZE 8192
+
+static char *read_header(FILE *fp, off_t *headerpos, off_t *endhp)
+{
+size_t i=0;
+int c;
+static char headerbuf[MAX_HEADER_SIZE];
+
+ while (*headerpos < *endhp)
+ {
+ while ((c=getc(fp)) != '\n' && c != EOF)
+ {
+ if (c == '\r')
+ c=' '; /* Otherwise Outlook croaks */
+
+ if (i < sizeof(headerbuf)-1)
+ headerbuf[i++]=c;
+ if ( ++*headerpos >= *endhp) break;
+ }
+ if (c == EOF || *headerpos >= *endhp)
+ {
+ *headerpos=*endhp;
+ break;
+ }
+ if (c == '\n' && ++*headerpos >= *endhp) break;
+ c=getc(fp);
+ if (c != EOF) ungetc(c, fp);
+ if (c == EOF)
+ {
+ *headerpos=*endhp;
+ break;
+ }
+ if (c != ' ' && c != '\t') break;
+ }
+ headerbuf[i]=0;
+ if (*headerpos == *endhp && i == 0) return (0);
+ return (headerbuf);
+}
+
+void msgappends(void (*writefunc)(const char *, size_t),
+ const char *s, size_t l)
+{
+ size_t i,j;
+ char *q=0;
+
+ for (i=0; i<l; i++)
+ if (s[i] & 0x80) /* Illegal 8-bit header content */
+ {
+ char *p=malloc(l+1);
+
+ if (!p)
+ write_error_exit(0);
+ if (l)
+ memcpy(p, s, l);
+ p[l]=0;
+
+ /* Assume UTF-8, if not, well, GIGO */
+ q=rfc2047_encode_str(p, "utf-8",
+ rfc2047_qp_allow_any);
+ free(p);
+ if (!q)
+ write_error_exit(0);
+ s=q;
+ l=strlen(s);
+ }
+
+ for (i=j=0; i<l; i++)
+ {
+ if (s[i] == '"' || s[i] == '\\')
+ {
+ (*writefunc)(s+j, i-j);
+ (*writefunc)("\\", 1);
+ j=i;
+ }
+ }
+ (*writefunc)(s+j, i-j);
+ if (q)
+ free(q);
+}
+
+static void doenvs(void (*writefunc)(const char *, size_t), char *s)
+{
+size_t i,j;
+char *t=s;
+
+ while ( s && *s && isspace((int)(unsigned char)*s))
+ ++s;
+
+ for (i=j=0; s && s[i]; i++)
+ if ( !isspace((int)(unsigned char)s[i]))
+ j=i+1;
+
+ if (j == 0)
+ (*writefunc)("NIL", 3);
+ else
+ {
+ (*writefunc)("\"", 1);
+ msgappends(writefunc, s, j);
+ (*writefunc)("\"", 1);
+ }
+
+ if (t) free(t);
+}
+
+static void doenva(void (*writefunc)(const char *, size_t), char *s)
+{
+struct rfc822t *t;
+struct rfc822a *a;
+int i;
+char *q, *r;
+
+ if (!s)
+ {
+ (*writefunc)("NIL", 3);
+ return;
+ }
+
+ t=rfc822t_alloc_new(s, 0, 0);
+ if (!t)
+ {
+ perror("malloc");
+ exit(0);
+ }
+ a=rfc822a_alloc(t);
+ if (!a)
+ {
+ perror("malloc");
+ exit(1);
+ }
+
+ if (a->naddrs == 0)
+ {
+ rfc822a_free(a);
+ rfc822t_free(t);
+ free(s);
+ (*writefunc)("NIL", 3);
+ return;
+ }
+
+ (*writefunc)("(", 1);
+ for (i=0; i<a->naddrs; i++)
+ {
+ (*writefunc)("(", 1);
+
+ q=rfc822_display_name_tobuf(a, i, NULL);
+
+ if (!q)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ if (a->addrs[i].tokens == 0)
+ {
+ if (strcmp(q, ";") == 0)
+ {
+ (*writefunc)("NIL NIL NIL NIL)", 16);
+ free(q);
+ continue;
+ }
+ r=strrchr(q, ':');
+ if (r && r[1] == 0) *r=0;
+
+ (*writefunc)("NIL NIL \"", 9);
+ msgappends(writefunc, q, strlen(q));
+ (*writefunc)("\" NIL)", 6);
+ free(q);
+ continue;
+ }
+
+ if (a->addrs[i].name == 0)
+ *q=0;
+ /* rfc822_display_name_tobuf() defaults to addr, ignore. */
+
+ doenvs(writefunc, q);
+ (*writefunc)(" NIL \"", 6); /* TODO @domain list */
+ q=rfc822_gettok(a->addrs[i].tokens);
+ if (!q)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ r=strrchr(q, '@');
+ if (r) *r++=0;
+ msgappends(writefunc, q, strlen(q));
+ (*writefunc)("\" \"", 3);
+ if (r)
+ msgappends(writefunc, r, strlen(r));
+ (*writefunc)("\")", 2);
+ free(q);
+ }
+ (*writefunc)(")", 1);
+ rfc822a_free(a);
+ rfc822t_free(t);
+ free(s);
+}
+
+void msgenvelope(void (*writefunc)(const char *, size_t),
+ FILE *fp, struct rfc2045 *mimep)
+{
+char *date=0, *subject=0;
+char *from=0, *sender=0, *replyto=0, *to=0, *cc=0, *bcc=0;
+char *inreplyto=0, *msgid=0;
+
+off_t start_pos, end_pos, start_body;
+off_t nlines, nbodylines;
+
+char *p, *q, *r;
+
+ rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
+ &nlines, &nbodylines);
+
+ if (fseek(fp, start_pos, SEEK_SET) < 0)
+ {
+ perror("fseek");
+ exit(0);
+ }
+
+ while ((p=read_header(fp, &start_pos, &start_body)) != 0)
+ {
+ char **hdrp=0;
+ size_t oldl, newl;
+ size_t c;
+
+ if ((q=strchr(p, ':')) != 0)
+ *q++=0;
+ for (r=p; *r; r++)
+ *r=tolower((int)(unsigned char)*r);
+ if (strcmp(p, "date") == 0) hdrp= &date;
+ if (strcmp(p, "subject") == 0) hdrp= &subject;
+ if (strcmp(p, "from") == 0) hdrp= &from;
+ if (strcmp(p, "sender") == 0) hdrp= &sender;
+ if (strcmp(p, "reply-to") == 0) hdrp= &replyto;
+ if (strcmp(p, "to") == 0) hdrp= &to;
+ if (strcmp(p, "cc") == 0) hdrp= &cc;
+ if (strcmp(p, "bcc") == 0) hdrp= &bcc;
+ if (strcmp(p, "in-reply-to") == 0) hdrp= &inreplyto;
+ if (strcmp(p, "message-id") == 0) hdrp= &msgid;
+ if (!hdrp) continue;
+ if (!q) q="";
+ oldl= *hdrp ? strlen(*hdrp):0;
+ newl= strlen(q);
+ c=oldl+newl+1;
+ if (c > 8192) c=8192;
+ r= (char *)(*hdrp ? realloc(*hdrp, c+1):malloc(c+1));
+ if (!r)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ if (oldl && oldl < c)
+ r[oldl++]=',';
+ newl=c-oldl;
+ if (newl) memcpy(r+oldl, q, newl);
+ r[oldl+newl]=0;
+ *hdrp= r;
+ }
+
+#if 1
+ if (!replyto)
+ replyto=strdup(from ? from:"");
+ if (!sender)
+ sender=strdup(from ? from:"");
+
+ if (!replyto || !sender)
+ {
+ perror("malloc");
+ exit(1);
+ }
+#endif
+
+ (*writefunc)("(", 1);
+ doenvs(writefunc, date);
+ (*writefunc)(" ", 1);
+ doenvs(writefunc, subject);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, from);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, sender);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, replyto);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, to);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, cc);
+ (*writefunc)(" ", 1);
+ doenva(writefunc, bcc);
+ (*writefunc)(" ", 1);
+ doenvs(writefunc, inreplyto);
+ (*writefunc)(" ", 1);
+ doenvs(writefunc, msgid);
+ (*writefunc)(")", 1);
+}