summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaac Dunham <ibid.ag@gmail.com>2015-01-27 21:35:30 -0800
committerNatanael Copa <ncopa@alpinelinux.org>2015-01-30 10:14:12 +0000
commit61ff788630422f3a99da03034c34e0a5d0c24910 (patch)
treea3993005aa5d1f0b868a3c272e4cec3c3b38ea03
parenta1bb1663fd7682effa65665509b72eb834eb3516 (diff)
downloadaports-61ff788630422f3a99da03034c34e0a5d0c24910.tar.bz2
aports-61ff788630422f3a99da03034c34e0a5d0c24910.tar.xz
testing/heirloom-mailx: new aport
heirloom-mailx is a clone of System V "mailx", based on Berkeley Mail 8.1. It has been enhanced to provide all the command line options required by POSIX, as well as several other features: * support for MIME, S/MIME, and attachments * support for SMTP(S), POP3(S), and IMAP(S) * support for maildir-format email archives ... and much more. This is updated from CVS to get current OpenSSL compat. NSS could be used instead of OpenSSL. Some security fixes from Florian Weimer are included - see http://seclists.org/oss-sec/2014/q4/1066 krb5 is used for IMAP authentication over GSS; our libgss doesn't work (and might not be OK to link with openssl?) and using libgssglue will probably require some patching of the makefile.
-rw-r--r--testing/heirloom-mailx/0001-outof-Introduce-expandaddr-flag.patch65
-rw-r--r--testing/heirloom-mailx/0002-unpack-Disable-option-processing-for-email-addresses.patch75
-rw-r--r--testing/heirloom-mailx/0003-fio_c-Unconditionally-require-wordexp-support.patch109
-rw-r--r--testing/heirloom-mailx/0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch26
-rw-r--r--testing/heirloom-mailx/12.4-to-12.5pre.patch1001
-rw-r--r--testing/heirloom-mailx/APKBUILD66
-rw-r--r--testing/heirloom-mailx/makevars.patch33
7 files changed, 1375 insertions, 0 deletions
diff --git a/testing/heirloom-mailx/0001-outof-Introduce-expandaddr-flag.patch b/testing/heirloom-mailx/0001-outof-Introduce-expandaddr-flag.patch
new file mode 100644
index 000000000..c56e8a79a
--- /dev/null
+++ b/testing/heirloom-mailx/0001-outof-Introduce-expandaddr-flag.patch
@@ -0,0 +1,65 @@
+>From 9984ae5cb0ea0d61df1612b06952a61323c083d9 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer () redhat com>
+Date: Mon, 17 Nov 2014 11:13:38 +0100
+Subject: [PATCH 1/4] outof: Introduce expandaddr flag
+
+Document that address expansion is disabled unless the expandaddr
+binary option is set.
+
+This has been assigned CVE-2014-7844 for BSD mailx, but it is not
+a vulnerability in Heirloom mailx because this feature was documented.
+---
+ mailx.1 | 14 ++++++++++++++
+ names.c | 3 +++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/mailx.1 b/mailx.1
+index 70a7859..22a171b 100644
+--- a/mailx.1
++++ b/mailx.1
+@@ -656,6 +656,14 @@ but any reply returned to the machine
+ will have the system wide alias expanded
+ as all mail goes through sendmail.
+ .SS "Recipient address specifications"
++If the
++.I expandaddr
++option is not set (the default), recipient addresses must be names of
++local mailboxes or Internet mail addresses.
++.PP
++If the
++.I expandaddr
++option is set, the following rules apply:
+ When an address is used to name a recipient
+ (in any of To, Cc, or Bcc),
+ names of local mail folders
+@@ -2391,6 +2399,12 @@ and exits immediately.
+ If this option is set,
+ \fImailx\fR starts even with an empty mailbox.
+ .TP
++.B expandaddr
++Causes
++.I mailx
++to expand message recipient addresses, as explained in the section,
++Recipient address specifications.
++.TP
+ .B flipr
+ Exchanges the
+ .I Respond
+diff --git a/names.c b/names.c
+index 66e976b..c69560f 100644
+--- a/names.c
++++ b/names.c
+@@ -268,6 +268,9 @@ outof(struct name *names, FILE *fo, struct header *hp)
+ FILE *fout, *fin;
+ int ispipe;
+
++ if (value("expandaddr") == NULL)
++ return names;
++
+ top = names;
+ np = names;
+ time(&now);
+--
+1.9.3
+
+
diff --git a/testing/heirloom-mailx/0002-unpack-Disable-option-processing-for-email-addresses.patch b/testing/heirloom-mailx/0002-unpack-Disable-option-processing-for-email-addresses.patch
new file mode 100644
index 000000000..9baf6088a
--- /dev/null
+++ b/testing/heirloom-mailx/0002-unpack-Disable-option-processing-for-email-addresses.patch
@@ -0,0 +1,75 @@
+>From e34e2ac67b80497080ebecccec40c3b61456167d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer () redhat com>
+Date: Mon, 17 Nov 2014 11:14:06 +0100
+Subject: [PATCH 2/4] unpack: Disable option processing for email addresses
+ when calling sendmail
+
+---
+ extern.h | 2 +-
+ names.c | 8 ++++++--
+ sendout.c | 2 +-
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/extern.h b/extern.h
+index 6b85ba0..8873fe8 100644
+--- a/extern.h
++++ b/extern.h
+@@ -396,7 +396,7 @@ struct name *outof(struct name *names, FILE *fo, struct header *hp);
+ int is_fileaddr(char *name);
+ struct name *usermap(struct name *names);
+ struct name *cat(struct name *n1, struct name *n2);
+-char **unpack(struct name *np);
++char **unpack(struct name *smopts, struct name *np);
+ struct name *elide(struct name *names);
+ int count(struct name *np);
+ struct name *delete_alternates(struct name *np);
+diff --git a/names.c b/names.c
+index c69560f..45bbaed 100644
+--- a/names.c
++++ b/names.c
+@@ -549,7 +549,7 @@ cat(struct name *n1, struct name *n2)
+ * Return an error if the name list won't fit.
+ */
+ char **
+-unpack(struct name *np)
++unpack(struct name *smopts, struct name *np)
+ {
+ char **ap, **top;
+ struct name *n;
+@@ -564,7 +564,7 @@ unpack(struct name *np)
+ * the terminating 0 pointer. Additional spots may be needed
+ * to pass along -f to the host mailer.
+ */
+- extra = 2;
++ extra = 3 + count(smopts);
+ extra++;
+ metoo = value("metoo") != NULL;
+ if (metoo)
+@@ -581,6 +581,10 @@ unpack(struct name *np)
+ *ap++ = "-m";
+ if (verbose)
+ *ap++ = "-v";
++ for (; smopts != NULL; smopts = smopts->n_flink)
++ if ((smopts->n_type & GDEL) == 0)
++ *ap++ = smopts->n_name;
++ *ap++ = "--";
+ for (; n != NULL; n = n->n_flink)
+ if ((n->n_type & GDEL) == 0)
+ *ap++ = n->n_name;
+diff --git a/sendout.c b/sendout.c
+index 7b7f2eb..c52f15d 100644
+--- a/sendout.c
++++ b/sendout.c
+@@ -835,7 +835,7 @@ start_mta(struct name *to, struct name *mailargs, FILE *input,
+ #endif /* HAVE_SOCKETS */
+
+ if ((smtp = value("smtp")) == NULL) {
+- args = unpack(cat(mailargs, to));
++ args = unpack(mailargs, to);
+ if (debug || value("debug")) {
+ printf(catgets(catd, CATSET, 181,
+ "Sendmail arguments:"));
+--
+1.9.3
+
+
diff --git a/testing/heirloom-mailx/0003-fio_c-Unconditionally-require-wordexp-support.patch b/testing/heirloom-mailx/0003-fio_c-Unconditionally-require-wordexp-support.patch
new file mode 100644
index 000000000..05fe00f2c
--- /dev/null
+++ b/testing/heirloom-mailx/0003-fio_c-Unconditionally-require-wordexp-support.patch
@@ -0,0 +1,109 @@
+>From 2bae8ecf04ec2ba6bb9f0af5b80485dd0edb427d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer () redhat com>
+Date: Mon, 17 Nov 2014 12:48:25 +0100
+Subject: [PATCH 3/4] fio.c: Unconditionally require wordexp support
+
+---
+ fio.c | 67 +++++--------------------------------------------------------------
+ 1 file changed, 5 insertions(+), 62 deletions(-)
+
+diff --git a/fio.c b/fio.c
+index 65e8f10..1529236 100644
+--- a/fio.c
++++ b/fio.c
+@@ -43,12 +43,15 @@ static char sccsid[] = "@(#)fio.c 2.76 (gritter) 9/16/09";
+ #endif /* not lint */
+
+ #include "rcv.h"
++
++#ifndef HAVE_WORDEXP
++#error wordexp support is required
++#endif
++
+ #include <sys/stat.h>
+ #include <sys/file.h>
+ #include <sys/wait.h>
+-#ifdef HAVE_WORDEXP
+ #include <wordexp.h>
+-#endif /* HAVE_WORDEXP */
+ #include <unistd.h>
+
+ #if defined (USE_NSS)
+@@ -481,7 +484,6 @@ next:
+ static char *
+ globname(char *name)
+ {
+-#ifdef HAVE_WORDEXP
+ wordexp_t we;
+ char *cp;
+ sigset_t nset;
+@@ -527,65 +529,6 @@ globname(char *name)
+ }
+ wordfree(&we);
+ return cp;
+-#else /* !HAVE_WORDEXP */
+- char xname[PATHSIZE];
+- char cmdbuf[PATHSIZE]; /* also used for file names */
+- int pid, l;
+- char *cp, *shell;
+- int pivec[2];
+- extern int wait_status;
+- struct stat sbuf;
+-
+- if (pipe(pivec) < 0) {
+- perror("pipe");
+- return name;
+- }
+- snprintf(cmdbuf, sizeof cmdbuf, "echo %s", name);
+- if ((shell = value("SHELL")) == NULL)
+- shell = SHELL;
+- pid = start_command(shell, 0, -1, pivec[1], "-c", cmdbuf, NULL);
+- if (pid < 0) {
+- close(pivec[0]);
+- close(pivec[1]);
+- return NULL;
+- }
+- close(pivec[1]);
+-again:
+- l = read(pivec[0], xname, sizeof xname);
+- if (l < 0) {
+- if (errno == EINTR)
+- goto again;
+- perror("read");
+- close(pivec[0]);
+- return NULL;
+- }
+- close(pivec[0]);
+- if (wait_child(pid) < 0 && WTERMSIG(wait_status) != SIGPIPE) {
+- fprintf(stderr, catgets(catd, CATSET, 81,
+- "\"%s\": Expansion failed.\n"), name);
+- return NULL;
+- }
+- if (l == 0) {
+- fprintf(stderr, catgets(catd, CATSET, 82,
+- "\"%s\": No match.\n"), name);
+- return NULL;
+- }
+- if (l == sizeof xname) {
+- fprintf(stderr, catgets(catd, CATSET, 83,
+- "\"%s\": Expansion buffer overflow.\n"), name);
+- return NULL;
+- }
+- xname[l] = 0;
+- for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
+- ;
+- cp[1] = '\0';
+- if (strchr(xname, ' ') && stat(xname, &sbuf) < 0) {
+- fprintf(stderr, catgets(catd, CATSET, 84,
+- "\"%s\": Ambiguous.\n"), name);
+- return NULL;
+- }
+- return savestr(xname);
+-#endif /* !HAVE_WORDEXP */
+ }
+
+ /*
+--
+1.9.3
+
+
diff --git a/testing/heirloom-mailx/0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch b/testing/heirloom-mailx/0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch
new file mode 100644
index 000000000..173378f36
--- /dev/null
+++ b/testing/heirloom-mailx/0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch
@@ -0,0 +1,26 @@
+>From 73fefa0c1ac70043ec84f2d8b8f9f683213f168d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer () redhat com>
+Date: Mon, 17 Nov 2014 13:11:32 +0100
+Subject: [PATCH 4/4] globname: Invoke wordexp with WRDE_NOCMD (CVE-2004-2771)
+
+---
+ fio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fio.c b/fio.c
+index 1529236..774a204 100644
+--- a/fio.c
++++ b/fio.c
+@@ -497,7 +497,7 @@ globname(char *name)
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &nset, NULL);
+- i = wordexp(name, &we, 0);
++ i = wordexp(name, &we, WRDE_NOCMD);
+ sigprocmask(SIG_UNBLOCK, &nset, NULL);
+ switch (i) {
+ case 0:
+--
+1.9.3
+
+
diff --git a/testing/heirloom-mailx/12.4-to-12.5pre.patch b/testing/heirloom-mailx/12.4-to-12.5pre.patch
new file mode 100644
index 000000000..9fd5c8fab
--- /dev/null
+++ b/testing/heirloom-mailx/12.4-to-12.5pre.patch
@@ -0,0 +1,1001 @@
+--- mailx-12.4/ChangeLog
++++ nail/ChangeLog
+@@ -1,3 +1,38 @@
++[12.5] as of 7/5/10
++* The undocumented contenttype-cntrl option works again (patch by
++ Laurent Parenteau).
++
++[12.5] as of 6/20/10
++* Fixed a message corruption that occurred when the "inc" command was used
++ with a mbox format mailbox after encrypted messages had been viewed
++ (reported by Martin Neitzel).
++* Fixed a condition that caused mailx to hang when looking at a message,
++ copying that message, and issuing a "z" command evaluating an uncached
++ portion of an IMAP folder.
++* Make it compile with OpenSSL 1.0.0-beta2 (patch by Bernhard Rosenkränzer).
++* When executing an "account" command, ensure that the values of the "hold",
++ "keepsave", "append", and "emptybox" variables remain those of the previous
++ account for all outstanding operations on that account (bug reported by
++ Jeff Woodall).
++* Support Gmail IMAP semantics of "delete" turning into "archive". Previously,
++ when mailx was setting the "\Deleted" flag on a message, it did not set any
++ other flags. This caused mails that had been read and then deleted to appear
++ as unread in Gmail's "All Mail". Now, flags besides "\Deleted" are also set,
++ so that they are kept in the archived copy (reported by Jeremy O'Brien).
++* For RFC 2047 MIME "encoded-word" parts in headers, assume that the end of
++ each word resets the conversion state (Yedidyah Bar-David).
++* When the ORGANIZATION variable has an empty value, do not generate an
++ "Organization:" header field. Previously, this condition resulted in
++ mailx refusing to send mail (Thomas E. Kammeyer).
++* When classifying messages with the junk filter, when selecting the most
++ representative tokens, prefer non-junk tokens over junk tokens if both
++ have the same (reversed) probability, in order to avoid false positives.
++* When calculating the probabilities of tokens that have occurred only in
++ good messages or only in junk messages so far, and these tokens occurred
++ less than ten times, give them slightly less than the minimum/maximum.
++* Fixed "unignore" and similar commands; they did not work at all so far
++ (http://www.freebsd.org/cgi/query-pr.cgi?pr=146280).
++
+ [12.4] released 7/29/08
+ * With the "-E" command line option or if the "skipemptybody" variable is
+ set, outgoing messages that contain no text in their first or only part
+--- mailx-12.4/cmd2.c
++++ nail/cmd2.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)cmd2.c 2.46 (gritter) 3/4/06";
++static char sccsid[] = "@(#)cmd2.c 2.47 (gritter) 5/9/10";
+ #endif
+ #endif /* not lint */
+
+@@ -803,16 +803,17 @@
+ int h = hash(name);
+
+ for (ip = tab->i_head[h]; ip; ip = ip->i_link) {
+- if (asccasecmp(ip->i_field, name)) {
++ if (asccasecmp(ip->i_field, name) == 0) {
+ free(ip->i_field);
+ if (iq != NULL)
+ iq->i_link = ip->i_link;
+ else
+- tab->i_head[h] = NULL;
++ tab->i_head[h] = ip->i_link;
+ free(ip);
+ tab->i_count--;
+ break;
+ }
++ iq = ip;
+ }
+ }
+
+--- mailx-12.4/cmd3.c
++++ nail/cmd3.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)cmd3.c 2.86 (gritter) 10/1/07";
++static char sccsid[] = "@(#)cmd3.c 2.87 (gritter) 10/1/08";
+ #endif
+ #endif /* not lint */
+
+@@ -1311,7 +1311,7 @@
+ char **args = (char **)v;
+ struct oldaccount *a;
+ char *cp;
+- int i, mc;
++ int i, mc, oqf, nqf;
+ FILE *fp = stdout;
+
+ if (args[0] == NULL) {
+@@ -1345,6 +1345,7 @@
+ return define1(args[0], 1);
+ }
+ strncpy(mboxname, expand("&"), sizeof mboxname)[sizeof mboxname-1]='\0';
++ oqf = savequitflags();
+ if ((a = get_oldaccount(args[0])) == NULL) {
+ if (args[1]) {
+ a = scalloc(1, sizeof *a);
+@@ -1368,8 +1369,13 @@
+ unset_allow_undefined = 1;
+ set(a->ac_vars);
+ unset_allow_undefined = 0;
+- setf: if (!starting)
+- return file1("%");
++ setf: if (!starting) {
++ nqf = savequitflags();
++ restorequitflags(oqf);
++ i = file1("%");
++ restorequitflags(nqf);
++ return i;
++ }
+ }
+ return 0;
+ }
+--- mailx-12.4/extern.h
++++ nail/extern.h
+@@ -35,7 +35,7 @@
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+- * Sccsid @(#)extern.h 2.161 (gritter) 10/1/07
++ * Sccsid @(#)extern.h 2.162 (gritter) 10/1/08
+ */
+
+ /* aux.c */
+@@ -446,6 +446,8 @@
+ void quit(void);
+ int holdbits(void);
+ enum okay makembox(void);
++int savequitflags(void);
++void restorequitflags(int);
+ /* send.c */
+ char *foldergets(char **s, size_t *size, size_t *count, size_t *llen,
+ FILE *stream);
+@@ -513,12 +515,12 @@
+ void demail(void);
+ char *username(void);
+ /* vars.c */
+-void assign(char *name, char *value);
++void assign(const char *name, const char *value);
+ char *vcopy(const char *str);
+ char *value(const char *name);
+ struct grouphead *findgroup(char *name);
+ void printgroup(char *name);
+ int hash(const char *name);
+-int unset_internal(char *name);
++int unset_internal(const char *name);
+ void remove_group(const char *name);
+ /* version.c */
+--- mailx-12.4/fio.c
++++ nail/fio.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)fio.c 2.73 (gritter) 1/7/08";
++static char sccsid[] = "@(#)fio.c 2.76 (gritter) 9/16/09";
+ #endif
+ #endif /* not lint */
+
+@@ -108,6 +108,7 @@
+ memset(&this, 0, sizeof this);
+ this.m_flag = MUSED|MNEW|MNEWEST;
+ filesize = mailsize - offset;
++ offset = ftell(mb.mb_otf);
+ for (;;) {
+ if (fgetline(&linebuf, &linesize, &filesize, &count, ibuf, 0)
+ == NULL) {
+@@ -1050,7 +1051,8 @@
+ NI_NUMERICHOST) != 0)
+ strcpy(hbuf, "unknown host");
+ fprintf(stderr, catgets(catd, CATSET, 192,
+- "Connecting to %s . . ."), hbuf);
++ "Connecting to %s:%s . . ."),
++ hbuf, portstr);
+ }
+ if ((sockfd = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol)) >= 0) {
+@@ -1068,26 +1070,25 @@
+ freeaddrinfo(res0);
+ #else /* !HAVE_IPv6_FUNCS */
+ if (port == 0) {
+- if ((ep = getservbyname((char *)portstr, "tcp")) == NULL) {
+- if (equal(portstr, "smtp"))
+- port = htons(25);
+- else if (equal(portstr, "smtps"))
+- port = htons(465);
+- else if (equal(portstr, "imap"))
+- port = htons(143);
+- else if (equal(portstr, "imaps"))
+- port = htons(993);
+- else if (equal(portstr, "pop3"))
+- port = htons(110);
+- else if (equal(portstr, "pop3s"))
+- port = htons(995);
+- else {
+- fprintf(stderr, catgets(catd, CATSET, 251,
+- "Unknown service: %s\n"), portstr);
+- return STOP;
+- }
+- } else
++ if (equal(portstr, "smtp"))
++ port = htons(25);
++ else if (equal(portstr, "smtps"))
++ port = htons(465);
++ else if (equal(portstr, "imap"))
++ port = htons(143);
++ else if (equal(portstr, "imaps"))
++ port = htons(993);
++ else if (equal(portstr, "pop3"))
++ port = htons(110);
++ else if (equal(portstr, "pop3s"))
++ port = htons(995);
++ else if ((ep = getservbyname((char *)portstr, "tcp")) != NULL)
+ port = ep->s_port;
++ else {
++ fprintf(stderr, catgets(catd, CATSET, 251,
++ "Unknown service: %s\n"), portstr);
++ return STOP;
++ }
+ } else
+ port = htons(port);
+ if (verbose)
+@@ -1109,7 +1110,8 @@
+ memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
+ if (verbose)
+ fprintf(stderr, catgets(catd, CATSET, 192,
+- "Connecting to %s . . ."), inet_ntoa(**pptr));
++ "Connecting to %s:%d . . ."),
++ inet_ntoa(**pptr), ntohs(port));
+ if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof servaddr)
+ != 0) {
+ perror(catgets(catd, CATSET, 254, "could not connect"));
+--- mailx-12.4/imap.c
++++ nail/imap.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)imap.c 1.219 (gritter) 1/6/08";
++static char sccsid[] = "@(#)imap.c 1.222 (gritter) 3/13/09";
+ #endif
+ #endif /* not lint */
+
+@@ -1821,57 +1821,62 @@
+ * reading their results.
+ */
+ needstat = stored > 0 && stored % 800 == 0;
++ /*
++ * Even if this message has been deleted, continue
++ * to set further flags. This is necessary to support
++ * Gmail semantics, where "delete" actually means
++ * "archive", and the flags are applied to the copy
++ * in "All Mail".
++ */
++ if ((m->m_flag&(MREAD|MSTATUS)) == (MREAD|MSTATUS)) {
++ imap_store(mp, m, m-message+1,
++ '+', "\\Seen", needstat);
++ stored++;
++ }
++ if (m->m_flag & MFLAG) {
++ imap_store(mp, m, m-message+1,
++ '+', "\\Flagged", needstat);
++ stored++;
++ }
++ if (m->m_flag & MUNFLAG) {
++ imap_store(mp, m, m-message+1,
++ '-', "\\Flagged", needstat);
++ stored++;
++ }
++ if (m->m_flag & MANSWER) {
++ imap_store(mp, m, m-message+1,
++ '+', "\\Answered", needstat);
++ stored++;
++ }
++ if (m->m_flag & MUNANSWER) {
++ imap_store(mp, m, m-message+1,
++ '-', "\\Answered", needstat);
++ stored++;
++ }
++ if (m->m_flag & MDRAFT) {
++ imap_store(mp, m, m-message+1,
++ '+', "\\Draft", needstat);
++ stored++;
++ }
++ if (m->m_flag & MUNDRAFT) {
++ imap_store(mp, m, m-message+1,
++ '-', "\\Draft", needstat);
++ stored++;
++ }
+ if (dodel) {
+ imap_delete(mp, m-message+1, m, needstat);
+ stored++;
+ gotcha++;
+- } else {
+- if ((m->m_flag&(MREAD|MSTATUS)) == (MREAD|MSTATUS)) {
+- imap_store(mp, m, m-message+1,
+- '+', "\\Seen", needstat);
+- stored++;
+- }
+- if (m->m_flag & MFLAG) {
+- imap_store(mp, m, m-message+1,
+- '+', "\\Flagged", needstat);
+- stored++;
+- }
+- if (m->m_flag & MUNFLAG) {
+- imap_store(mp, m, m-message+1,
+- '-', "\\Flagged", needstat);
+- stored++;
+- }
+- if (m->m_flag & MANSWER) {
+- imap_store(mp, m, m-message+1,
+- '+', "\\Answered", needstat);
+- stored++;
+- }
+- if (m->m_flag & MUNANSWER) {
+- imap_store(mp, m, m-message+1,
+- '-', "\\Answered", needstat);
+- stored++;
+- }
+- if (m->m_flag & MDRAFT) {
+- imap_store(mp, m, m-message+1,
+- '+', "\\Draft", needstat);
+- stored++;
+- }
+- if (m->m_flag & MUNDRAFT) {
+- imap_store(mp, m, m-message+1,
+- '-', "\\Draft", needstat);
+- stored++;
+- }
+- if (mp->mb_type != MB_CACHE ||
+- !edit && (!(m->m_flag&(MBOXED|MSAVED|MDELETED))
+- || (m->m_flag &
+- (MBOXED|MPRESERVE|MTOUCH)) ==
+- (MPRESERVE|MTOUCH)) ||
+- edit && !(m->m_flag & MDELETED))
+- held++;
+- if (m->m_flag & MNEW) {
+- m->m_flag &= ~MNEW;
+- m->m_flag |= MSTATUS;
+- }
++ } else if (mp->mb_type != MB_CACHE ||
++ !edit && (!(m->m_flag&(MBOXED|MSAVED|MDELETED))
++ || (m->m_flag &
++ (MBOXED|MPRESERVE|MTOUCH)) ==
++ (MPRESERVE|MTOUCH)) ||
++ edit && !(m->m_flag & MDELETED))
++ held++;
++ if (m->m_flag & MNEW) {
++ m->m_flag &= ~MNEW;
++ m->m_flag |= MSTATUS;
+ }
+ }
+ bypass: if (readstat != NULL)
+@@ -2571,6 +2576,7 @@
+ const char *qname;
+ enum okay ok = STOP;
+ int twice = 0;
++ int stored = 0;
+ FILE *queuefp = NULL;
+
+ if (mp->mb_type == MB_CACHE) {
+@@ -2629,20 +2635,38 @@
+ * ... and reset the flag to its initial value so that
+ * the 'exit' command still leaves the message unread.
+ */
+-out: if ((m->m_flag&(MREAD|MSTATUS)) == (MREAD|MSTATUS))
++out: if ((m->m_flag&(MREAD|MSTATUS)) == (MREAD|MSTATUS)) {
+ imap_store(mp, m, n, '-', "\\Seen", 0);
+- if (m->m_flag&MFLAG)
++ stored++;
++ }
++ if (m->m_flag&MFLAG) {
+ imap_store(mp, m, n, '-', "\\Flagged", 0);
+- if (m->m_flag&MUNFLAG)
++ stored++;
++ }
++ if (m->m_flag&MUNFLAG) {
+ imap_store(mp, m, n, '+', "\\Flagged", 0);
+- if (m->m_flag&MANSWER)
++ stored++;
++ }
++ if (m->m_flag&MANSWER) {
+ imap_store(mp, m, n, '-', "\\Answered", 0);
+- if (m->m_flag&MUNANSWER)
++ stored++;
++ }
++ if (m->m_flag&MUNANSWER) {
+ imap_store(mp, m, n, '+', "\\Answered", 0);
+- if (m->m_flag&MDRAFT)
++ stored++;
++ }
++ if (m->m_flag&MDRAFT) {
+ imap_store(mp, m, n, '-', "\\Draft", 0);
+- if (m->m_flag&MUNDRAFT)
++ stored++;
++ }
++ if (m->m_flag&MUNDRAFT) {
+ imap_store(mp, m, n, '+', "\\Draft", 0);
++ stored++;
++ }
++ if (stored) {
++ mp->mb_active |= MB_COMD;
++ imap_finish(mp);
++ }
+ return ok;
+ }
+
+--- mailx-12.4/junk.c
++++ nail/junk.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)junk.c 1.73 (gritter) 3/4/06";
++static char sccsid[] = "@(#)junk.c 1.75 (gritter) 9/14/08";
+ #endif
+ #endif /* not lint */
+
+@@ -920,6 +920,10 @@
+ smin(1.0, nbad ? (float)b/nbad : 0.0));
+ p = smin(TOP, p);
+ p = smax(BOT, p);
++ if (p == TOP && b <= 10 && g == 0)
++ p -= BOT;
++ else if (p == BOT && g <= 10 && b == 0)
++ p += BOT;
+ } else if (g == 0 && b == 0)
+ p = DFL;
+ else
+@@ -1095,13 +1099,20 @@
+ if (h1 == best[i].hash1 && h2 == best[i].hash2)
+ break;
+ /*
+- * This selection prefers words from the end of the
+- * header and from the start of the body. It does
+- * probably not matter much at all, but gives at
+- * least the most interesting verbose output.
++ * For equal distance, this selection prefers
++ * words with a low probability, since a false
++ * negative is better than a false positive,
++ * and since experience has shown that false
++ * positives are more likely otherwise. Then,
++ * words from the end of the header and from
++ * the start of the body are preferred. This
++ * gives the most interesting verbose output.
+ */
+- if (d > best[i].dist || best[i].loc == HEADER &&
+- d >= best[i].dist) {
++ if (d > best[i].dist ||
++ d == best[i].dist &&
++ p < best[i].prob ||
++ best[i].loc == HEADER &&
++ d == best[i].dist) {
+ for (j = BEST-2; j >= i; j--)
+ best[j+1] = best[j];
+ best[i].dist = d;
+--- mailx-12.4/list.c
++++ nail/list.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)list.c 2.61 (gritter) 01/07/07";
++static char sccsid[] = "@(#)list.c 2.62 (gritter) 12/11/08";
+ #endif
+ #endif /* not lint */
+
+@@ -438,7 +438,7 @@
+ if (!inhook)
+ printf(tback ?
+ "No previously marked messages.\n" :
+- "No messages satify (criteria).\n");
++ "No messages satisfy (criteria).\n");
+ markall_ret(-1)
+ }
+ }
+--- mailx-12.4/mailx.1
++++ nail/mailx.1
+@@ -34,9 +34,9 @@
+ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ .\" SUCH DAMAGE.
+ .\"
+-.\" Sccsid: @(#)mailx.1 2.326 (gritter) 10/1/07
++.\" Sccsid: @(#)mailx.1 2.329 (gritter) 10/9/10
+ .\"
+-.TH MAILX 1 "10/1/07" "Heirloom mailx 12.4" "User Commands"
++.TH MAILX 1 "10/9/10" "Heirloom mailx 12.5" "User Commands"
+ .SH NAME
+ mailx \- send and receive Internet mail
+ .SH SYNOPSIS
+@@ -418,6 +418,21 @@
+ .I address
+ All messages from
+ .IR address .
++By default, this is a case-sensitive search
++for the complete email address.
++If the
++.I allnet
++variable is set,
++only the local part of the addresses is evaluated for the comparison.
++Otherwise if the
++.I showname
++variable is set,
++a case-sensitive search for the complete real name
++of a sender is performed.
++The IMAP-style
++.BI (from\ address)
++expression can be used instead
++if substring matches are desired.
+ .TP
+ .BI ( criterion )
+ All messages that satisfy the given IMAP-style SEARCH
+@@ -3766,7 +3781,7 @@
+ .sp
+ .fi
+ which might cause
+-.N mailx
++.B mailx
+ to respond with, for example:
+ .nf
+ .sp
+--- mailx-12.4/makeconfig
++++ nail/makeconfig
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+
+ #
+-# Sccsid @(#)makeconfig 1.43 (gritter) 4/14/07
++# Sccsid @(#)makeconfig 1.44 (gritter) 5/26/09
+ #
+
+ tmp=___build$$
+@@ -393,6 +393,25 @@
+ !
+ fi
+
++if test x$have_openssl = xyes
++then
++ compile_check stack_of 'for STACK_OF()' '#define HAVE_STACK_OF' <<\!
++#include <openssl/ssl.h>
++#include <openssl/err.h>
++#include <openssl/x509v3.h>
++#include <openssl/x509.h>
++#include <openssl/rand.h>
++
++int main(void)
++{
++ STACK_OF(GENERAL_NAME) *gens = NULL;
++ printf("%p", gens); /* to make it used */
++ SSLv23_client_method();
++ PEM_read_PrivateKey(0, 0, 0, 0);
++ return 0;
++}
++!
++fi
+
+ cat >$tmp2.c <<\!
+ #include <gssapi/gssapi.h>
+--- mailx-12.4/mime.c
++++ nail/mime.c
+@@ -40,7 +40,7 @@
+ #ifdef DOSCCS
+ static char copyright[]
+ = "@(#) Copyright (c) 2000, 2002 Gunnar Ritter. All rights reserved.\n";
+-static char sccsid[] = "@(#)mime.c 2.69 (gritter) 6/29/08";
++static char sccsid[] = "@(#)mime.c 2.71 (gritter) 7/5/10";
+ #endif /* DOSCCS */
+ #endif /* not lint */
+
+@@ -788,8 +788,7 @@
+
+ *isclean = mime_isclean(fp);
+ if (*isclean & MIME_HASNUL ||
+- *contenttype && ascncasecmp(*contenttype, "text/", 5) ||
+- *contenttype == NULL && *isclean & MIME_CTRLCHAR) {
++ *contenttype && ascncasecmp(*contenttype, "text/", 5)) {
+ convert = CONV_TOB64;
+ if (*contenttype == NULL ||
+ ascncasecmp(*contenttype, "text/", 5) == 0)
+@@ -809,6 +808,7 @@
+ *contenttype = "application/octet-stream";
+ *charset = NULL;
+ } if (*isclean & MIME_CTRLCHAR) {
++ convert = CONV_TOB64;
+ /*
+ * RFC 2046 forbids control characters other than
+ * ^I or ^L in text/plain bodies. However, some
+@@ -1048,12 +1048,22 @@
+ uptr = nptr + outleft;
+ iptr = cout.s;
+ if (iconv_ft(fhicd, &iptr, &inleft,
+- &nptr, &outleft) != 0 &&
++ &nptr, &outleft) == (size_t)-1 &&
+ errno == E2BIG) {
+ iconv(fhicd, NULL, NULL, NULL, NULL);
+ mime_fromhdr_inc(inleft);
+ goto again;
+ }
++ /*
++ * For state-dependent encodings,
++ * reset the state here, assuming
++ * that states are restricted to
++ * single encoded-word parts.
++ */
++ while (iconv(fhicd, NULL, NULL,
++ &nptr, &outleft) == (size_t)-1 &&
++ errno == E2BIG)
++ mime_fromhdr_inc(16);
+ out->l += uptr - mptr - outleft;
+ q += uptr - mptr - outleft;
+ } else {
+@@ -1295,7 +1305,7 @@
+ isz = len;
+ op = cbuf;
+ osz = cbufsz;
+- if (iconv(iconvd, &ip, &isz, &op, &osz) != 0) {
++ if (iconv(iconvd, &ip, &isz, &op, &osz) == (size_t)-1) {
+ if (errno != E2BIG) {
+ ac_free(cbuf);
+ return 0;
+@@ -1489,7 +1499,8 @@
+ outleft = mptrsz;
+ nptr = mptr;
+ iptr = ptr;
+- if (iconv_ft(iconvd, &iptr, &inleft, &nptr, &outleft) != 0 &&
++ if (iconv_ft(iconvd, &iptr, &inleft, &nptr, &outleft) ==
++ (size_t)-1 &&
+ errno == E2BIG) {
+ iconv(iconvd, NULL, NULL, NULL, NULL);
+ ac_free(mptr);
+--- mailx-12.4/nail.rc
++++ nail/nail.rc
+@@ -4,7 +4,7 @@
+ # This file is not overwritten when 'make install' is run in
+ # the mailx build process again.
+
+-# Sccsid @(#)nail.rc 2.10 (gritter) 3/4/06
++# Sccsid @(#)nail.rc 2.11 (gritter) 8/2/08
+
+ # Do not forward to mbox by default since this is likely to be
+ # irritating for most users today.
+@@ -54,6 +54,9 @@
+
+ # If threaded mode is activated, automatically collapse thread.
+ set autocollapse
++
++# Mark messages that have been answered.
++set markanswered
+
+ # Hide some header fields which are uninteresting for most human readers.
+ ignore received in-reply-to message-id references
+--- mailx-12.4/openssl.c
++++ nail/openssl.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)openssl.c 1.25 (gritter) 8/4/07";
++static char sccsid[] = "@(#)openssl.c 1.26 (gritter) 5/26/09";
+ #endif
+ #endif /* not lint */
+
+@@ -101,12 +101,17 @@
+ static int ssl_rand_init(void);
+ static void ssl_init(void);
+ static int ssl_verify_cb(int success, X509_STORE_CTX *store);
+-static SSL_METHOD *ssl_select_method(const char *uhp);
++static const SSL_METHOD *ssl_select_method(const char *uhp);
+ static void ssl_load_verifications(struct sock *sp);
+ static void ssl_certificate(struct sock *sp, const char *uhp);
+ static enum okay ssl_check_host(const char *server, struct sock *sp);
++#ifdef HAVE_STACK_OF
++static int smime_verify(struct message *m, int n, STACK_OF(X509) *chain,
++ X509_STORE *store);
++#else
+ static int smime_verify(struct message *m, int n, STACK *chain,
+ X509_STORE *store);
++#endif
+ static EVP_CIPHER *smime_cipher(const char *name);
+ static int ssl_password_cb(char *buf, int size, int rwflag, void *userdata);
+ static FILE *smime_sign_cert(const char *xname, const char *xname2, int warn);
+@@ -203,10 +208,10 @@
+ return 1;
+ }
+
+-static SSL_METHOD *
++static const SSL_METHOD *
+ ssl_select_method(const char *uhp)
+ {
+- SSL_METHOD *method;
++ const SSL_METHOD *method;
+ char *cp;
+
+ cp = ssl_method_string(uhp);
+@@ -308,7 +313,11 @@
+ X509 *cert;
+ X509_NAME *subj;
+ char data[256];
++#ifdef HAVE_STACK_OF
++ STACK_OF(GENERAL_NAME) *gens;
++#else
+ /*GENERAL_NAMES*/STACK *gens;
++#endif
+ GENERAL_NAME *gen;
+ int i;
+
+@@ -357,7 +366,8 @@
+
+ ssl_init();
+ ssl_set_vrfy_level(uhp);
+- if ((sp->s_ctx = SSL_CTX_new(ssl_select_method(uhp))) == NULL) {
++ if ((sp->s_ctx =
++ SSL_CTX_new((SSL_METHOD *)ssl_select_method(uhp))) == NULL) {
+ ssl_gen_err(catgets(catd, CATSET, 261, "SSL_CTX_new() failed"));
+ return STOP;
+ }
+@@ -496,7 +506,11 @@
+ }
+
+ static int
++#ifdef HAVE_STACK_OF
++smime_verify(struct message *m, int n, STACK_OF(X509) *chain, X509_STORE *store)
++#else
+ smime_verify(struct message *m, int n, STACK *chain, X509_STORE *store)
++#endif
+ {
+ struct message *x;
+ char *cp, *sender, *to, *cc, *cnttype;
+@@ -505,7 +519,12 @@
+ off_t size;
+ BIO *fb, *pb;
+ PKCS7 *pkcs7;
++#ifdef HAVE_STACK_OF
++ STACK_OF(X509) *certs;
++ STACK_OF(GENERAL_NAME) *gens;
++#else
+ STACK *certs, *gens;
++#endif
+ X509 *cert;
+ X509_NAME *subj;
+ char data[LINESIZE];
+@@ -614,7 +633,11 @@
+ {
+ int *msgvec = vp, *ip;
+ int ec = 0;
++#ifdef HAVE_STACK_OF
++ STACK_OF(X509) *chain = NULL;
++#else
+ STACK *chain = NULL;
++#endif
+ X509_STORE *store;
+ char *ca_dir, *ca_file;
+
+@@ -687,7 +710,11 @@
+ X509 *cert;
+ PKCS7 *pkcs7;
+ BIO *bb, *yb;
++#ifdef HAVE_STACK_OF
++ STACK_OF(X509) *certs;
++#else
+ STACK *certs;
++#endif
+ EVP_CIPHER *cipher;
+
+ certfile = expand((char *)certfile);
+@@ -950,9 +977,14 @@
+ off_t size;
+ BIO *fb, *pb;
+ PKCS7 *pkcs7;
++#ifdef HAVE_STACK_OF
++ STACK_OF(X509) *certs;
++ STACK_OF(X509) *chain = NULL;
++#else
+ STACK *certs;
+- X509 *cert;
+ STACK *chain = NULL;
++#endif
++ X509 *cert;
+ enum okay ok = OKAY;
+
+ message_number = n;
+--- mailx-12.4/quit.c
++++ nail/quit.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)quit.c 2.28 (gritter) 3/4/06";
++static char sccsid[] = "@(#)quit.c 2.30 (gritter) 11/11/08";
+ #endif
+ #endif /* not lint */
+
+@@ -584,4 +584,47 @@
+
+ done:
+ relsesigs();
++}
++
++enum quitflags {
++ QUITFLAG_HOLD = 001,
++ QUITFLAG_KEEPSAVE = 002,
++ QUITFLAG_APPEND = 004,
++ QUITFLAG_EMPTYBOX = 010
++};
++
++static const struct quitnames {
++ enum quitflags flag;
++ const char *name;
++} quitnames[] = {
++ { QUITFLAG_HOLD, "hold" },
++ { QUITFLAG_KEEPSAVE, "keepsave" },
++ { QUITFLAG_APPEND, "append" },
++ { QUITFLAG_EMPTYBOX, "emptybox" },
++ { 0, NULL }
++};
++
++int
++savequitflags(void)
++{
++ enum quitflags qf = 0;
++ int i;
++
++ for (i = 0; quitnames[i].name; i++)
++ if (value(quitnames[i].name))
++ qf |= quitnames[i].flag;
++ return qf;
++}
++
++void
++restorequitflags(int qf)
++{
++ int i;
++
++ for (i = 0; quitnames[i].name; i++)
++ if (qf & quitnames[i].flag) {
++ if (value(quitnames[i].name) == NULL)
++ assign(quitnames[i].name, "");
++ } else if (value(quitnames[i].name))
++ unset_internal(quitnames[i].name);
+ }
+--- mailx-12.4/sendout.c
++++ nail/sendout.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)sendout.c 2.99 (gritter) 7/4/08";
++static char sccsid[] = "@(#)sendout.c 2.100 (gritter) 3/1/09";
+ #endif
+ #endif /* not lint */
+
+@@ -1219,8 +1219,9 @@
+ if (putname(addr, w, action, &gotcha, "From:", fo,
+ &fromfield))
+ return 1;
+- if ((addr = hp->h_organization) != NULL ||
+- (addr = value("ORGANIZATION")) != NULL) {
++ if (((addr = hp->h_organization) != NULL ||
++ (addr = value("ORGANIZATION")) != NULL)
++ && strlen(addr) > 0) {
+ fwrite("Organization: ", sizeof (char), 14, fo);
+ if (mime_write(addr, strlen(addr), fo,
+ action == SEND_TODISP ?
+@@ -1269,7 +1270,8 @@
+ fwrite("Subject: ", sizeof (char), 9, fo);
+ if (ascncasecmp(hp->h_subject, "re: ", 4) == 0) {
+ fwrite("Re: ", sizeof (char), 4, fo);
+- if (mime_write(hp->h_subject + 4,
++ if (strlen(hp->h_subject + 4) > 0 &&
++ mime_write(hp->h_subject + 4,
+ strlen(hp->h_subject + 4),
+ fo, action == SEND_TODISP ?
+ CONV_NONE:CONV_TOHDR,
+--- mailx-12.4/vars.c
++++ nail/vars.c
+@@ -38,7 +38,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)vars.c 2.11 (gritter) 3/4/06";
++static char sccsid[] = "@(#)vars.c 2.12 (gritter) 10/1/08";
+ #endif
+ #endif /* not lint */
+
+@@ -81,7 +81,7 @@
+ * Assign a value to a variable.
+ */
+ void
+-assign(char *name, char *value)
++assign(const char *name, const char *value)
+ {
+ struct var *vp;
+ int h;
+@@ -221,7 +221,7 @@
+ }
+
+ int
+-unset_internal(char *name)
++unset_internal(const char *name)
+ {
+ struct var *vp, *vp2;
+ int h;
+--- mailx-12.4/version.c
++++ nail/version.c
+@@ -1,4 +1,4 @@
+-#define V "12.4"
++#define V "12.5"
+ /*
+ * Heirloom mailx - a mail user agent derived from Berkeley Mail.
+ *
+@@ -39,7 +39,7 @@
+
+ #ifndef lint
+ #ifdef DOSCCS
+-static char sccsid[] = "@(#)version.c 2.386 (gritter) 7/29/08";
++static char sccsid[] = "@(#)version.c 2.404 (gritter) 7/5/10";
+ #endif
+ #endif /* not lint */
+
+@@ -48,7 +48,7 @@
+ * Load this file first to get a "total" Mail version.
+ */
+ /*char *version = "8.1 6/6/93";*/
+-const char *version = V " 7/29/08";
++const char *version = V " 7/5/10";
+ #ifndef lint
+ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
+ #define USED __attribute__ ((used))
+@@ -57,7 +57,7 @@
+ #else
+ #define USED
+ #endif
+-static const char *versionid USED = "@(#)mailx " V " (gritter) 7/29/08";
++static const char *versionid USED = "@(#)mailx " V " (gritter) 7/5/10";
+ #endif /* !lint */
+ /* SLIST */
+ /*
+@@ -65,42 +65,42 @@
+ base64.c:static char sccsid[] = "@(#)base64.c 2.14 (gritter) 4/21/06";
+ cache.c:static char sccsid[] = "@(#)cache.c 1.61 (gritter) 3/4/06";
+ cmd1.c:static char sccsid[] = "@(#)cmd1.c 2.97 (gritter) 6/16/07";
+-cmd2.c:static char sccsid[] = "@(#)cmd2.c 2.46 (gritter) 3/4/06";
+-cmd3.c:static char sccsid[] = "@(#)cmd3.c 2.86 (gritter) 10/1/07";
++cmd2.c:static char sccsid[] = "@(#)cmd2.c 2.47 (gritter) 5/9/10";
++cmd3.c:static char sccsid[] = "@(#)cmd3.c 2.87 (gritter) 10/1/08";
+ cmdtab.c:static char sccsid[] = "@(#)cmdtab.c 2.51 (gritter) 3/4/06";
+ collect.c:static char sccsid[] = "@(#)collect.c 2.54 (gritter) 6/16/07";
+ def.h: * Sccsid @(#)def.h 2.104 (gritter) 3/4/06
+ dotlock.c:static char sccsid[] = "@(#)dotlock.c 2.9 (gritter) 3/20/06";
+ edit.c:static char sccsid[] = "@(#)edit.c 2.24 (gritter) 3/4/06";
+-extern.h: * Sccsid @(#)extern.h 2.161 (gritter) 10/1/07
+-fio.c:static char sccsid[] = "@(#)fio.c 2.73 (gritter) 1/7/08";
++extern.h: * Sccsid @(#)extern.h 2.162 (gritter) 10/1/08
++fio.c:static char sccsid[] = "@(#)fio.c 2.76 (gritter) 9/16/09";
+ getname.c:static char sccsid[] = "@(#)getname.c 2.5 (gritter) 3/4/06";
+ getopt.c: Sccsid @(#)getopt.c 1.7 (gritter) 12/16/07
+ glob.h: * Sccsid @(#)glob.h 2.27 (gritter) 6/16/07
+ head.c:static char sccsid[] = "@(#)head.c 2.17 (gritter) 3/4/06";
+ hmac.c: Sccsid @(#)hmac.c 1.8 (gritter) 3/4/06
+-imap.c:static char sccsid[] = "@(#)imap.c 1.219 (gritter) 1/6/08";
++imap.c:static char sccsid[] = "@(#)imap.c 1.222 (gritter) 3/13/09";
+ imap_gssapi.c:static char sccsid[] = "@(#)imap_gssapi.c 1.10 (gritter) 3/4/06";
+ imap_search.c:static char sccsid[] = "@(#)imap_search.c 1.29 (gritter) 3/4/06";
+-junk.c:static char sccsid[] = "@(#)junk.c 1.73 (gritter) 3/4/06";
++junk.c:static char sccsid[] = "@(#)junk.c 1.75 (gritter) 9/14/08";
+ lex.c:static char sccsid[] = "@(#)lex.c 2.86 (gritter) 12/25/06";
+-list.c:static char sccsid[] = "@(#)list.c 2.61 (gritter) 01/07/07";
++list.c:static char sccsid[] = "@(#)list.c 2.62 (gritter) 12/11/08";
+ lzw.c: * Sccsid @(#)lzw.c 1.11 (gritter) 3/4/06
+ macro.c:static char sccsid[] = "@(#)macro.c 1.13 (gritter) 3/4/06";
+ maildir.c:static char sccsid[] = "@(#)maildir.c 1.20 (gritter) 12/28/06";
+ main.c:static char sccsid[] = "@(#)main.c 2.51 (gritter) 10/1/07";
+ md5.c: Sccsid @(#)md5.c 1.8 (gritter) 3/4/06
+ md5.h: Sccsid @(#)md5.h 1.8 (gritter) 3/4/06
+-mime.c:static char sccsid[] = "@(#)mime.c 2.69 (gritter) 6/29/08";
++mime.c:static char sccsid[] = "@(#)mime.c 2.71 (gritter) 7/5/10";
+ names.c:static char sccsid[] = "@(#)names.c 2.22 (gritter) 3/4/06";
+ nss.c:static char sccsid[] = "@(#)nss.c 1.48 (gritter) 8/4/07";
+-openssl.c:static char sccsid[] = "@(#)openssl.c 1.25 (gritter) 8/4/07";
++openssl.c:static char sccsid[] = "@(#)openssl.c 1.26 (gritter) 5/26/09";
+ pop3.c:static char sccsid[] = "@(#)pop3.c 2.43 (gritter) 3/4/06";
+ popen.c:static char sccsid[] = "@(#)popen.c 2.20 (gritter) 3/4/06";
+-quit.c:static char sccsid[] = "@(#)quit.c 2.28 (gritter) 3/4/06";
++quit.c:static char sccsid[] = "@(#)quit.c 2.30 (gritter) 11/11/08";
+ rcv.h: * Sccsid @(#)rcv.h 2.7 (gritter) 3/4/06
+ send.c:static char sccsid[] = "@(#)send.c 2.86 (gritter) 2/4/08";
+-sendout.c:static char sccsid[] = "@(#)sendout.c 2.99 (gritter) 7/4/08";
++sendout.c:static char sccsid[] = "@(#)sendout.c 2.100 (gritter) 3/1/09";
+ smtp.c:static char sccsid[] = "@(#)smtp.c 2.43 (gritter) 8/4/07";
+ ssl.c:static char sccsid[] = "@(#)ssl.c 1.39 (gritter) 6/12/06";
+ strings.c:static char sccsid[] = "@(#)strings.c 2.6 (gritter) 3/4/06";
+@@ -108,5 +108,5 @@
+ thread.c:static char sccsid[] = "@(#)thread.c 1.57 (gritter) 3/4/06";
+ tty.c:static char sccsid[] = "@(#)tty.c 2.29 (gritter) 3/9/07";
+ v7.local.c:static char sccsid[] = "@(#)v7.local.c 2.10 (gritter) 3/4/06";
+-vars.c:static char sccsid[] = "@(#)vars.c 2.11 (gritter) 3/4/06";
++vars.c:static char sccsid[] = "@(#)vars.c 2.12 (gritter) 10/1/08";
+ */
diff --git a/testing/heirloom-mailx/APKBUILD b/testing/heirloom-mailx/APKBUILD
new file mode 100644
index 000000000..cfb322fba
--- /dev/null
+++ b/testing/heirloom-mailx/APKBUILD
@@ -0,0 +1,66 @@
+# Contributor: Isaac Dunham <ibid.ag@gmail.com>
+# Maintainer: Isaac Dunham <ibid.ag@gmail.com>
+pkgname=heirloom-mailx
+pkgver=12.4
+pkgrel=0
+pkgdesc="A free clone of SysV mailx"
+url="http://heirloom.sourceforge.net/mailx.html"
+arch="all"
+license="BSD"
+depends=""
+makedepends="openssl-dev krb5-dev"
+install=""
+subpackages="$pkgname-doc"
+source="http://sourceforge.net/projects/heirloom/files/heirloom-mailx/$pkgver/mailx-$pkgver.tar.bz2
+ 12.4-to-12.5pre.patch
+ makevars.patch
+ 0001-outof-Introduce-expandaddr-flag.patch
+ 0002-unpack-Disable-option-processing-for-email-addresses.patch
+ 0003-fio_c-Unconditionally-require-wordexp-support.patch
+ 0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch
+ "
+
+_builddir="$srcdir"/mailx-$pkgver
+prepare() {
+ local i
+ cd "$_builddir"
+ for i in $source; do
+ case $i in
+ *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+ esac
+ done
+}
+
+build() {
+ cd "$_builddir"
+ make || return 1
+}
+
+package() {
+ cd "$_builddir"
+ make DESTDIR="$pkgdir" install || return 1
+ install -Dm 0644 COPYING "$pkgdir"/usr/share/licenses/"$pkgname"/COPYING || return 1
+ cd "$pkgdir"/usr/share/man/man1/ && mv mailx.1 "$pkgname".1
+}
+
+md5sums="0c93759e34200eb56a0e7c464680a54a mailx-12.4.tar.bz2
+a4a91391ada32a7b87ff5255d2f06c47 12.4-to-12.5pre.patch
+75abf9efc9fabee598d5500951073cb6 makevars.patch
+268353d063e6c962f02672ecec9cb77b 0001-outof-Introduce-expandaddr-flag.patch
+011a9c9a7d208b363bd548b84c710fa4 0002-unpack-Disable-option-processing-for-email-addresses.patch
+7455da8174ac31a3d1c5afd1a37d7f2d 0003-fio_c-Unconditionally-require-wordexp-support.patch
+19eaa6ee08c45db17b48d65b3eaca78b 0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch"
+sha256sums="92201e769fe346bc0364c87437a330ef3c97ab3e9d7b2235b93f509e85e5716a mailx-12.4.tar.bz2
+d3629782c2b4d676aadea823335a57c8ed5f86e6d6fde31b18313b9c070727bc 12.4-to-12.5pre.patch
+5df76dc08562bf12ab0c2ac1e32fe70f137c18258af29284448448f0b5848ace makevars.patch
+70c268a40d32215392c08f88c841a2125572879f954f4e165bbc8fe6ca1beff8 0001-outof-Introduce-expandaddr-flag.patch
+8bf07ea359daee7477765f1e4f4d7ba6d923a6937743f097a1940b87fe1bdd73 0002-unpack-Disable-option-processing-for-email-addresses.patch
+6902e1fb2c71b24d15db527e10e0bf6bc7e63a3048b7851174693cde92dddbc2 0003-fio_c-Unconditionally-require-wordexp-support.patch
+538285fabe1ede7f62013ced05b00b28e86b8c1543f6de73ee3b1c05a9c2ecec 0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch"
+sha512sums="a0e29972f552bd630ce1a14f70e61661815118520bcd4a00b6cad53f3270d3d08c835ff6982ba8800eb380a5b46f54eb6e60fb7533b5f41c916af45d29605af8 mailx-12.4.tar.bz2
+c2435c18b3e972a77bbaa1b915cae567cafcd65cba1710cd78e7b934d33662361aa1e72fb99d0f109945c603ec847552345a4a5c3ec64dbc307cbb811a6d74d0 12.4-to-12.5pre.patch
+b831544e92b0262b6d5276cb7e78427cb33fd09bc3cb2ffc398cb3f930f05764bcecc8e5b1743554dadc5e0bd791d56b4a72b7a05089db7170437dd5254b9080 makevars.patch
+fc5a22bf17e998c5228ff581388a3e2f8ffad9c70b46f7e94edc63d304e5e9576b59c57df07dc7e40cf234fc8b89bf2c52248592ad834fc4b4d29e25a673edc8 0001-outof-Introduce-expandaddr-flag.patch
+b10a5ec515ba447e828dbf4562b07b65bc2c812f0d731b244f77cc43152bf14200e40d218ebb080fd820dc18ed4666c4f66de579b562a9231d8a0e95b4c0bb25 0002-unpack-Disable-option-processing-for-email-addresses.patch
+c41ad1e90ebc6060ce0a7badfde5fc01b87c4c0c9eacf7e2f55444212cbd93097b37a3e426bcdcb4a565c1b0d16010996d9aca1d61c0d918a1d4acb41754d516 0003-fio_c-Unconditionally-require-wordexp-support.patch
+bee2afb9f691a5c7b715eaa9adb14afbde0694235bb22449741f464812276c3f44d1b90e8b07255d1378b941d2b14133161a1575c40605b0911d8e28afaf578a 0004-globname-Invoke-wordexp-with-WRDE_NOCMD-CVE-2004-277.patch"
diff --git a/testing/heirloom-mailx/makevars.patch b/testing/heirloom-mailx/makevars.patch
new file mode 100644
index 000000000..94d97eb85
--- /dev/null
+++ b/testing/heirloom-mailx/makevars.patch
@@ -0,0 +1,33 @@
+commit 31527ffd5d77c6cf21850bddd9ae7e97e37721ca
+Author: Isaac Dunham <ibid.ag@gmail.com>
+Date: Sat Sep 13 09:48:34 2014 -0700
+
+ Use more standard defaults
+
+diff --git a/Makefile b/Makefile
+index 5f4b124..05d0635 100644
+--- a/Makefile
++++ b/Makefile
+@@ -6,18 +6,18 @@
+ # See the file INSTALL if you need help.
+ #
+
+-PREFIX = /usr/local
++PREFIX = /usr
+ BINDIR = $(PREFIX)/bin
+ MANDIR = $(PREFIX)/share/man
+ SYSCONFDIR = /etc
+
+ MAILRC = $(SYSCONFDIR)/nail.rc
+-MAILSPOOL = /var/mail
+-SENDMAIL = /usr/lib/sendmail
++MAILSPOOL = /var/spool/mail
++SENDMAIL = /usr/sbin/sendmail
+
+ DESTDIR =
+
+-UCBINSTALL = /usr/ucb/install
++UCBINSTALL = /usr/bin/install
+
+ # Define compiler, preprocessor, and linker flags here.
+ # Note that some Linux/glibc versions need -D_GNU_SOURCE in CPPFLAGS, or