2 ** whom.c -- list recipients of message
4 ** This code is Copyright (c) 2012, by the authors of mmh. See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
10 #include <h/addrsbr.h>
11 #include <h/fmt_scan.h>
14 static struct swit switches[] = {
37 #define HRESENT (1<<1)
42 struct mailname head = {0};
43 struct mailname *mp = &head;
47 static int resent = 0; /* consider normal or resent headers */
48 static int toccsw = 1; /* list sighted recipients */
49 static int bccsw = 1; /* list hidden recipients */
50 static int alisw = 1; /* expand aliases on rcpt addrs */
52 static char *separator = "\t==BCC==";
58 static int process(char *);
59 static void proc_hdr(char *, char *);
60 static int print(void);
61 static int printbcc(void);
62 static void printone(struct mailname *);
66 main(int argc, char **argv)
68 int filep=0, naddrs=0, n;
70 char buf[BUFSIZ], **argp;
71 char **arguments, *files[NFILES];
74 setlocale(LC_ALL, "");
75 invo_name = mhbasename(argv[0]);
77 /* read user profile/context */
80 arguments = getarguments(invo_name, argc, argv, 1);
83 while ((cp = *argp++)) {
85 switch (smatch(++cp, switches)) {
87 ambigsw(cp, switches);
91 adios(NULL, "-%s unknown", cp);
94 snprintf(buf, sizeof(buf),
95 "%s [switches] file ...",
97 print_help(buf, switches, 1);
100 print_version(invo_name);
125 if (filep > NFILES) {
126 adios(NULL, "too many files (more than %d)",
134 adios(NULL, "usage: %s [switches] file ...", invo_name);
136 if (!toccsw && !bccsw) {
137 adios(NULL, "give -tocc or -bcc or both to produce output");
139 for (filep=0; files[filep]; filep++) {
140 process(files[filep]);
143 cmd = add("ali -list", NULL);
144 if ((n=print()) && alisw) {
145 if (!(in = popen(cmd, "r"))) {
146 adios("popen", "unable to");
148 while (fgets(buf, sizeof buf, in)) {
156 cmd = add("ali -list", NULL);
157 if ((n=printbcc()) && alisw) {
158 if (!(in = popen(cmd, "r"))) {
159 adios("popen", "unable to");
161 while (fgets(buf, sizeof buf, in)) {
168 return naddrs ? 0 : 1;
177 char buf[BUFSIZ], name[NAMESZ];
181 if ((in = fopen(file, "r")) == NULL) {
182 adios(file, "unable to open");
185 for (compnum = 1, state = FLD;;) {
186 switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
195 while (state == FLDPLUS) {
196 state = m_getfld(state, name, buf,
210 adios(NULL, "message format error in component #%d",
214 adios(NULL, "getfld() returned %d", state);
224 ** Check if the header contains addresses we're interested in.
225 ** If so, extract the addresses and add them to the global list.
228 proc_hdr(char *name, char *val)
233 while (*val==' ' || *val=='\t' || *val=='\n') {
236 if (strncasecmp(name, "resent-", 7)==0) {
239 if (mh_strcasecmp(name, "to")==0) {
241 } else if (mh_strcasecmp(name, "cc")==0) {
243 } else if (mh_strcasecmp(name, "bcc")==0) {
245 } else if (mh_strcasecmp(name, "resent-to")==0) {
246 type = (HRESENT | HTO);
247 } else if (mh_strcasecmp(name, "resent-cc")==0) {
248 type = (HRESENT | HCC);
249 } else if (mh_strcasecmp(name, "resent-bcc")==0) {
250 type = (HRESENT | HBCC);
252 /* ignore non-recpient headers */
256 /* ignore recipient headers we are not interested in */
257 if ((type&HTO || type&HCC) && !toccsw) {
260 if ((type&HBCC) && !bccsw) {
264 while ((cp = getname(val))) {
265 if (!(mp->m_next = getm(cp, NULL, 0, AD_NAME, NULL))) {
266 adios(NULL, "illegal address: %s", cp);
269 if (mp->m_type == BADHOST) {
270 admonish(NULL, "bad address `%s'", mp->m_text);
279 ** Walk through the list of addresses and print the right ones.
286 for (mp=head.m_next; mp; mp=mp->m_next) {
287 /* skip unless both are resent or neither one is */
288 if (resent != (mp->m_type&HRESENT)) {
291 if (mp->m_type & (HTO|HCC)) {
300 ** Walk through the list of addresses and print the right ones.
307 for (mp=head.m_next; mp; mp=mp->m_next) {
308 /* skip unless both are resent or neither one is */
309 if (resent != (mp->m_type&HRESENT)) {
312 if (mp->m_type & HBCC) {
313 if (!naddrs && toccsw) {
325 ** Print one single address in appropriate form.
328 printone(struct mailname *mp)
333 snprintf(buf, sizeof buf, " %s@%s", mp->m_mbox, mp->m_host);
335 snprintf(buf, sizeof buf, " %s", mp->m_mbox);