X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fwhom.c;h=c4e7e8f87497fa1bee07e0ed603280babc472441;hp=57fddc8eda1f889fe9e317cf619289215ce9c2f6;hb=a87df3543d3bc128ba4079d1f95638476ba5ca50;hpb=a72c94d4e0c02b5095ca6798de2474768490ef94 diff --git a/uip/whom.c b/uip/whom.c index 57fddc8..c4e7e8f 100644 --- a/uip/whom.c +++ b/uip/whom.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include static struct swit switches[] = { #define VERSIONSW 0 @@ -20,13 +22,17 @@ static struct swit switches[] = { { "tocc", 0 }, #define NTOCCSW 3 { "notocc", 2 }, -#define BCCSW 4 +#define DCCSW 4 + { "dcc", 0 }, +#define NDCCSW 5 + { "nodcc", 2 }, +#define BCCSW 6 { "bcc", 0 }, -#define NBCCSW 5 +#define NBCCSW 7 { "nobcc", 2 }, -#define ALISW 6 +#define ALISW 8 { "alias", 0 }, -#define NALISW 7 +#define NALISW 9 { "noalias", 2 }, { NULL, 0 } }; @@ -37,7 +43,8 @@ static struct swit switches[] = { #define HRESENT (1<<1) #define HTO (1<<2) #define HCC (1<<3) -#define HBCC (1<<4) +#define HDCC (1<<4) +#define HBCC (1<<5) struct mailname head = {0}; struct mailname *mp = &head; @@ -46,10 +53,12 @@ static char *cmd; static int resent = 0; /* consider normal or resent headers */ static int toccsw = 1; /* list sighted recipients */ -static int bccsw = 1; /* list hidden recipients */ +static int dccsw = 1; /* list hidden dcc recipients */ +static int bccsw = 1; /* list hidden bcc recipients */ static int alisw = 1; /* expand aliases on rcpt addrs */ -static char *separator = "\t==BCC=="; +static char *dccsep = "\t==DCC=="; +static char *bccsep = "\t==BCC=="; /* @@ -58,6 +67,7 @@ static char *separator = "\t==BCC=="; static int process(char *); static void proc_hdr(char *, char *); static int print(void); +static int printdcc(void); static int printbcc(void); static void printone(struct mailname *); @@ -85,20 +95,20 @@ main(int argc, char **argv) switch (smatch(++cp, switches)) { case AMBIGSW: ambigsw(cp, switches); - done(1); + exit(EX_USAGE); case UNKWNSW: - adios(NULL, "-%s unknown", cp); + adios(EX_USAGE, NULL, "-%s unknown", cp); case HELPSW: snprintf(buf, sizeof(buf), "%s [switches] file ...", invo_name); print_help(buf, switches, 1); - done(1); + exit(argc == 2 ? EX_OK : EX_USAGE); case VERSIONSW: print_version(invo_name); - done(1); + exit(argc == 2 ? EX_OK : EX_USAGE); case TOCCSW: toccsw = 1; @@ -107,6 +117,13 @@ main(int argc, char **argv) toccsw = 0; continue; + case DCCSW: + dccsw = 1; + continue; + case NDCCSW: + dccsw = 0; + continue; + case BCCSW: bccsw = 1; continue; @@ -123,7 +140,7 @@ main(int argc, char **argv) } } if (filep > NFILES) { - adios(NULL, "too many files (more than %d)", + adios(EX_USAGE, NULL, "too many files (more than %d)", NFILES); } else { files[filep++] = cp; @@ -131,10 +148,10 @@ main(int argc, char **argv) } files[filep] = NULL; if (!filep) { - adios(NULL, "usage: %s [switches] file ...", invo_name); + adios(EX_USAGE, NULL, "usage: %s [switches] file ...", invo_name); } - if (!toccsw && !bccsw) { - adios(NULL, "give -tocc or -bcc or both to produce output"); + if (!toccsw && !dccsw && !bccsw) { + adios(EX_USAGE, NULL, "use at least one of: -tocc -dcc -bcc"); } for (filep=0; files[filep]; filep++) { process(files[filep]); @@ -143,7 +160,20 @@ main(int argc, char **argv) cmd = add("ali -list", NULL); if ((n=print()) && alisw) { if (!(in = popen(cmd, "r"))) { - adios("popen", "unable to"); + adios(EX_IOERR, "popen", "unable to"); + } + while (fgets(buf, sizeof buf, in)) { + fputs(buf, stdout); + } + pclose(in); + } + free(cmd); + naddrs += n; + + cmd = add("ali -list", NULL); + if ((n=printdcc()) && alisw) { + if (!(in = popen(cmd, "r"))) { + adios(EX_IOERR, "popen", "unable to"); } while (fgets(buf, sizeof buf, in)) { fputs(buf, stdout); @@ -156,7 +186,7 @@ main(int argc, char **argv) cmd = add("ali -list", NULL); if ((n=printbcc()) && alisw) { if (!(in = popen(cmd, "r"))) { - adios("popen", "unable to"); + adios(EX_IOERR, "popen", "unable to"); } while (fgets(buf, sizeof buf, in)) { fputs(buf, stdout); @@ -165,6 +195,7 @@ main(int argc, char **argv) } free(cmd); naddrs += n; + return naddrs ? 0 : 1; } @@ -172,46 +203,34 @@ main(int argc, char **argv) static int process(char *file) { - int state, compnum; - char *cp = NULL; - char buf[BUFSIZ], name[NAMESZ]; + enum state state; + struct field f = free_field; + int compnum; FILE *in; if ((in = fopen(file, "r")) == NULL) { - adios(file, "unable to open"); + adios(EX_IOERR, file, "unable to open"); } - for (compnum = 1, state = FLD;;) { - switch (state = m_getfld(state, name, buf, sizeof(buf), in)) { - case FLD: - compnum++; - proc_hdr(name, buf); + for (compnum=1, state=FLD2;; compnum++) { + switch (state = m_getfld2(state, &f, in)) { + case FLD2: + proc_hdr(f.name, f.value); continue; - case FLDPLUS: - compnum++; - cp = add(buf, cp); - while (state == FLDPLUS) { - state = m_getfld(state, name, buf, - sizeof(buf), in); - cp = add(buf, cp); - } - proc_hdr(name, cp); - free(cp); - continue; - - case BODY: - case FILEEOF: + case BODY2: + case FILEEOF2: break; - case LENERR: - case FMTERR: - adios(NULL, "message format error in component #%d", + case LENERR2: + case FMTERR2: + case IOERR2: + adios(EX_DATAERR, NULL, "message format error in component #%d", compnum); default: - adios(NULL, "getfld() returned %d", state); + adios(EX_SOFTWARE, NULL, "getfld() returned %d", state); } break; } @@ -240,12 +259,16 @@ proc_hdr(char *name, char *val) type = HTO; } else if (mh_strcasecmp(name, "cc")==0) { type = HCC; + } else if (mh_strcasecmp(name, "dcc")==0) { + type = HDCC; } else if (mh_strcasecmp(name, "bcc")==0) { type = HBCC; } else if (mh_strcasecmp(name, "resent-to")==0) { type = (HRESENT | HTO); } else if (mh_strcasecmp(name, "resent-cc")==0) { type = (HRESENT | HCC); + } else if (mh_strcasecmp(name, "resent-dcc")==0) { + type = (HRESENT | HDCC); } else if (mh_strcasecmp(name, "resent-bcc")==0) { type = (HRESENT | HBCC); } @@ -257,13 +280,16 @@ proc_hdr(char *name, char *val) if ((type&HTO || type&HCC) && !toccsw) { return; } + if ((type&HDCC) && !dccsw) { + return; + } if ((type&HBCC) && !bccsw) { return; } while ((cp = getname(val))) { if (!(mp->m_next = getm(cp, NULL, 0, AD_NAME, NULL))) { - adios(NULL, "illegal address: %s", cp); + adios(EX_DATAERR, NULL, "illegal address: %s", cp); } mp = mp->m_next; if (mp->m_type == BADHOST) { @@ -300,6 +326,30 @@ print(void) ** Walk through the list of addresses and print the right ones. */ static int +printdcc(void) +{ + int naddrs = 0; + + for (mp=head.m_next; mp; mp=mp->m_next) { + /* skip unless both are resent or neither one is */ + if (resent != (mp->m_type&HRESENT)) { + continue; + } + if (mp->m_type & HDCC) { + if (!naddrs && (toccsw || bccsw)) { + puts(dccsep); + } + naddrs++; + printone(mp); + } + } + return naddrs; +} + +/* +** Walk through the list of addresses and print the right ones. +*/ +static int printbcc(void) { int naddrs = 0; @@ -310,8 +360,8 @@ printbcc(void) continue; } if (mp->m_type & HBCC) { - if (!naddrs && toccsw) { - puts(separator); + if (!naddrs && (toccsw || dccsw)) { + puts(bccsep); } naddrs++; printone(mp);