|
|
1.1 ! root 1: /* rcvdist.c - a rcvmail program to distribute messages */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include "../h/formatsbr.h" ! 5: #include "../h/rcvmail.h" ! 6: #include "../zotnet/tws.h" ! 7: #include <stdio.h> ! 8: ! 9: /* */ ! 10: ! 11: static struct swit switches[] = { ! 12: #define FORMSW 0 ! 13: "form formfile", 4, ! 14: ! 15: #define HELPSW 1 ! 16: "help", 4, ! 17: ! 18: NULL, NULL ! 19: }; ! 20: ! 21: /* */ ! 22: ! 23: static char backup[BUFSIZ] = ""; ! 24: static char drft[BUFSIZ] = ""; ! 25: static char tmpfil[BUFSIZ] = ""; ! 26: ! 27: static void rcvdistout(), rcvdistdone(); ! 28: ! 29: /* */ ! 30: ! 31: /* ARGSUSED */ ! 32: ! 33: main(argc, argv) ! 34: int argc; ! 35: char **argv; ! 36: { ! 37: int i, ! 38: child_id, ! 39: vecp = 1; ! 40: char *addrs = NULL, ! 41: *cp, ! 42: *form = NULL, ! 43: buf[100], ! 44: **ap, ! 45: **argp, ! 46: *arguments[MAXARGS], ! 47: *vec[MAXARGS]; ! 48: register FILE * fp; ! 49: ! 50: invo_name = r1bindex (argv[0], '/'); ! 51: mts_init (invo_name); ! 52: if ((cp = m_find (invo_name)) != NULL) { ! 53: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 54: ap = copyip (ap, arguments); ! 55: } ! 56: else ! 57: ap = arguments; ! 58: (void) copyip (argv + 1, ap); ! 59: argp = arguments; ! 60: ! 61: /* */ ! 62: ! 63: while (cp = *argp++) { ! 64: if (*cp == '-') ! 65: switch (smatch (++cp, switches)) { ! 66: case AMBIGSW: ! 67: ambigsw (cp, switches); ! 68: rcvdistdone (1); ! 69: case UNKWNSW: ! 70: vec[vecp++] = --cp; ! 71: continue; ! 72: case HELPSW: ! 73: (void) sprintf (buf, ! 74: "%s [switches] [switches for postproc] address ...", ! 75: invo_name); ! 76: help (buf, switches); ! 77: rcvdistdone (1); ! 78: ! 79: case FORMSW: ! 80: if (!(form = *argp++) || *form == '-') ! 81: adios (NULLCP, "missing argument to %s", argp[-2]); ! 82: continue; ! 83: } ! 84: addrs = addrs ? add (cp, add (", ", addrs)) : getcpy (cp); ! 85: } ! 86: ! 87: /* */ ! 88: ! 89: if (addrs == NULL) ! 90: adios (NULLCP, "usage: %s [switches] [switches for postproc] address ...", ! 91: invo_name); ! 92: ! 93: (void) umask (~m_gmprot ()); ! 94: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 95: if ((fp = fopen (tmpfil, "w+")) == NULL) ! 96: adios (tmpfil, "unable to create"); ! 97: (void) cpydata (fileno (stdin), fileno (fp), "message", tmpfil); ! 98: (void) fseek (fp, 0L, 0); ! 99: (void) strcpy (drft, m_tmpfil (invo_name)); ! 100: rcvdistout (fp, form, addrs); ! 101: (void) fclose (fp); ! 102: ! 103: if (distout (drft, tmpfil, backup) == NOTOK) ! 104: rcvdistdone (1); ! 105: ! 106: vec[0] = r1bindex (postproc, '/'); ! 107: vec[vecp++] = "-dist"; ! 108: vec[vecp++] = drft; ! 109: vec[vecp] = NULL; ! 110: ! 111: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) ! 112: sleep (5); ! 113: switch (child_id) { ! 114: case NOTOK: ! 115: admonish (NULLCP, "unable to fork");/* fall */ ! 116: case OK: ! 117: execvp (postproc, vec); ! 118: fprintf (stderr, "unable to exec "); ! 119: perror (postproc); ! 120: _exit (1); ! 121: ! 122: default: ! 123: rcvdistdone (pidXwait (child_id, postproc)); ! 124: } ! 125: /* NOTREACHED */ ! 126: } ! 127: ! 128: /* */ ! 129: ! 130: /* very similar to routine in replsbr.c */ ! 131: ! 132: #define SBUFSIZ 256 ! 133: ! 134: static int outputlinelen = OUTPUTLINELEN; ! 135: ! 136: static struct format *fmt; ! 137: ! 138: static int ncomps = 0; ! 139: static char **compbuffers = 0; ! 140: static struct comp **used_buf = 0; ! 141: ! 142: static int dat[4]; ! 143: ! 144: ! 145: static void ! 146: rcvdistout(inb, form, addrs) ! 147: register FILE *inb; ! 148: char *form, *addrs; ! 149: { ! 150: register int char_read = 0, ! 151: format_len, ! 152: i, ! 153: state; ! 154: register char *tmpbuf, ! 155: **nxtbuf; ! 156: char *cp, ! 157: *scanl, ! 158: name[NAMESZ]; ! 159: register struct comp *cptr, ! 160: **savecomp; ! 161: FILE *out; ! 162: ! 163: if ((out = fopen (drft, "w")) == NULL) ! 164: adios (drft, "unable to create"); ! 165: ! 166: cp = new_fs (form ? form : rcvdistcomps, NULLCP, NULLCP); ! 167: format_len = strlen (cp); ! 168: ncomps = fmt_compile (cp, &fmt) + 1; ! 169: nxtbuf = compbuffers = (char **) calloc ((unsigned) ncomps, ! 170: sizeof (char *)); ! 171: if (nxtbuf == NULL) ! 172: adios (NULLCP, "unable to allocate component buffers"); ! 173: used_buf = (struct comp **) calloc ((unsigned) (ncomps + 1), ! 174: sizeof (struct comp *)); ! 175: if (used_buf == NULL) ! 176: adios (NULLCP, "unable to allocate component buffer stack"); ! 177: used_buf += ncomps + 1; ! 178: *--used_buf = 0; ! 179: for (i = ncomps; i--;) ! 180: if ((*nxtbuf++ = malloc (SBUFSIZ)) == NULL) ! 181: adios (NULLCP, "unable to allocate component buffer"); ! 182: ! 183: nxtbuf = compbuffers; ! 184: savecomp = used_buf; ! 185: tmpbuf = *nxtbuf++; ! 186: ! 187: FINDCOMP (cptr, "addresses"); ! 188: if (cptr) ! 189: cptr -> c_text = addrs; ! 190: ! 191: for (state = FLD;;) { ! 192: switch (state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb)) { ! 193: case FLD: ! 194: case FLDPLUS: ! 195: if (cptr = wantcomp[CHASH (name)]) ! 196: do { ! 197: if (uleq (name, cptr -> c_name)) { ! 198: char_read += msg_count; ! 199: if (!cptr -> c_text) { ! 200: cptr -> c_text = tmpbuf; ! 201: *--savecomp = cptr; ! 202: tmpbuf = *nxtbuf++; ! 203: } ! 204: else { ! 205: i = strlen (cp = cptr -> c_text) - 1; ! 206: if (cp[i] == '\n') ! 207: if (cptr -> c_flags) { ! 208: cp[i] = NULL; ! 209: cp = add (",\n\t", cp); ! 210: } ! 211: else ! 212: cp = add ("\t", cp); ! 213: cptr -> c_text = add (tmpbuf, cp); ! 214: } ! 215: break; ! 216: } ! 217: } ! 218: while (cptr = cptr -> c_next); ! 219: ! 220: while (state == FLDPLUS) { ! 221: state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb); ! 222: cptr -> c_text = add (tmpbuf, cptr -> c_text); ! 223: char_read += msg_count; ! 224: } ! 225: break; ! 226: ! 227: case LENERR: ! 228: case FMTERR: ! 229: case BODY: ! 230: case FILEEOF: ! 231: goto finished; ! 232: ! 233: default: ! 234: adios (NULLCP, "m_getfld() returned %d", state); ! 235: } ! 236: } ! 237: finished: ; ! 238: ! 239: i = format_len + char_read + 256; ! 240: scanl = malloc ((unsigned) i + 2); ! 241: dat[0] = dat[1] = dat[2] = 0; ! 242: dat[3] = outputlinelen; ! 243: (void) fmtscan (fmt, scanl, i, dat); ! 244: fputs (scanl, out); ! 245: ! 246: if (ferror (out)) ! 247: adios (drft, "error writing"); ! 248: (void) fclose (out); ! 249: ! 250: free (scanl); ! 251: while (cptr = *savecomp++) ! 252: free (cptr -> c_text); ! 253: free (tmpbuf); ! 254: free ((char *) compbuffers); ! 255: free ((char *) used_buf); ! 256: } ! 257: ! 258: /* */ ! 259: ! 260: static void ! 261: rcvdistdone(status) ! 262: register int status; ! 263: { ! 264: if (backup[0]) ! 265: (void) unlink (backup); ! 266: if (drft[0]) ! 267: (void) unlink (drft); ! 268: if (tmpfil[0]) ! 269: (void) unlink (tmpfil); ! 270: ! 271: exit (status ? RCV_MBX : RCV_MOK); ! 272: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.