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
.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

22
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/^/> /'

188
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;
}

Loading…
Cancel
Save