aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in10
-rw-r--r--driver.c15
-rw-r--r--etrn.c7
-rw-r--r--fetchmail.c1
-rw-r--r--fetchmail.h10
-rw-r--r--imap.c4
-rw-r--r--pop2.c5
-rw-r--r--pop3.c6
-rw-r--r--rcfile_l.l1
-rw-r--r--rcfile_y.y6
10 files changed, 46 insertions, 19 deletions
diff --git a/Makefile.in b/Makefile.in
index a983c2f3..db605dec 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -83,7 +83,7 @@ CTAGS = ctags
protobjs = rcfile_y.o rcfile_l.o socket.o getpass.o pop2.o pop3.o imap.o \
etrn.o fetchmail.o env.o options.o daemon.o driver.o rfc822.o smtp.o \
xmalloc.o uid.o mxget.o md5c.o md5ify.o rpa.o interface.o netrc.o \
- base64.o error.o
+ base64.o error.o unmime.o
objs = $(protobjs) $(extras) $(EXTRAOBJ)
@@ -95,7 +95,7 @@ srcs = $(srcdir)/socket.c $(srcdir)/getpass.c $(srcdir)/pop2.c \
$(srcdir)/xmalloc.c $(srcdir)/uid.c $(srcdir)/mxget.c \
$(srcdir)/md5c.c $(srcdir)/md5ify.c $(srcdir)/rpa.c \
$(srcdir)/interface.c $(srcdir)/netrc.c $(srcdir)/base64.c \
- $(srcdir)/error.c
+ $(srcdir)/error.c $(srcdir)/unmime.c
.SUFFIXES:
.SUFFIXES: .o .c .h .y .l .ps .dvi .info .texi
@@ -112,6 +112,10 @@ fetchmail: $(objs)
rfc822: rfc822.c
gcc -DTESTMAIN -g rfc822.c -o rfc822
+# Stand-alone MIME decoder
+unmime: unmime.c base64.c rfc822.c xmalloc.c error.c
+ $(CC) -DSTANDALONE -g -o $@ $^
+
.c.o:
$(CC) $(defines) -c -I$(srcdir) -I. $(CEFLAGS) $(CFLAGS) $<
@@ -147,7 +151,7 @@ clean:
-rm -f fetchmail *.o core fetchmail.dvi \
rcfile_l.c rcfile_y.h rcfile_y.c \
fetchmail.tar fetchmail.tar.gz \
- rfc822
+ rfc822 unmime
distclean: clean
-rm -f Makefile config.h TAGS tags
diff --git a/driver.c b/driver.c
index a3e8a633..19a55b32 100644
--- a/driver.c
+++ b/driver.c
@@ -1826,7 +1826,7 @@ const struct method *proto; /* protocol method table */
else
{
char buf [POPBUFSIZE+1], *realhost;
- int *msgsizes, len, num, count, new, deletions = 0;
+ int *msgsizes, len, num, count, new, bytes, deletions = 0;
#if INET6
int fetches, dispatches;
#else /* INET6 */
@@ -1955,7 +1955,7 @@ const struct method *proto; /* protocol method table */
error(0, 0, "selecting or re-polling default folder");
/* compute # of messages and number of new messages waiting */
- ok = (protocol->getrange)(sock, ctl, idp->id, &count, &new);
+ ok = (protocol->getrange)(sock, ctl, idp->id, &count, &new, &bytes);
if (ok != 0)
goto cleanUp;
@@ -1964,18 +1964,23 @@ const struct method *proto; /* protocol method table */
(void) sprintf(buf, "%s at %s (folder %s)",
ctl->remotename, ctl->server.truename, idp->id);
else
- (void) sprintf(buf, "%s at %s", ctl->remotename, ctl->server.truename);
+ (void) sprintf(buf, "%s at %s",
+ ctl->remotename, ctl->server.truename);
if (outlevel > O_SILENT)
if (count == -1) /* only used for ETRN */
error(0, 0, "Polling %s", ctl->server.truename);
else if (count != 0)
{
if (new != -1 && (count - new) > 0)
- error(0, 0, "%d message%s (%d seen) for %s.",
+ error_build("%d message%s (%d seen) for %s",
count, count > 1 ? "s" : "", count-new, buf);
else
- error(0, 0, "%d message%s for %s.",
+ error_build("%d message%s for %s",
count, count > 1 ? "s" : "", buf);
+ if (bytes == -1)
+ error_complete(0, 0, ".");
+ else
+ error_complete(0, 0, " (%d bytes).", bytes);
}
else
{
diff --git a/etrn.c b/etrn.c
index 7deb4312..69175149 100644
--- a/etrn.c
+++ b/etrn.c
@@ -28,8 +28,8 @@ static int etrn_ok (int sock, char *argbuf)
return(ok);
}
-static int etrn_getrange(int sock, struct query *ctl, char *id, int *countp,
- int *newp)
+static int etrn_getrange(int sock, struct query *ctl, char *id,
+ int *countp, int *newp, int *bytes)
/* send ETRN and interpret the response */
{
int ok, opts;
@@ -49,7 +49,8 @@ static int etrn_getrange(int sock, struct query *ctl, char *id, int *countp,
return(PS_PROTOCOL);
}
- *countp = *newp = -1; /* make sure we don't enter the fetch loop */
+ /* make sure we don't enter the fetch loop */
+ *bytes = *countp = *newp = -1;
/*
* By default, the hostlist has a single entry, the fetchmail host's
diff --git a/fetchmail.c b/fetchmail.c
index 9ce2b066..43799cc1 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -753,6 +753,7 @@ static int load_params(int argc, char **argv, int optind)
DEFAULT(ctl->forcecr, FALSE);
DEFAULT(ctl->pass8bits, FALSE);
DEFAULT(ctl->dropstatus, FALSE);
+ DEFAULT(ctl->mimedecode, TRUE);
DEFAULT(ctl->server.dns, TRUE);
DEFAULT(ctl->server.uidl, FALSE);
#undef DEFAULT
diff --git a/fetchmail.h b/fetchmail.h
index 4f01557d..1f528c06 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -169,6 +169,7 @@ struct query
flag forcecr; /* if TRUE, force CRs before LFs in text */
flag pass8bits; /* if TRUE, ignore Content-Transfer-Encoding */
flag dropstatus; /* if TRUE, drop Status lines in mail */
+ flag mimedecode; /* if TRUE, decode MIME-coded headers/coded printable*/
int limit; /* limit size of retrieved messages */
int fetchlimit; /* max # msgs to get in single poll */
int batchlimit; /* max # msgs to pass in single SMTP session */
@@ -326,6 +327,15 @@ int prc_filecheck(const char *);
void to64frombits(unsigned char *, const unsigned char *, int);
int from64tobits(char *, const char *);
+/* unmime.c */
+/* Bit-mask returned by MimeBodyType */
+#define MSG_IS_7BIT 0x01
+#define MSG_IS_8BIT 0x02
+#define MSG_NEEDS_DECODE 0x80
+extern void UnMimeHeader(unsigned char *buf);
+extern int MimeBodyType(unsigned char *hdrs);
+extern int UnMimeBodyline(unsigned char **buf, int collapsedoubledot);
+
/* interface.c */
void interface_parse(char *, struct hostdata *);
void interface_note_activity(struct hostdata *);
diff --git a/imap.c b/imap.c
index 227565cd..86a5e245 100644
--- a/imap.c
+++ b/imap.c
@@ -709,13 +709,13 @@ static int internal_expunge(int sock)
static int imap_getrange(int sock,
struct query *ctl,
const char *folder,
- int *countp, int *newp)
+ int *countp, int *newp, int *bytes)
/* get range of messages to be fetched */
{
int ok;
/* find out how many messages are waiting */
- recent = unseen = -1;
+ *bytes, recent = unseen = -1;
if (pass > 1)
{
diff --git a/pop2.c b/pop2.c
index ee0e7809..a17a4e22 100644
--- a/pop2.c
+++ b/pop2.c
@@ -59,7 +59,8 @@ int pop2_getauth(int sock, struct query *ctl, char *buf)
ctl->remotename, ctl->password));
}
-static int pop2_getrange(int sock, struct query *ctl, const char *folder, int*countp, int*newp)
+static int pop2_getrange(int sock, struct query *ctl, const char *folder,
+ int *countp, int *newp, int *bytes)
/* get range of messages to be fetched */
{
/* maybe the user wanted a non-default folder */
@@ -87,7 +88,7 @@ static int pop2_getrange(int sock, struct query *ctl, const char *folder, int*co
return(PS_ERROR);
*countp = pound_arg;
- *newp = -1;
+ *bytes = *newp = -1;
return(0);
}
diff --git a/pop3.c b/pop3.c
index 9502d104..f189e39d 100644
--- a/pop3.c
+++ b/pop3.c
@@ -353,7 +353,7 @@ pop3_slowuidl( int sock, struct query *ctl, int *countp, int *newp)
static int pop3_getrange(int sock,
struct query *ctl,
const char *folder,
- int *countp, int *newp)
+ int *countp, int *newp, int *bytes)
/* get range of messages to be fetched */
{
int ok;
@@ -375,7 +375,7 @@ static int pop3_getrange(int sock,
gen_send(sock, "STAT");
ok = pop3_ok(sock, buf);
if (ok == 0)
- sscanf(buf,"%d %*d", countp);
+ sscanf(buf,"%d %d", countp, bytes);
else
return(ok);
@@ -445,7 +445,7 @@ static int pop3_getrange(int sock,
}
}
- return(0);
+ return(PS_SUCCESS);
}
static int pop3_getsizes(int sock, int count, int *sizes)
diff --git a/rcfile_l.l b/rcfile_l.l
index 995ebfc1..0c8e5edf 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -79,6 +79,7 @@ forcecr { return FORCECR; }
stripcr { return STRIPCR; }
pass8(bits)? { return PASS8BITS; }
dropstatus? { return DROPSTATUS; }
+mimedec(ode)? { return MIMEDECODE; }
dns { return DNS; }
uidl { return UIDL; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 9c536bdf..49e85fc4 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -72,7 +72,7 @@ extern char * yytext;
%token <sval> STRING
%token <number> NUMBER
%token NO KEEP FLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS DROPSTATUS
-%token DNS SERVICE PORT UIDL INTERVAL
+%token DNS SERVICE PORT UIDL INTERVAL MIMEDECODE
%%
@@ -283,6 +283,7 @@ user_option : TO localnames HERE
| STRIPCR {current.stripcr = FLAG_TRUE;}
| PASS8BITS {current.pass8bits = FLAG_TRUE;}
| DROPSTATUS {current.dropstatus = FLAG_TRUE;}
+ | MIMEDECODE {current.mimedecode = FLAG_TRUE;}
| NO KEEP {current.keep = FLAG_FALSE;}
| NO FLUSH {current.flush = FLAG_FALSE;}
@@ -292,6 +293,7 @@ user_option : TO localnames HERE
| NO STRIPCR {current.stripcr = FLAG_FALSE;}
| NO PASS8BITS {current.pass8bits = FLAG_FALSE;}
| NO DROPSTATUS {current.dropstatus = FLAG_FALSE;}
+ | NO MIMEDECODE {current.mimedecode = FLAG_FALSE;}
| LIMIT NUMBER {current.limit = NUM_VALUE($2);}
| FETCHLIMIT NUMBER {current.fetchlimit = NUM_VALUE($2);}
@@ -500,6 +502,7 @@ static void record_current(void)
FLAG_FORCE(stripcr);
FLAG_FORCE(pass8bits);
FLAG_FORCE(dropstatus);
+ FLAG_FORCE(mimedecode);
FLAG_FORCE(limit);
FLAG_FORCE(fetchlimit);
FLAG_FORCE(batchlimit);
@@ -560,6 +563,7 @@ void optmerge(struct query *h2, struct query *h1)
FLAG_MERGE(stripcr);
FLAG_MERGE(pass8bits);
FLAG_MERGE(dropstatus);
+ FLAG_MERGE(mimedecode);
FLAG_MERGE(limit);
FLAG_MERGE(fetchlimit);
FLAG_MERGE(batchlimit);