mhdr: almost-rewrite, use getopt

pull/1/merge
Christian Neukirchen 8 years ago
parent 5e1d751f29
commit ad6cec9e16

@ -1,4 +1,4 @@
.Dd July 22, 2016 .Dd July 28, 2016
.Dt MHDR 1 .Dt MHDR 1
.Os .Os
.Sh NAME .Sh NAME
@ -6,7 +6,10 @@
.Nd show mail headers .Nd show mail headers
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl Ar header .Op Fl h Ar header
.Op Fl d
.Op Fl M
.Op Fl A | Fl D
.Op Ar msgs\ ... .Op Ar msgs\ ...
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
@ -24,16 +27,36 @@ will default to the current message.
.Pp .Pp
The options are as follows: The options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl Ar header .It Fl h Ar header
Only print the value of the header Only print the values of the headers in the colon-separated list
.Sq Ar header Ns Li \&: . .Ar header .
.Pp .It Fl d
By default, print all headers in normalized form (lowercase and unfolded). 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 .El
.Sh EXIT STATUS .Sh EXIT STATUS
.Ex -std .Ex -std
.Sh SEE ALSO .Sh SEE ALSO
.Xr mmsg 7 .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 .Sh AUTHORS
.An Christian Neukirchen Aq Mt chneukirchen@gmail.com .An Christian Neukirchen Aq Mt chneukirchen@gmail.com
.Sh LICENSE .Sh LICENSE

22
mcomp

@ -19,7 +19,7 @@ draft="snd.$i"
echo "Cc: " echo "Cc: "
echo "Bcc: " echo "Bcc: "
echo "Subject: " echo "Subject: "
from=$(mhdr -local-mailbox ~/.santoku/profile) from=$(mhdr -h local-mailbox ~/.santoku/profile)
[ "$from" ] && echo "From: $from" [ "$from" ] && echo "From: $from"
cat ~/.santoku/headers 2>/dev/null cat ~/.santoku/headers 2>/dev/null
echo echo
@ -28,30 +28,30 @@ draft="snd.$i"
*mrepl*) *mrepl*)
[ "$#" -eq 0 ] && set -- . [ "$#" -eq 0 ] && set -- .
# XXX reply-all # XXX reply-all
echo "To: $(mhdr -from "$1")" echo "To: $(mhdr -h from "$1")"
echo "Cc: " echo "Cc: "
echo "Bcc: " echo "Bcc: "
s=$(mhdr -subject "$1") s=$(mhdr -d -h subject "$1")
os= os=
while [ "$os" != "$s" ]; do while [ "$os" != "$s" ]; do
os=$s os=$s
s=${s% } s=${s# }
s=${s%[Rr][Ee]:} s=${s#[Rr][Ee]:}
s=${s%[Aa][Ww]:} s=${s#[Aa][Ww]:}
s=${s%[Ff][Ww][Dd]:} s=${s#[Ff][Ww][Dd]:}
done done
echo "Subject: Re: $s" echo "Subject: Re: $s"
cat ~/.santoku/headers 2>/dev/null cat ~/.santoku/headers 2>/dev/null
echo -n "References:" echo -n "References:"
{ {
mhdr -references "$1" mhdr -h references "$1"
mhdr -message-id "$1" mhdr -h message-id "$1"
} | sed 's/^[^<]*//g;s/[^>]*$//g;s/>[^<]*</>\n</g' | } | sed 's/^[^<]*//g;s/[^>]*$//g;s/>[^<]*</>\n</g' |
uniq | sed 's/^/ /' uniq | sed 's/^/ /'
echo "In-Reply-To: $(mhdr -message-id "$1")" echo "In-Reply-To: $(mhdr -h message-id "$1")"
echo echo
echo "$(mhdr -from "$1") wrote:" echo "$(mhdr -d -h from "$1") wrote:"
mshow -R "$1" | mshow -R "$1" |
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' |
sed 's/^/> /' sed 's/^/> /'

188
mhdr.c

@ -11,22 +11,11 @@
#include "blaze822.h" #include "blaze822.h"
static size_t l; static char *hflag;
static char *hdr; static int Aflag;
static int Dflag;
void static int Mflag;
header(char *file) static int dflag;
{
struct message *msg;
msg = blaze822(file);
if (!msg)
return;
char *v = blaze822_hdr_(msg, hdr, l);
if (v)
printf("%s\n", v);
}
static void static void
printhdr(char *hdr) printhdr(char *hdr)
@ -43,47 +32,160 @@ printhdr(char *hdr)
} }
void 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; struct message *msg;
while (*file == ' ' || *file == '\t')
file++;
msg = blaze822(file); msg = blaze822(file);
if (!msg) if (!msg)
return; return;
char *h = 0; if (!hflag)
while ((h = blaze822_next_header(msg, h))) { return headerall(msg);
char d[4096]; if (Mflag)
blaze822_decode_rfc2047(d, h, sizeof d, "UTF-8"); return headermany(msg);
printhdr(d); 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 int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
void (*cb)(char *) = headerall; int c;
while ((c = getopt(argc, argv, "h:ADMdv)) != -1)
if (argc >= 2 && argv[1][0] == '-') { switch(c) {
l = strlen(argv[1])+1; case 'h': hflag = optarg; break;
hdr = malloc(l); case 'A': Aflag = 1; break;
hdr[0] = 0; case 'D': Dflag = 1; break;
char *s = hdr+1; case 'M': Mflag = 1; break;
char *t = argv[1]+1; case 'd': dflag = 1; break;
while (*t) default:
*s++ = tolower(*t++); fprintf(stderr,
*s = ':'; "Usage: mhdr [-h header] [-d] [-M] [-A|-D] [msgs...]\n");
exit(1);
cb = header; }
argc--;
argv++; if (argc == optind && isatty(0))
} blaze822_loop1(".", header);
if (argc == 1 && isatty(0))
blaze822_loop1(".", cb);
else else
blaze822_loop(argc-1, argv+1, cb); blaze822_loop(argc-optind, argv+optind, header);
return 0; return 0;
} }

Loading…
Cancel
Save