X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Frcvdist.c;h=af3fc10d0511ec34a1206bddb674dc26436e4773;hp=24cf48b718a5b99b00e99e4da2cba23b6cdddffc;hb=6e9577f324bef90765a5edc02044eb111ec48072;hpb=240013872c392fe644bd4f79382d9f5314b4ea60 diff --git a/uip/rcvdist.c b/uip/rcvdist.c index 24cf48b..af3fc10 100644 --- a/uip/rcvdist.c +++ b/uip/rcvdist.c @@ -10,19 +10,24 @@ #include #include #include -#include #include +#include +#include +#include +#include static struct swit switches[] = { #define FORMSW 0 - { "form formfile", 4 }, + { "form formfile", 0 }, #define VERSIONSW 1 - { "version", 0 }, + { "Version", 0 }, #define HELPSW 2 { "help", 0 }, { NULL, 0 } }; +char *version=VERSION; + static char backup[BUFSIZ] = ""; static char drft[BUFSIZ] = ""; static char tmpfil[BUFSIZ] = ""; @@ -31,116 +36,101 @@ static char tmpfil[BUFSIZ] = ""; ** prototypes */ static void rcvdistout(FILE *, char *, char *); -static void unlink_done(int) NORETURN; +void unlink_done(); int main(int argc, char **argv) { - pid_t child_id; - int i, vecp = 1; + int vecp = 1; char *addrs = NULL, *cp, *form = NULL, buf[BUFSIZ]; char **argp, **arguments, *vec[MAXARGS]; FILE *fp; char *tfile = NULL; - done=unlink_done; + if (atexit(unlink_done) != 0) { + adios(EX_OSERR, NULL, "atexit failed"); + } -#ifdef LOCALE setlocale(LC_ALL, ""); -#endif invo_name = mhbasename(argv[0]); /* read user profile/context */ context_read(); - mts_init(invo_name); arguments = getarguments(invo_name, argc, argv, 1); argp = arguments; while ((cp = *argp++)) { if (*cp == '-') { switch (smatch(++cp, switches)) { - case AMBIGSW: - ambigsw(cp, switches); - done(1); - case UNKWNSW: - vec[vecp++] = --cp; - continue; - - case HELPSW: - snprintf(buf, sizeof(buf), "%s [switches] [switches for postproc] address ...", invo_name); - print_help(buf, switches, 1); - done(1); - case VERSIONSW: - print_version(invo_name); - done(1); - - case FORMSW: - if (!(form = *argp++) || *form == '-') - adios(NULL, "missing argument to %s", argp[-2]); - continue; + case AMBIGSW: + ambigsw(cp, switches); + exit(EX_USAGE); + case UNKWNSW: + vec[vecp++] = --cp; + continue; + + case HELPSW: + snprintf(buf, sizeof(buf), "%s [switches] [switches for spost] address ...", invo_name); + print_help(buf, switches, 1); + exit(argc == 2 ? EX_OK : EX_USAGE); + case VERSIONSW: + print_version(invo_name); + exit(argc == 2 ? EX_OK : EX_USAGE); + + case FORMSW: + if (!(form = *argp++) || *form == '-') { + adios(EX_USAGE, NULL, "missing argument to %s", + argp[-2]); + } + continue; } } - addrs = addrs ? add(cp, add(", ", addrs)) : getcpy(cp); + addrs = addrs ? add(cp, add(", ", addrs)) : mh_xstrdup(cp); } - if (addrs == NULL) - adios(NULL, "usage: %s [switches] [switches for postproc] address ...", invo_name); + if (!addrs) { + adios(EX_USAGE, NULL, "usage: %s [switches] [switches for spost] address ...", invo_name); + } umask(~m_gmprot()); tfile = m_mktemp2(NULL, invo_name, NULL, &fp); - if (tfile == NULL) adios("rcvdist", "unable to create temporary file"); + if (tfile == NULL) adios(EX_CANTCREAT, "rcvdist", "unable to create temporary file"); strncpy(tmpfil, tfile, sizeof(tmpfil)); cpydata(fileno(stdin), fileno(fp), "message", tmpfil); fseek(fp, 0L, SEEK_SET); tfile = m_mktemp2(NULL, invo_name, NULL, NULL); - if (tfile == NULL) adios("forw", "unable to create temporary file"); + if (tfile == NULL) adios(EX_CANTCREAT, "forw", "unable to create temporary file"); strncpy(drft, tfile, sizeof(tmpfil)); rcvdistout(fp, form, addrs); fclose(fp); - if (distout(drft, tmpfil, backup) == NOTOK) - done(1); + if (distout(drft, tmpfil, backup) == NOTOK) { + exit(EX_IOERR); + } - vec[0] = mhbasename(postproc); + vec[0] = "spost"; vec[vecp++] = "-dist"; vec[vecp++] = drft; vec[vecp] = NULL; - for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) - sleep(5); - switch (child_id) { - case NOTOK: - admonish(NULL, "unable to fork");/* fall */ - case OK: - execvp(postproc, vec); - fprintf(stderr, "unable to exec "); - perror(postproc); - _exit(1); - - default: - done(pidXwait(child_id, postproc)); - } - + execvp(*vec, vec); + fprintf(stderr, "unable to exec "); + perror(*vec); + _exit(EX_OSERR); return 0; /* dead code to satisfy the compiler */ } /* very similar to routine in replsbr.c */ -#define SBUFSIZ 256 - -static int outputlinelen = OUTPUTLINELEN; - static struct format *fmt; static int ncomps = 0; -static char **compbuffers = 0; -static struct comp **used_buf = 0; static int dat[5]; @@ -164,123 +154,104 @@ static char *addrcomps[] = { static void rcvdistout(FILE *inb, char *form, char *addrs) { - register int char_read = 0, format_len, i, state; - register char *tmpbuf, **nxtbuf, **ap; - char *cp, *scanl, name[NAMESZ]; - register struct comp *cptr, **savecomp; + int char_read = 0, format_len, i; + enum state state; + struct field f = {{0}}; + char **ap; + char *cp, *scanl; + struct comp *cptr; FILE *out; - if (!(out = fopen(drft, "w"))) - adios(drft, "unable to create"); + if (!(out = fopen(drft, "w"))) { + adios(EX_CANTCREAT, drft, "unable to create"); + } /* get new format string */ - cp = new_fs(form ? form : rcvdistcomps, NULL, NULL); + cp = new_fs(form ? form : rcvdistcomps, NULL); format_len = strlen(cp); ncomps = fmt_compile(cp, &fmt) + 1; - if (!(nxtbuf = compbuffers = - (char **) calloc((size_t) ncomps, sizeof(char *)))) - adios(NULL, "unable to allocate component buffers"); - if (!(savecomp = used_buf = - (struct comp **) calloc((size_t) (ncomps + 1), - sizeof(struct comp *)))) - adios(NULL, "unable to allocate component buffer stack"); - savecomp += ncomps + 1; - *--savecomp = 0; - - for (i = ncomps; i--;) - *nxtbuf++ = mh_xmalloc(SBUFSIZ); - nxtbuf = compbuffers; - tmpbuf = *nxtbuf++; for (ap = addrcomps; *ap; ap++) { FINDCOMP(cptr, *ap); - if (cptr) + if (cptr) { cptr->c_type |= CT_ADDR; + } } FINDCOMP(cptr, "addresses"); - if (cptr) + if (cptr) { cptr->c_text = addrs; - - for (state = FLD;;) { - switch (state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb)) { - case FLD: - case FLDPLUS: - if ((cptr = wantcomp[CHASH(name)])) - do { - if (!mh_strcasecmp(name, cptr->c_name)) { - char_read += msg_count; - if (!cptr->c_text) { - cptr->c_text = tmpbuf; - *--savecomp = cptr; - tmpbuf = *nxtbuf++; + } + state = FLD2; + while (1) { + state = m_getfld2(state, &f, inb); + switch (state) { + case FLD2: + if ((cptr = wantcomp[CHASH(f.name)])) { + do { + if (mh_strcasecmp(f.name, cptr->c_name)!=0) { + continue; + } + char_read += strlen(f.value); + if (!cptr->c_text) { + cptr->c_text = mh_xstrdup(f.value); + } else { + cp = cptr->c_text; + i = strlen(cp) - 1; + if (cp[i] == '\n') { + if (cptr->c_type & CT_ADDR) { + cp[i] = 0; + cp = add(",\n\t", cp); } else { - i = strlen(cp = cptr->c_text) - 1; - if (cp[i] == '\n') { - if (cptr->c_type & CT_ADDR) { - cp[i] = 0; - cp = add(",\n\t", cp); - } else - cp = add("\t", cp); - } - cptr->c_text = add(tmpbuf, cp); - } - while (state == FLDPLUS) { - state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb); - cptr->c_text = add(tmpbuf, cptr->c_text); - char_read += msg_count; + cp = add("\t", cp); } - break; } - } while ((cptr = cptr->c_next)); - - while (state == FLDPLUS) - state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb); - break; + cptr->c_text = add(f.value, cp); + } + break; + } while ((cptr = cptr->c_next)); + } + break; - case LENERR: - case FMTERR: - case BODY: - case FILEEOF: - goto finished; + case LENERR2: + case FMTERR2: + case IOERR2: + case BODY2: + case FILEEOF2: + goto finished; - default: - adios(NULL, "m_getfld() returned %d", state); + default: + adios(EX_SOFTWARE, NULL, "m_getfld() returned %d", state); } } finished: ; i = format_len + char_read + 256; - scanl = mh_xmalloc((size_t) i + 2); + scanl = mh_xcalloc(i + 2, sizeof(char)); dat[0] = dat[1] = dat[2] = dat[4] = 0; - dat[3] = outputlinelen; + dat[3] = OUTPUTLINELEN; fmt_scan(fmt, scanl, i, dat); fputs(scanl, out); - if (ferror(out)) - adios(drft, "error writing"); + if (ferror(out)) { + adios(EX_IOERR, drft, "error writing"); + } fclose(out); - free(scanl); - for (nxtbuf = compbuffers, i = ncomps; (cptr = *savecomp++); - nxtbuf++, i--) - free(cptr->c_text); - while (i-- > 0) - free(*nxtbuf++); - free((char *) compbuffers); - free((char *) used_buf); + mh_free0(&scanl); } -static void -unlink_done(int status) +void +unlink_done() { - if (backup[0]) + if (*backup) { unlink(backup); - if (drft[0]) + } + if (*drft) { unlink(drft); - if (tmpfil[0]) + } + if (*tmpfil) { unlink(tmpfil); - - exit(status ? RCV_MBX : RCV_MOK); + } }