--- fetchmail-6.3.4/contrib/fetchmail-mode.el.stripnul 2005-12-01 00:33:08.000000000 +0100 +++ fetchmail-6.3.4/contrib/fetchmail-mode.el 2006-08-29 18:50:09.000000000 +0200 @@ -75,7 +75,7 @@ (unless fetchmail-keywords (setq fetchmail-keywords - '("poll" "skip" "via" "in" "proto" "protocol" "uidl" "no" "port" "auth" "authenticate" "timeout" "envelope" "qvirtual" "envelope" "aka" "localdomains" "interface" "monitor" "dns" "user" "username" "is" "folder" "pass" "password" "smtp" "smtphost" "smtpaddress" "antispam" "mda" "pre" "preconnect" "post" "postconnect" "keep" "flush" "fetchall" "rewrite" "forcecr" "stripcr" "pass8bits" "dropstatus" "limit" "fetchlimit" "batchlimit" "expunge" "pop2" "POP2" "pop3" "POP3" "imap" "IMAP" "imap-k4" "IMAP-K4" "apop" "APOP" "rpop" "RPOP" "kpop" "KPOP" "etrn" "ETRN" "login" "kerberos" "kerberos_v5" "logfile" "daemon" "syslog" "invisible" "and" "with" "has" "wants" "options" "here" "there" "aka" "set"))) + '("poll" "skip" "via" "in" "proto" "protocol" "uidl" "no" "port" "auth" "authenticate" "timeout" "envelope" "qvirtual" "envelope" "aka" "localdomains" "interface" "monitor" "dns" "user" "username" "is" "folder" "pass" "password" "smtp" "smtphost" "smtpaddress" "antispam" "mda" "pre" "preconnect" "post" "postconnect" "keep" "flush" "fetchall" "rewrite" "forcecr" "stripcr" "stripnul" "pass8bits" "dropstatus" "limit" "fetchlimit" "batchlimit" "expunge" "pop2" "POP2" "pop3" "POP3" "imap" "IMAP" "imap-k4" "IMAP-K4" "apop" "APOP" "rpop" "RPOP" "kpop" "KPOP" "etrn" "ETRN" "login" "kerberos" "kerberos_v5" "logfile" "daemon" "syslog" "invisible" "and" "with" "has" "wants" "options" "here" "there" "aka" "set"))) (defvar fetchmail-keyword-table nil "Completion table for fetchmail-mode" ) --- fetchmail-6.3.4/fetchmail-features.html.stripnul 2006-03-31 02:26:03.000000000 +0200 +++ fetchmail-6.3.4/fetchmail-features.html 2006-08-29 18:50:09.000000000 +0200 @@ -181,6 +181,10 @@ forwarding.</li> </ul> +<li>The stripnul option to explicitly control +NUL character stripping before mail forwarding.</li> +</ul> + <h2>Since 2.0:</h2> <ul> --- fetchmail-6.3.4/fetchmail.h.stripnul 2006-04-02 12:18:20.000000000 +0200 +++ fetchmail-6.3.4/fetchmail.h 2006-08-29 18:50:09.000000000 +0200 @@ -322,6 +322,7 @@ flag limitflush; /* if TRUE, delete oversized mails */ flag rewrite; /* if TRUE, canonicalize recipient addresses */ flag stripcr; /* if TRUE, strip CRs in text */ + flag stripnul; /* if TRUE, strip NUL characters in text */ 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 */ --- fetchmail-6.3.4/fetchmail.man.stripnul 2006-04-06 11:44:05.000000000 +0200 +++ fetchmail-6.3.4/fetchmail.man 2006-08-29 18:50:09.000000000 +0200 @@ -1671,6 +1671,9 @@ forcecr \& \& T{ Force carriage returns at ends of lines T} +stripnul \& T{ +Strip NUL characters from text +T} pass8bits \& \& T{ Force BODY=8BITMIME to ESMTP listener T} --- fetchmail-6.3.4/fetchmailconf.py.stripnul 2006-03-14 17:10:10.000000000 +0100 +++ fetchmail-6.3.4/fetchmailconf.py 2006-08-29 18:50:09.000000000 +0200 @@ -240,6 +240,7 @@ self.rewrite = TRUE # Rewrite message headers self.forcecr = FALSE # Force LF -> CR/LF self.stripcr = FALSE # Strip CR + self.stripnul = FALSE # Strip NUL self.pass8bits = FALSE # Force BODY=7BIT self.mimedecode = FALSE # Undo MIME armoring self.dropstatus = FALSE # Drop incoming Status lines @@ -280,6 +281,7 @@ ('rewrite', 'Boolean'), ('forcecr', 'Boolean'), ('stripcr', 'Boolean'), + ('stripnul', 'Boolean'), ('pass8bits', 'Boolean'), ('mimedecode', 'Boolean'), ('dropstatus', 'Boolean'), @@ -317,6 +319,7 @@ or self.rewrite != UserDefaults.rewrite or self.forcecr != UserDefaults.forcecr or self.stripcr != UserDefaults.stripcr + or self.stripnul != UserDefaults.stripnul or self.pass8bits != UserDefaults.pass8bits or self.mimedecode != UserDefaults.mimedecode or self.dropstatus != UserDefaults.dropstatus @@ -337,6 +340,8 @@ res = res + flag2str(self.forcecr, 'forcecr') if self.stripcr != UserDefaults.stripcr: res = res + flag2str(self.stripcr, 'stripcr') + if self.stripnul != UserDefaults.stripnul: + res = res + flag2str(self.stripcr, 'stripnul') if self.pass8bits != UserDefaults.pass8bits: res = res + flag2str(self.pass8bits, 'pass8bits') if self.mimedecode != UserDefaults.mimedecode: @@ -1703,6 +1708,8 @@ variable=self.forcecr).pack(side=TOP, anchor=W) Checkbutton(optwin, text="Strip CR from end of each line", variable=self.stripcr).pack(side=TOP, anchor=W) + Checkbutton(optwin, text="Strip NUL character", + variable=self.stripnul).pack(side=TOP, anchor=W) Checkbutton(optwin, text="Pass 8 bits even though SMTP says 7BIT", variable=self.pass8bits).pack(side=TOP, anchor=W) Checkbutton(optwin, text="Undo MIME armoring on header and body", --- fetchmail-6.3.4/rcfile_l.l.stripnul 2006-04-02 12:23:41.000000000 +0200 +++ fetchmail-6.3.4/rcfile_l.l 2006-08-29 18:50:09.000000000 +0200 @@ -154,6 +154,7 @@ norewrite | noforcecr | nostripcr | +nostripnul | nopass8(bits)? | nodropstatus | nodropdelivered | @@ -173,6 +174,7 @@ rewrite { return REWRITE; } forcecr { return FORCECR; } stripcr { return STRIPCR; } +stripnul { return STRIPNUL; } pass8(bits)? { return PASS8BITS; } dropstatus { return DROPSTATUS; } dropdelivered { return DROPDELIVERED; } #--- fetchmail-6.3.4/rcfile_y.y.stripnul 2006-04-02 12:34:01.000000000 +0200 #+++ fetchmail-6.3.4/rcfile_y.y 2006-08-29 18:50:09.000000000 +0200 #@@ -73,9 +73,9 @@ # %token <proto> PROTO AUTHTYPE # %token <sval> STRING # %token <number> NUMBER #-%token NO KEEP FLUSH LIMITFLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS #+%token NO KEEP FLUSH LIMITFLUSH FETCHALL REWRITE FORCECR STRIPCR STRIPNUL PASS8BITS # %token DROPSTATUS DROPDELIVERED # %token DNS SERVICE PORT UIDL INTERVAL MIMEDECODE IDLE CHECKALIAS # %token SSL SSLKEY SSLCERT SSLPROTO SSLCERTCK SSLCERTPATH SSLFINGERPRINT #@@ -320,6 +320,7 @@ # | REWRITE {current.rewrite = FLAG_TRUE;} # | FORCECR {current.forcecr = FLAG_TRUE;} # | STRIPCR {current.stripcr = FLAG_TRUE;} #+ | STRIPNUL {current.stripnul = FLAG_TRUE;} # | PASS8BITS {current.pass8bits = FLAG_TRUE;} # | DROPSTATUS {current.dropstatus = FLAG_TRUE;} # | DROPDELIVERED {current.dropdelivered = FLAG_TRUE;} #@@ -347,6 +348,7 @@ # | NO REWRITE {current.rewrite = FLAG_FALSE;} # | NO FORCECR {current.forcecr = FLAG_FALSE;} # | NO STRIPCR {current.stripcr = FLAG_FALSE;} #+ | NO STRIPNUL {current.stripnul = FLAG_FALSE;} # | NO PASS8BITS {current.pass8bits = FLAG_FALSE;} # | NO DROPSTATUS {current.dropstatus = FLAG_FALSE;} # | NO DROPDELIVERED {current.dropdelivered = FLAG_FALSE;} --- fetchmail-6.3.4/sink.c.stripnul 2006-04-04 14:14:37.000000000 +0200 +++ fetchmail-6.3.4/sink.c 2006-08-29 19:03:08.000000000 +0200 @@ -619,6 +619,14 @@ int n, oldphase; char *last; + if (ctl->stripnul) + { + if (*buf == '\0') + { + return 0; /* skip lines containing only the NUL character */ + } + } + /* The line may contain NUL characters. Find the last char to use * -- the real line termination is the sequence "\n\0". */ --- fetchmail-6.3.9/fetchmail.c +++ fetchmail-6.3.9/fetchmail.c 2009-01-08 16:27:31.000000000 +0100 @@ -94,11 +94,11 @@ struct group *gr; gid_t egid; gid_t rgid; - + egid = getegid(); rgid = getgid(); gr = getgrgid(egid); - + if (gr && !strcmp(gr->gr_name, "kmem")) { extern void interface_set_gids(gid_t egid, gid_t rgid); @@ -127,7 +127,7 @@ #define timestamp rfc822timestamp #endif -static RETSIGTYPE donothing(int sig) +static RETSIGTYPE donothing(int sig) { set_signal_handler(sig, donothing); lastsig = sig; @@ -189,7 +189,7 @@ #define IDFILE_NAME ".fetchids" run.idfile = prependdir (IDFILE_NAME, fmhome); - + outlevel = O_NORMAL; /* @@ -223,7 +223,7 @@ if (versioninfo) { - const char *features = + const char *features = #ifdef POP2_ENABLE "+POP2" #endif /* POP2_ENABLE */ @@ -348,7 +348,7 @@ free(netrc_file); #undef NETRC_FILE - /* pick up passwords where we can */ + /* pick up passwords where we can */ for (ctl = querylist; ctl; ctl = ctl->next) { if (ctl->active && !(implicitmode && ctl->server.skip)&&!ctl->password) @@ -371,7 +371,7 @@ /* otherwise try with "via" name if there is one */ else if (ctl->server.via) { - p = search_netrc(netrc_list, + p = search_netrc(netrc_list, ctl->server.via, ctl->remotename); if (p && p->password) ctl->password = xstrdup(p->password); @@ -512,7 +512,7 @@ } } - /* pick up interactively any passwords we need but don't have */ + /* pick up interactively any passwords we need but don't have */ for (ctl = querylist; ctl; ctl = ctl->next) { if (ctl->active && !(implicitmode && ctl->server.skip) @@ -613,7 +613,7 @@ * reflect the status of that transaction. */ do { - /* + /* * Check to see if the rcfile has been touched. If so, * re-exec so the file will be reread. Doing it this way * avoids all the complications of trying to deallocate the @@ -626,7 +626,7 @@ /* do nothing */ } else if (stat(rcfile, &rcstat) == -1) { if (errno != ENOENT) - report(stderr, + report(stderr, GT_("couldn't time-check %s (error %d)\n"), rcfile, errno); } @@ -693,16 +693,16 @@ { if (ctl->wedged) { - report(stderr, + report(stderr, GT_("poll of %s skipped (failed authentication or too many timeouts)\n"), ctl->server.pollname); continue; } /* check skip interval first so that it counts all polls */ - if (run.poll_interval && ctl->server.interval) + if (run.poll_interval && ctl->server.interval) { - if (ctl->server.poll_count++ % ctl->server.interval) + if (ctl->server.poll_count++ % ctl->server.interval) { if (outlevel >= O_VERBOSE) report(stdout, @@ -739,13 +739,13 @@ if (querystatus == PS_SUCCESS) successes++; - else if (!check_only && + else if (!check_only && ((querystatus!=PS_NOMAIL) || (outlevel==O_DEBUG))) switch(querystatus) { case PS_SUCCESS: report(stdout,GT_("Query status=0 (SUCCESS)\n"));break; - case PS_NOMAIL: + case PS_NOMAIL: report(stdout,GT_("Query status=1 (NOMAIL)\n")); break; case PS_SOCKET: report(stdout,GT_("Query status=2 (SOCKET)\n")); break; @@ -799,7 +799,7 @@ */ if (run.poll_interval) { - /* + /* * Because passwords can expire, it may happen that *all* * hosts are now out of the loop due to authfail * conditions. If this happens daemon-mode fetchmail @@ -824,7 +824,7 @@ GT_("sleeping at %s for %d seconds\n"), timestamp(), run.poll_interval); /* - * With this simple hack, we make it possible for a foreground + * With this simple hack, we make it possible for a foreground * fetchmail to wake up one in daemon mode. What we want is the * side effect of interrupting any sleep that may be going on, * forcing fetchmail to re-poll its hosts. The second line is @@ -844,10 +844,10 @@ { if (outlevel > O_SILENT) #ifdef SYS_SIGLIST_DECLARED - report(stdout, + report(stdout, GT_("awakened by %s\n"), sys_siglist[lastsig]); #else - report(stdout, + report(stdout, GT_("awakened by signal %d\n"), lastsig); #endif for (ctl = querylist; ctl; ctl = ctl->next) @@ -880,7 +880,7 @@ /* * If force is off, modify dstl fields only when they're empty (treat srcl * as defaults). If force is on, modify each dstl field whenever scrcl - * is nonempty (treat srcl as an override). + * is nonempty (treat srcl as an override). */ if (force ? !!*srcl : !*dstl) { @@ -944,6 +944,7 @@ FLAG_MERGE(rewrite); FLAG_MERGE(forcecr); FLAG_MERGE(stripcr); + FLAG_MERGE(stripnul); FLAG_MERGE(pass8bits); FLAG_MERGE(dropstatus); FLAG_MERGE(dropdelivered); @@ -1032,7 +1033,7 @@ ctl->active = !ctl->server.skip; } else - for (; optind < argc; optind++) + for (; optind < argc; optind++) { flag predeclared = FALSE; @@ -1069,7 +1070,7 @@ /* * If there's a defaults record, merge it and lose it. - */ + */ if (querylist && strcmp(querylist->server.pollname, "defaults") == 0) { for (ctl = querylist->next; ctl; ctl = ctl->next) @@ -1123,11 +1124,11 @@ * to be fully-qualified domain names. The default for * this list should be the FQDN of localhost. * - * If we're using Kerberos for authentication, we need + * If we're using Kerberos for authentication, we need * the FQDN in order to generate capability keys. */ for (ctl = querylist; ctl; ctl = ctl->next) - if (ctl->active && + if (ctl->active && (ctl->server.protocol==P_ETRN || ctl->server.protocol==P_ODMR || ctl->server.authenticate == A_KERBEROS_V4 || ctl->server.authenticate == A_KERBEROS_V5)) @@ -1161,10 +1162,10 @@ optmerge(ctl, &cmd_opts, TRUE); /* - * queryname has to be set up for inactive servers too. + * queryname has to be set up for inactive servers too. * Otherwise the UIDL code core-dumps on startup. */ - if (ctl->server.via) + if (ctl->server.via) ctl->server.queryname = xstrdup(ctl->server.via); else ctl->server.queryname = xstrdup(ctl->server.pollname); @@ -1183,8 +1184,9 @@ DEFAULT(ctl->flush, FALSE); DEFAULT(ctl->limitflush, FALSE); DEFAULT(ctl->rewrite, TRUE); - DEFAULT(ctl->stripcr, (ctl->mda != (char *)NULL)); - DEFAULT(ctl->forcecr, FALSE); + DEFAULT(ctl->stripcr, (ctl->mda != (char *)NULL)); + DEFAULT(ctl->stripnul, FALSE); + DEFAULT(ctl->forcecr, FALSE); DEFAULT(ctl->pass8bits, FALSE); DEFAULT(ctl->dropstatus, FALSE); DEFAULT(ctl->dropdelivered, FALSE); @@ -1200,7 +1202,7 @@ * XXX FIXME: do we need this check or can we rely on the .y * parser handling this? */ - if (ctl->use_ssl) + if (ctl->use_ssl) { report(stderr, GT_("SSL support is not compiled in.\n")); exit(PS_SYNTAX); @@ -1364,7 +1366,7 @@ terminate_poll(sig); - /* + /* * Craig Metz, the RFC1938 one-time-password guy, points out: * "Remember that most kernels don't zero pages before handing them to the * next process and many kernels share pages between user and kernel space. @@ -1392,7 +1394,7 @@ /* * Sequence of protocols to try when autoprobing, most capable to least. */ -static const int autoprobe[] = +static const int autoprobe[] = { #ifdef IMAP_ENABLE P_IMAP, @@ -1431,7 +1433,7 @@ ctl->server.protocol = autoprobe[i]; do { st = query_host(ctl); - } while + } while (st == PS_REPOLL); if (st == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL || st == PS_LOCKBUSY || st == PS_SMTP || st == PS_MAXFETCH || st == PS_DNS) break; @@ -1573,7 +1575,7 @@ } } - if (ctl->server.protocol == P_POP3 + if (ctl->server.protocol == P_POP3 && ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT) && (ctl->server.authenticate == A_KERBEROS_V4 || ctl->server.authenticate == A_KERBEROS_V5)) @@ -1646,7 +1648,7 @@ else printf(".\n"); - if (MAILBOX_PROTOCOL(ctl)) + if (MAILBOX_PROTOCOL(ctl)) { if (!ctl->mailboxes->id) printf(GT_(" Default mailbox selected.\n")); @@ -1677,7 +1679,10 @@ printf(ctl->stripcr ? GT_(" Carriage-return stripping is enabled (stripcr on).\n") : GT_(" Carriage-return stripping is disabled (stripcr off).\n")); - printf(ctl->forcecr + printf(ctl->stripnul + ? GT_(" NUL character stripping is enabled (stripnul on).\n") + : GT_(" NUL character stripping is disbled (stripnul off).\n")); + printf(ctl->forcecr ? GT_(" Carriage-return forcing is enabled (forcecr on).\n") : GT_(" Carriage-return forcing is disabled (forcecr off).\n")); printf(ctl->pass8bits @@ -1698,12 +1703,12 @@ if (NUM_NONZERO(ctl->limit)) { if (NUM_NONZERO(ctl->limit)) - printf(GT_(" Message size limit is %d octets (--limit %d).\n"), + printf(GT_(" Message size limit is %d octets (--limit %d).\n"), ctl->limit, ctl->limit); else if (outlevel >= O_VERBOSE) printf(GT_(" No message size limit (--limit 0).\n")); if (run.poll_interval > 0) - printf(GT_(" Message size warning interval is %d seconds (--warnings %d).\n"), + printf(GT_(" Message size warning interval is %d seconds (--warnings %d).\n"), ctl->warnings, ctl->warnings); else if (outlevel >= O_VERBOSE) printf(GT_(" Size warnings on every poll (--warnings 0).\n")); @@ -1762,7 +1767,7 @@ if (ctl->smtphunt) { - printf(GT_(" Messages will be %cMTP-forwarded to:"), + printf(GT_(" Messages will be %cMTP-forwarded to:"), ctl->listener); for (idp = ctl->smtphunt; idp; idp = idp->next) { @@ -1855,7 +1860,7 @@ if (ctl->server.qvirtual) printf(GT_(" Prefix %s will be removed from user id\n"), ctl->server.qvirtual); - else if (outlevel >= O_VERBOSE) + else if (outlevel >= O_VERBOSE) printf(GT_(" No prefix stripping\n")); }