aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-07-28 13:08:04 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-07-28 13:08:04 +0200
commitad6cec9e16bf41de2798a0d48ae4d08d019235c9 (patch)
tree63de022cd6f208789728a9918fe23d5019bf5acc
parent5e1d751f292fbe7dc0d2bdc2b03c6349c5c742f9 (diff)
downloadmblaze-ad6cec9e16bf41de2798a0d48ae4d08d019235c9.tar.gz
mhdr: almost-rewrite, use getopt
-rw-r--r--man/mhdr.137
-rwxr-xr-xmcomp22
-rw-r--r--mhdr.c188
3 files changed, 186 insertions, 61 deletions
diff --git a/man/mhdr.1 b/man/mhdr.1
index 31648fc..48672fe 100644
--- a/man/mhdr.1
+++ b/man/mhdr.1
@@ -1,4 +1,4 @@
-.Dd July 22, 2016
+.Dd July 28, 2016
.Dt MHDR 1
.Os
.Sh NAME
@@ -6,7 +6,10 @@
.Nd show mail headers
.Sh SYNOPSIS
.Nm
-.Op Fl Ar header
+.Op Fl h Ar header
+.Op Fl d
+.Op Fl M
+.Op Fl A | Fl D
.Op Ar msgs\ ...
.Sh DESCRIPTION
.Nm
@@ -24,16 +27,36 @@ will default to the current message.
.Pp
The options are as follows:
.Bl -tag -width Ds
-.It Fl Ar header
-Only print the value of the header
-.Sq Ar header Ns Li \&: .
-.Pp
-By default, print all headers in normalized form (lowercase and unfolded).
+.It Fl h Ar header
+Only print the values of the headers in the colon-separated list
+.Ar header .
+.It Fl d
+Decode the headers according to RFC 2047.
+.It Fl M
+Search for all occurrences of the headers
+(default: only the first).
+.It Fl A
+Scan for RFC 5322 addresses in the headers and print them line by line.
+.It Fl D
+Assume header contains RFC 5322 date and print as Unix timestamp.
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr mmsg 7
+.Rs
+.%A N. Freed
+.%A N. Borenstein
+.%B MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text
+.%R RFC 2047
+.%D November 1996
+.Re
+.Rs
+.%A P. Resnick (ed.)
+.%B Internet Message Format
+.%R RFC 5322
+.%D October 2008
+.Re
.Sh AUTHORS
.An Christian Neukirchen Aq Mt chneukirchen@gmail.com
.Sh LICENSE
diff --git a/mcomp b/mcomp
index c8d41ac..66980f4 100755
--- a/mcomp
+++ b/mcomp
@@ -19,7 +19,7 @@ draft="snd.$i"
echo "Cc: "
echo "Bcc: "
echo "Subject: "
- from=$(mhdr -local-mailbox ~/.santoku/profile)
+ from=$(mhdr -h local-mailbox ~/.santoku/profile)
[ "$from" ] && echo "From: $from"
cat ~/.santoku/headers 2>/dev/null
echo
@@ -28,30 +28,30 @@ draft="snd.$i"
*mrepl*)
[ "$#" -eq 0 ] && set -- .
# XXX reply-all
- echo "To: $(mhdr -from "$1")"
+ echo "To: $(mhdr -h from "$1")"
echo "Cc: "
echo "Bcc: "
- s=$(mhdr -subject "$1")
+ s=$(mhdr -d -h subject "$1")
os=
while [ "$os" != "$s" ]; do
os=$s
- s=${s% }
- s=${s%[Rr][Ee]:}
- s=${s%[Aa][Ww]:}
- s=${s%[Ff][Ww][Dd]:}
+ s=${s# }
+ s=${s#[Rr][Ee]:}
+ s=${s#[Aa][Ww]:}
+ s=${s#[Ff][Ww][Dd]:}
done
echo "Subject: Re: $s"
cat ~/.santoku/headers 2>/dev/null
echo -n "References:"
{
- mhdr -references "$1"
- mhdr -message-id "$1"
+ mhdr -h references "$1"
+ mhdr -h message-id "$1"
} | sed 's/^[^<]*//g;s/[^>]*$//g;s/>[^<]*</>\n</g' |
uniq | sed 's/^/ /'
- echo "In-Reply-To: $(mhdr -message-id "$1")"
+ echo "In-Reply-To: $(mhdr -h message-id "$1")"
echo
- echo "$(mhdr -from "$1") wrote:"
+ echo "$(mhdr -d -h from "$1") wrote:"
mshow -R "$1" |
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' |
sed 's/^/> /'
diff --git a/mhdr.c b/mhdr.c
index f177c5e..0820c85 100644
--- a/mhdr.c
+++ b/mhdr.c
@@ -11,22 +11,11 @@
#include "blaze822.h"
-static size_t l;
-static char *hdr;
-
-void
-header(char *file)
-{
- struct message *msg;
-
- msg = blaze822(file);
- if (!msg)
- return;
-
- char *v = blaze822_hdr_(msg, hdr, l);
- if (v)
- printf("%s\n", v);
-}
+static char *hflag;
+static int Aflag;
+static int Dflag;
+static int Mflag;
+static int dflag;
static void
printhdr(char *hdr)
@@ -43,47 +32,160 @@ printhdr(char *hdr)
}
void
-headerall(char *file)
+headerall(struct message *msg)
+{
+ char *h = 0;
+ while ((h = blaze822_next_header(msg, h))) {
+ if (dflag) {
+ char d[4096];
+ blaze822_decode_rfc2047(d, h, sizeof d, "UTF-8");
+ printhdr(d);
+ } else {
+ printhdr(h);
+ }
+ }
+
+ blaze822_free(msg);
+}
+
+void
+print_addresses(char *s)
+{
+ char *disp, *addr;
+ while ((s = blaze822_addr(s, &disp, &addr))) {
+ if (disp && addr) {
+ if (dflag) {
+ char d[4096];
+ blaze822_decode_rfc2047(d, disp, sizeof d,
+ "UTF-8");
+ printf("%s <%s>\n", d, addr);
+ } else {
+ printf("%s <%s>\n", disp, addr);
+ }
+ } else if (addr) {
+ printf("%s\n", addr);
+ }
+ }
+}
+
+void
+print_date(char *s)
+{
+ time_t t = blaze822_date(s);
+ if (t == -1)
+ return;
+ printf("%ld\n", t);
+}
+
+void
+print_decode_header(char *s)
+{
+ char d[4096];
+ blaze822_decode_rfc2047(d, s, sizeof d, "UTF-8");
+ printf("%s\n", d);
+}
+
+void
+print_header(char *v)
+{
+ if (Aflag)
+ print_addresses(v);
+ else if (Dflag)
+ print_date(v);
+ else if (dflag)
+ print_decode_header(v);
+ else
+ printf("%s\n", v);
+}
+
+void
+headermany(struct message *msg)
+{
+ char *hdr = 0;
+ while ((hdr = blaze822_next_header(msg, hdr))) {
+ char *h = hflag;
+ while (*h) {
+ char *n = strchr(h, ':');
+ if (n)
+ *n = 0;
+
+ size_t l = strlen(h);
+ if (strncmp(hdr, h, l) == 0 && hdr[l] == ':') {
+ hdr += l + 1;
+ while (*hdr == ' ' || *hdr == '\t')
+ hdr++;
+ print_header(hdr);
+ }
+
+ if (n) {
+ *n = ':';
+ h = n + 1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ blaze822_free(msg);
+}
+
+void
+header(char *file)
{
struct message *msg;
+ while (*file == ' ' || *file == '\t')
+ file++;
+
msg = blaze822(file);
if (!msg)
return;
- char *h = 0;
- while ((h = blaze822_next_header(msg, h))) {
- char d[4096];
- blaze822_decode_rfc2047(d, h, sizeof d, "UTF-8");
-
- printhdr(d);
+ if (!hflag)
+ return headerall(msg);
+ if (Mflag)
+ return headermany(msg);
+
+ char *h = hflag;
+ while (*h) {
+ char *n = strchr(h, ':');
+ if (n)
+ *n = 0;
+ char *v = blaze822_chdr(msg, h);
+ if (v)
+ print_header(v);
+ if (n) {
+ *n = ':';
+ h = n + 1;
+ } else {
+ break;
+ }
}
+
+ blaze822_free(msg);
}
int
main(int argc, char *argv[])
{
- void (*cb)(char *) = headerall;
-
- if (argc >= 2 && argv[1][0] == '-') {
- l = strlen(argv[1])+1;
- hdr = malloc(l);
- hdr[0] = 0;
- char *s = hdr+1;
- char *t = argv[1]+1;
- while (*t)
- *s++ = tolower(*t++);
- *s = ':';
-
- cb = header;
- argc--;
- argv++;
- }
-
- if (argc == 1 && isatty(0))
- blaze822_loop1(".", cb);
+ int c;
+ while ((c = getopt(argc, argv, "h:ADMdv)) != -1)
+ switch(c) {
+ case 'h': hflag = optarg; break;
+ case 'A': Aflag = 1; break;
+ case 'D': Dflag = 1; break;
+ case 'M': Mflag = 1; break;
+ case 'd': dflag = 1; break;
+ default:
+ fprintf(stderr,
+"Usage: mhdr [-h header] [-d] [-M] [-A|-D] [msgs...]\n");
+ exit(1);
+ }
+
+ if (argc == optind && isatty(0))
+ blaze822_loop1(".", header);
else
- blaze822_loop(argc-1, argv+1, cb);
+ blaze822_loop(argc-optind, argv+optind, header);
return 0;
}