mblaze/mhdr.c
Leah Neukirchen 0ed7f72d31 mhdr: print_addresses: decode only display part of address
RFC 2047.6.2:
   NOTE: Decoding and display of encoded-words occurs *after* a
   structured field body is parsed into tokens.
2021-06-18 01:13:03 +02:00

259 lines
3.8 KiB
C

#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "blaze822.h"
#include "xpledge.h"
static char *hflag;
static char *pflag;
static int Aflag;
static int Dflag;
static int Hflag;
static int Mflag;
static int dflag;
static char *curfile;
static int status;
static void
printhdr(char *hdr)
{
int uc = 1;
if (Hflag)
printf("%s\t", curfile);
while (*hdr && *hdr != ':') {
putc(uc ? toupper(*hdr) : *hdr, stdout);
uc = (*hdr == '-');
hdr++;
}
fputs(hdr, stdout);
fputc('\n', stdout);
status = 0;
}
void
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_quoted(char *s)
{
char *t;
for (t = s; *t; t++)
if ((unsigned char)*t < 32 || strchr("()<>[]:;@\\,.\"", *t))
goto quote;
printf("%s", s);
return;
quote:
putchar('"');
for (t = s; *t; t++) {
if (*t == '"' || *t == '\\')
putchar('\\');
putchar(*t);
}
putchar('"');
}
void
print_addresses(char *s)
{
char *disp, *addr;
char ddec[4096];
while ((s = blaze822_addr(s, &disp, &addr))) {
if (Hflag && addr)
printf("%s\t", curfile);
if (disp && addr) {
if (dflag) {
blaze822_decode_rfc2047(ddec, disp, sizeof ddec, "UTF-8");
ddec[sizeof ddec - 1] = 0;
disp = ddec;
}
print_quoted(disp);
printf(" <%s>\n", 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", (long)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 (pflag) {
char *s, *se;
if (blaze822_mime_parameter(v, pflag, &s, &se)) {
*se = 0;
v = s;
} else {
return;
}
}
status = 0;
if (Hflag && !Aflag)
printf("%s\t", curfile);
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 (strncasecmp(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++;
curfile = file;
msg = blaze822(file);
if (!msg)
return;
if (!hflag) {
headerall(msg);
return;
}
if (Mflag) {
headermany(msg);
return;
}
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[])
{
int c;
while ((c = getopt(argc, argv, "h:p:ADHMd")) != -1)
switch (c) {
case 'h': hflag = optarg; break;
case 'p': pflag = optarg; break;
case 'A': Aflag = 1; break;
case 'D': Dflag = 1; break;
case 'H': Hflag = 1; break;
case 'M': Mflag = 1; break;
case 'd': dflag = 1; break;
default:
fprintf(stderr,
"Usage: mhdr [-h header [-p parameter]] [-d] [-H] [-M] [-A|-D] [msgs...]\n");
exit(2);
}
status = 1;
xpledge("stdio rpath", "");
if (argc == optind && isatty(0))
blaze822_loop1(".", header);
else
blaze822_loop(argc-optind, argv+optind, header);
return status;
}