1 #include <sys/types.h>
2 
3 #include <errno.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 
9 #include "blaze822.h"
10 #include "xpledge.h"
11 
12 static int aflag;
13 static int dflag;
14 static char defaulthflags[] = "from:sender:reply-to:to:cc:bcc:"
15     "resent-from:resent-sender:resent-to:resent-cc:resent-bcc:";
16 static char *hflag = defaulthflags;
17 
18 void
print_quoted(char * s)19 print_quoted(char *s)
20 {
21 	char *t;
22 
23 	for (t = s; *t; t++)
24                 if ((unsigned char)*t < 32 || strchr("()<>[]:;@\\,.\"", *t))
25 			goto quote;
26 
27 	printf("%s", s);
28 	return;
29 
30 quote:
31 	putchar('"');
32 	for (t = s; *t; t++) {
33 		if (*t == '"' || *t == '\\')
34 			putchar('\\');
35 		putchar(*t);
36 	}
37 	putchar('"');
38 
39 }
40 
41 void
addr(char * file)42 addr(char *file)
43 {
44 	while (*file == ' ' || *file == '\t')
45 		file++;
46 
47 	struct message *msg = blaze822(file);
48 	if (!msg)
49 		return;
50 
51 	char *h = hflag;
52 	char *v;
53 	while (*h) {
54 		char *n = strchr(h, ':');
55 		if (n)
56 			*n = 0;
57 		v = blaze822_chdr(msg, h);
58 		if (v) {
59 			char *disp, *addr;
60 			char vdec[16384];
61 			blaze822_decode_rfc2047(vdec, v, sizeof vdec - 1, "UTF-8");
62 			vdec[sizeof vdec - 1] = 0;
63 			v = vdec;
64 
65 			while ((v = blaze822_addr(v, &disp, &addr))) {
66 				if (disp && addr && strcmp(disp, addr) == 0)
67 					disp = 0;
68 
69 				if (aflag) {
70 					if (addr)
71 						printf("%s\n", addr);
72 				} else if (dflag) {
73 					if (disp) {
74 						print_quoted(disp);
75 						printf("\n");
76 					}
77 				} else {
78 					if (disp && addr) {
79 						print_quoted(disp);
80 						printf(" <%s>\n", addr);
81 					} else if (addr) {
82 						printf("%s\n", addr);
83 					}
84 				}
85 			}
86 		}
87 		if (n) {
88 			*n = ':';
89 			h = n + 1;
90 		} else {
91 			break;
92 		}
93 	}
94 	blaze822_free(msg);
95 }
96 
97 int
main(int argc,char * argv[])98 main(int argc, char *argv[])
99 {
100 	int c;
101 	while ((c = getopt(argc, argv, "adh:")) != -1)
102 		switch (c) {
103 		case 'a': aflag = 1; break;
104 		case 'd': dflag = 1; break;
105 		case 'h': hflag = optarg; break;
106 		default:
107 			fprintf(stderr,
108 			    "Usage: maddr [-ad] [-h headers] [msgs...]\n");
109 			exit(1);
110 		}
111 
112 	xpledge("stdio rpath", "");
113 
114 	if (argc == optind && isatty(0))
115 		blaze822_loop1(":", addr);
116 	else
117 		blaze822_loop(argc-optind, argv+optind, addr);
118 
119 	return 0;
120 }
121