diff --git a/GNUmakefile b/GNUmakefile index 6d96d60..d730bd1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,7 +6,7 @@ OS := $(shell uname) ifeq ($(OS),OpenBSD) LOCALBASE=/usr/local -CFLAGS+=-I$(LOCALBASE)/include -pthread +override CFLAGS+=-I$(LOCALBASE)/include -pthread LDLIBS=-L$(LOCALBASE)/lib -liconv -pthread endif diff --git a/man/mshow.1 b/man/mshow.1 index ef439ed..dbb0d9d 100644 --- a/man/mshow.1 +++ b/man/mshow.1 @@ -8,7 +8,7 @@ .Nm .Op Fl h Ar headers .Op Fl A Ar mimetypes -.Op Fl nqrHLN +.Op Fl nqrFHLN .Op Ar msgs\ ... .Nm .Fl x Ar msg @@ -62,6 +62,8 @@ Don't render the body, stop after header output. .It Fl r Don't render the body, print raw body. This may be dangerous to use on a tty. +.It Fl F +Don't apply filters to MIME parts. .It Fl H Don't decode the headers, print all raw headers. This may be dangerous to use on a tty. diff --git a/mcom b/mcom index 6fe2b84..fb7ec8d 100755 --- a/mcom +++ b/mcom @@ -38,6 +38,23 @@ needs_multipart() { grep -q '^#[^ ]*/[^ ]* ' "$1" } +do_mime() { + if needs_multipart "$draft"; then + ( + IFS=' +' + msed '/attach/d' $draft + for f in $(mhdr -M -h attach $draft); do + printf '#%s %s\n' \ + "$(file -Lbi $f | sed 's/ //g')" \ + "$f" + done + ) | mmime >$draftmime + else + mmime -r <"$draft" >"$draftmime" + fi +} + MBLAZE=${MBLAZE:-$HOME/.mblaze} sendmail=$(mhdr -h sendmail "$MBLAZE/profile") @@ -173,6 +190,7 @@ fi fi } >$draft +automime= c=e while :; do case "$c" in @@ -183,7 +201,7 @@ while :; do esac if [ -e $draftmime ]; then - if [ $draft -ot $draftmime ]; then + if [ $draft -ot $draftmime ] || [ "$automime" -eq 1 ]; then stampdate $draftmime if $sendmail <$draftmime; then if [ "$outbox" ]; then @@ -227,20 +245,7 @@ while :; do exit 1 ;; m|mime) - if needs_multipart "$draft"; then - ( - IFS=' -' - msed '/attach/d' $draft - for f in $(mhdr -M -h attach $draft); do - printf '#%s %s\n' \ - "$(file -Lbi $f | sed 's/ //g')" \ - "$f" - done - ) | mmime >$draftmime - else - mmime -r <"$draft" >"$draftmime" - fi + do_mime mshow -t $draftmime c= ;; @@ -249,6 +254,12 @@ while :; do if ! ${EDITOR:-vi} $draft; then c=c fi + if mmime -c <$draft; then + automime= + else + automime=1 + do_mime + fi ;; d|delete) rm -i $draft @@ -278,7 +289,7 @@ while :; do c= ;; *) - printf 'What now? ([s]end, [c]ancel, [d]elete, [e]dit, [m]ime, sign, encrypt) ' + printf 'What now? (%s[s]end, [c]ancel, [d]elete, [e]dit, [m]ime, sign, encrypt) ' "${automime:+mime and }" read -r c ;; esac diff --git a/mflow.c b/mflow.c index 6a9d55b..6405b28 100644 --- a/mflow.c +++ b/mflow.c @@ -188,7 +188,7 @@ main(int argc, char *argv[]) continue; } - if (rd > 0 && line[rd-1] == ' ') { // flowed line + if (reflow && rd > 0 && line[rd-1] == ' ') { // flowed line if (delsp) line[--rd] = 0; flowed(quotes, line, rd); diff --git a/mmime.c b/mmime.c index e6204ed..fcd593b 100644 --- a/mmime.c +++ b/mmime.c @@ -86,8 +86,11 @@ int gen_qp(uint8_t *s, off_t size, int maxlinelen, int linelen) } if ((s[i] > 126) || - (s[i] < 32 && s[i] != '\n' && s[i] != '\t') || - (s[i] == '=')) { + (s[i] == '=') || + (linelen == 0 && + (strncmp((char *)s, "From ", 5) == 0 || + (s[i] == '.' && i+1 < size && + (s[i+1] == '\n' || s[i+1] == '\r'))))) { printf("=%02X", s[i]); linelen += 3; prev = s[i]; @@ -100,6 +103,18 @@ int gen_qp(uint8_t *s, off_t size, int maxlinelen, int linelen) putc_unlocked('_', stdout); linelen++; prev = '_'; + } else if (s[i] < 33 && s[i] != '\n') { + if ((s[i] == ' ' || s[i] == '\t') && + i+1 < size && + (s[i+1] != '\n' && s[i+1] != '\r')) { + putc_unlocked(s[i], stdout); + linelen += 1; + prev = s[i]; + } else { + printf("=%02X", s[i]); + linelen += 3; + prev = '_'; + } } else if (s[i] == '\n') { if (prev == ' ' || prev == '\t') puts("="); diff --git a/mshow.c b/mshow.c index a759181..6407080 100644 --- a/mshow.c +++ b/mshow.c @@ -19,6 +19,7 @@ static int rflag; static int Rflag; static int qflag; +static int Fflag; static int Hflag; static int Lflag; static int Nflag; @@ -728,12 +729,13 @@ main(int argc, char *argv[]) pid_t pid1 = -1, pid2 = -1; int c; - while ((c = getopt(argc, argv, "h:A:qrtHLNx:O:Rn")) != -1) + while ((c = getopt(argc, argv, "h:A:qrtFHLNx:O:Rn")) != -1) switch (c) { case 'h': hflag = optarg; break; case 'A': Aflag = optarg; break; case 'q': qflag = 1; break; case 'r': rflag = 1; break; + case 'F': Fflag = 1; break; case 'H': Hflag = 1; break; case 'L': Lflag = 1; break; case 'N': Nflag = 1; break; @@ -744,7 +746,7 @@ main(int argc, char *argv[]) case 'n': nflag = 1; break; default: fprintf(stderr, - "Usage: mshow [-h headers] [-A mimetypes] [-nqrHLN] [msgs...]\n" + "Usage: mshow [-h headers] [-A mimetypes] [-nqrFHLN] [msgs...]\n" " mshow -x msg parts...\n" " mshow -O msg parts...\n" " mshow -t msgs...\n" @@ -795,7 +797,7 @@ main(int argc, char *argv[]) } else if (Rflag) { // render for reply blaze822_loop(argc-optind, argv+optind, reply); } else { // show - if (!(qflag || rflag)) { + if (!(qflag || rflag || Fflag)) { char *f = getenv("MAILFILTER"); if (!f) f = blaze822_home_file("filter"); diff --git a/rfc2047.c b/rfc2047.c index 0d5bea5..6d4760a 100644 --- a/rfc2047.c +++ b/rfc2047.c @@ -41,9 +41,9 @@ blaze822_decode_qp(char *start, char *stop, char **deco, size_t *decleno, int un unsigned char c2 = s[2]; s += 3; if (c1 > 127 || c2 > 127 || hex[c1] < 0 || hex[c2] < 0) { - *buf++ = '?'; - *buf++ = '?'; - *buf++ = '?'; + *buf++ = '='; + *buf++ = c1; + *buf++ = c2; continue; } *buf++ = (hex[c1] << 4) | hex[c2];