summaryrefslogtreecommitdiffstats
path: root/imap/pop3dserver.c
diff options
context:
space:
mode:
authorSam Varshavchik2018-11-16 20:40:52 -0500
committerSam Varshavchik2018-11-16 20:40:52 -0500
commitbefd23187c407f2462d0abc6359db46c5dd22a66 (patch)
tree392a15c2534bbf0b7b3d123c4b7bf66165e90b13 /imap/pop3dserver.c
parent7f7351fd49c4b858612b821790a7707416078c46 (diff)
downloadcourier-libs-befd23187c407f2462d0abc6359db46c5dd22a66.tar.bz2
Adjust Unicode wrapping.
Diffstat (limited to 'imap/pop3dserver.c')
-rw-r--r--imap/pop3dserver.c103
1 files changed, 88 insertions, 15 deletions
diff --git a/imap/pop3dserver.c b/imap/pop3dserver.c
index beca04a..8972668 100644
--- a/imap/pop3dserver.c
+++ b/imap/pop3dserver.c
@@ -92,6 +92,7 @@ static unsigned msglist_cnt;
static struct stat enomem_stat;
static int enomem_1msg;
int utf8_enabled;
+int savesizes=0;
/*
** When a disk error occurs while saving an updated courierpop3dsizelist
@@ -178,7 +179,7 @@ static struct msglist **readpop3dlist(unsigned long *uid)
struct msglist *list=NULL;
size_t mcnt=0;
- char linebuf[1024];
+ char linebuf[2048];
FILE *fp=openpop3dlist();
@@ -191,12 +192,18 @@ static struct msglist **readpop3dlist(unsigned long *uid)
fgets(linebuf, sizeof(linebuf)-1, fp) == NULL ||
linebuf[0] != '/' || sscanf(linebuf+1, "%d %lu %lu", &vernum,
uid, &uidv)
- < 2 || vernum != LISTVERSION)
+ < 2 || (vernum != LISTVERSION &&
+ vernum != (LISTVERSION-1)))
{
if (fp)
fclose(fp);
fp=NULL;
}
+ else
+ {
+ if (vernum != LISTVERSION)
+ savesizes=1;
+ }
if (fp)
{
@@ -211,7 +218,7 @@ static struct msglist **readpop3dlist(unsigned long *uid)
{
if (ch != '\n')
{
- if (n < sizeof(linebuf)-3)
+ if (n < sizeof(linebuf)-20)
linebuf[n++]=ch;
continue;
}
@@ -243,6 +250,10 @@ static struct msglist **readpop3dlist(unsigned long *uid)
exit(1);
}
+ // Converting from LISTVERSION 2, assuming no UTF-8.
+ // We have extra room at the end.
+ strcat(p, ":0");
+
if (sscanf(p, "%lu %lu:%lu:%d", &m->size,
&m->uid.n, &m->uid.uidv,
&m->isutf8) == 4)
@@ -417,7 +428,6 @@ static void sortmsgs()
size_t i, n;
struct msglist *m;
struct msglist **prev_list;
- int savesizes=0;
unsigned long nextuid;
@@ -637,6 +647,59 @@ char buf[NUMBUFSIZE];
/* RETR and TOP POP3 commands */
+#define MIMEWRAPTXT \
+ "From: Mail Delivery Subsystem <postmaster>\n" \
+ "Subject: Cannot display Unicode content\n" \
+ "Mime-Version: 1.0\n" \
+ "Content-Type: multipart/mixed; boundary=\"%s\"\n" \
+ "\n\n\n--%s\n" \
+ "Content-Type: text/plain\n\n" \
+ "This E-mail message was determined to be Unicode-formatted\n" \
+ "but your E-mail reader does not support Unicode E-mail.\n\n" \
+ "Please use an E-mail reader that supports POP3 with UTF-8\n" \
+ "(see https://tools.ietf.org/html/rfc6856.html).\n\n" \
+ "This can also happen when the sender's E-mail program does not\n" \
+ "correctly format the sent message.\n\n" \
+ "The original message is included as a separate attachment\n" \
+ "so that it can be downloaded manually.\n\n" \
+ "--%s\n" \
+ "Content-Type: message/global\n\n"
+
+struct retr_source {
+ char *wrapheader;
+ FILE *f;
+ char *wrapfooter;
+};
+
+static int get_retr_source(struct retr_source *s)
+{
+ int c=(unsigned char)*s->wrapheader;
+
+ if (c)
+ {
+ ++s->wrapheader;
+ return c;
+ }
+
+ if (s->f)
+ {
+ int c=getc(s->f);
+
+ if (c >= 0)
+ return c;
+ s->f=0;
+ }
+
+ if (*s->wrapfooter)
+ {
+ int c=(unsigned char)*s->wrapfooter;
+
+ ++s->wrapfooter;
+ return c;
+ }
+ return -1;
+}
+
static void do_retr(unsigned i, unsigned *lptr)
{
FILE *f;
@@ -645,18 +708,21 @@ static void do_retr(unsigned i, unsigned *lptr)
int inheader=1;
char buf[NUMBUFSIZE];
unsigned long *cntr;
+ char boundary[256];
+ char wrapheader[sizeof(MIMEWRAPTXT)+768];
+ char wrapfooter[512];
+
+ struct retr_source rs;
+
+ wrapheader[0]=0;
+ wrapfooter[0]=0;
if (msglist_a[i]->isutf8 && !utf8_enabled)
{
- printed(printf("-ERR Cannot open message %u because it is"
- " a Unicode message and your E-mail reader"
- " did not enable Unicode support. Please"
- " use an E-mail reader that supports POP3"
- " with UTF-8 (see"
- " https://tools.ietf.org/html/rfc6856.html)\r\n",
- i+1));
- fflush(stdout);
- return;
+ sprintf(boundary, "=_%d-%d", (int)getpid(), (int)time(NULL));
+
+ sprintf(wrapheader, MIMEWRAPTXT, boundary, boundary, boundary);
+ sprintf(wrapfooter, "\n--%s--\n", boundary);
}
f=fopen(msglist_a[i]->filename, "r");
@@ -668,13 +734,20 @@ static void do_retr(unsigned i, unsigned *lptr)
return;
}
printed(printf( (lptr ? "+OK headers follow.\r\n":"+OK %s octets follow.\r\n"),
- libmail_str_off_t(msglist_a[i]->size, buf)));
+ libmail_str_off_t(msglist_a[i]->size +
+ strlen(wrapheader) +
+ strlen(wrapfooter),
+ buf)));
cntr= &retr_count;
if (lptr)
cntr= &top_count;
- for (lastc=0; (c=getc(f)) >= 0; lastc=c)
+ rs.wrapheader=wrapheader;
+ rs.f=f;
+ rs.wrapfooter=wrapfooter;
+
+ for (lastc=0; (c=get_retr_source(&rs)) >= 0; lastc=c)
{
if (lastc == '\n')
{