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