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>
15 static struct swit switches[] = {
38 #define HRESENT (1<<1)
43 struct mailname head = {0};
44 struct mailname *mp = &head;
48 static int resent = 0; /* consider normal or resent headers */
49 static int toccsw = 1; /* list sighted recipients */
50 static int bccsw = 1; /* list hidden recipients */
51 static int alisw = 1; /* expand aliases on rcpt addrs */
53 static char *separator = "\t==BCC==";
59 static int process(char *);
60 static void proc_hdr(char *, char *);
61 static int print(void);
62 static int printbcc(void);
63 static void printone(struct mailname *);
67 main(int argc, char **argv)
69 int filep=0, naddrs=0, n;
71 char buf[BUFSIZ], **argp;
72 char **arguments, *files[NFILES];
75 setlocale(LC_ALL, "");
76 invo_name = mhbasename(argv[0]);
78 /* read user profile/context */
81 arguments = getarguments(invo_name, argc, argv, 1);
84 while ((cp = *argp++)) {
86 switch (smatch(++cp, switches)) {
88 ambigsw(cp, switches);
92 adios(NULL, "-%s unknown", cp);
95 snprintf(buf, sizeof(buf),
96 "%s [switches] file ...",
98 print_help(buf, switches, 1);
101 print_version(invo_name);
126 if (filep > NFILES) {
127 adios(NULL, "too many files (more than %d)",
135 adios(NULL, "usage: %s [switches] file ...", invo_name);
137 if (!toccsw && !bccsw) {
138 adios(NULL, "give -tocc or -bcc or both to produce output");
140 for (filep=0; files[filep]; filep++) {
141 process(files[filep]);
144 cmd = add("ali -list", NULL);
145 if ((n=print()) && alisw) {
146 if (!(in = popen(cmd, "r"))) {
147 adios("popen", "unable to");
149 while (fgets(buf, sizeof buf, in)) {
157 cmd = add("ali -list", NULL);
158 if ((n=printbcc()) && alisw) {
159 if (!(in = popen(cmd, "r"))) {
160 adios("popen", "unable to");
162 while (fgets(buf, sizeof buf, in)) {
169 return naddrs ? 0 : 1;
178 char buf[BUFSIZ], name[NAMESZ];
182 if ((in = fopen(file, "r")) == NULL) {
183 adios(file, "unable to open");
186 for (compnum = 1, state = FLD;;) {
187 switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
196 while (state == FLDPLUS) {
197 state = m_getfld(state, name, buf,
211 adios(NULL, "message format error in component #%d",
215 adios(NULL, "getfld() returned %d", state);
225 ** Check if the header contains addresses we're interested in.
226 ** If so, extract the addresses and add them to the global list.
229 proc_hdr(char *name, char *val)
234 while (*val==' ' || *val=='\t' || *val=='\n') {
237 if (strncasecmp(name, "resent-", 7)==0) {
240 if (mh_strcasecmp(name, "to")==0) {
242 } else if (mh_strcasecmp(name, "cc")==0) {
244 } else if (mh_strcasecmp(name, "bcc")==0) {
246 } else if (mh_strcasecmp(name, "resent-to")==0) {
247 type = (HRESENT | HTO);
248 } else if (mh_strcasecmp(name, "resent-cc")==0) {
249 type = (HRESENT | HCC);
250 } else if (mh_strcasecmp(name, "resent-bcc")==0) {
251 type = (HRESENT | HBCC);
253 /* ignore non-recpient headers */
257 /* ignore recipient headers we are not interested in */
258 if ((type&HTO || type&HCC) && !toccsw) {
261 if ((type&HBCC) && !bccsw) {
265 while ((cp = getname(val))) {
266 if (!(mp->m_next = getm(cp, NULL, 0, AD_NAME, NULL))) {
267 adios(NULL, "illegal address: %s", cp);
270 if (mp->m_type == BADHOST) {
271 admonish(NULL, "bad address `%s'", mp->m_text);
280 ** Walk through the list of addresses and print the right ones.
287 for (mp=head.m_next; mp; mp=mp->m_next) {
288 /* skip unless both are resent or neither one is */
289 if (resent != (mp->m_type&HRESENT)) {
292 if (mp->m_type & (HTO|HCC)) {
301 ** Walk through the list of addresses and print the right ones.
308 for (mp=head.m_next; mp; mp=mp->m_next) {
309 /* skip unless both are resent or neither one is */
310 if (resent != (mp->m_type&HRESENT)) {
313 if (mp->m_type & HBCC) {
314 if (!naddrs && toccsw) {
326 ** Print one single address in appropriate form.
329 printone(struct mailname *mp)
334 snprintf(buf, sizeof buf, " %s@%s", mp->m_mbox, mp->m_host);
336 snprintf(buf, sizeof buf, " %s", mp->m_mbox);