|
|
1.1 ! root 1: /* forw.c - forward messages */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include "../h/formatsbr.h" ! 5: #include "../zotnet/tws.h" ! 6: #include <stdio.h> ! 7: #include <sys/types.h> ! 8: #include <sys/stat.h> ! 9: ! 10: ! 11: #define IFMT "digest-issue-%s" ! 12: #define VFMT "digest-volume-%s" ! 13: ! 14: /* */ ! 15: ! 16: static struct swit switches[] = { ! 17: #define ANNOSW 0 ! 18: "annotate", 0, ! 19: #define NANNOSW 1 ! 20: "noannotate", 0, ! 21: ! 22: #define DFOLDSW 2 ! 23: "draftfolder +folder", 0, ! 24: #define DMSGSW 3 ! 25: "draftmessage msg", 0, ! 26: #define NDFLDSW 4 ! 27: "nodraftfolder", 0, ! 28: ! 29: #define EDITRSW 5 ! 30: "editor editor", 0, ! 31: #define NEDITSW 6 ! 32: "noedit", 0, ! 33: ! 34: #define FILTSW 7 ! 35: "filter filterfile", 0, ! 36: #define FORMSW 8 ! 37: "form formfile", 0, ! 38: ! 39: #define FRMTSW 9 ! 40: "format", 5, ! 41: #define NFRMTSW 10 ! 42: "noformat", 7, ! 43: ! 44: #define INPLSW 11 ! 45: "inplace", 0, ! 46: #define NINPLSW 12 ! 47: "noinplace", 0, ! 48: ! 49: #define DGSTSW 13 ! 50: "digest list", 0, ! 51: #define ISSUESW 14 ! 52: "issue number", 0, ! 53: #define VOLUMSW 15 ! 54: "volume number", 0, ! 55: ! 56: #define WHATSW 16 ! 57: "whatnowproc program", 0, ! 58: #define NWHATSW 17 ! 59: "nowhatnowproc", 0, ! 60: ! 61: #define DASHSW 18 ! 62: "dashmunging", 4, ! 63: #define NDASHSW 19 ! 64: "nodashmunging", 6, ! 65: ! 66: #define HELPSW 20 ! 67: "help", 4, ! 68: ! 69: #define FILESW 21 ! 70: "file file", -4, /* interface from msh */ ! 71: ! 72: #ifdef MHE ! 73: #define BILDSW 22 ! 74: "build", -5, /* interface from mhe */ ! 75: #endif MHE ! 76: ! 77: NULL, NULL ! 78: }; ! 79: ! 80: /* */ ! 81: ! 82: static struct swit aqrnl[] = { ! 83: #define NOSW 0 ! 84: "quit", 0, ! 85: #define YESW 1 ! 86: "replace", 0, ! 87: #define LISTDSW 2 ! 88: "list", 0, ! 89: #define REFILSW 3 ! 90: "refile +folder", 0, ! 91: #define NEWSW 4 ! 92: "new", 0, ! 93: ! 94: NULL, NULL ! 95: }; ! 96: ! 97: ! 98: static struct swit aqrl[] = { ! 99: "quit", 0, ! 100: "replace", 0, ! 101: "list", 0, ! 102: "refile +folder", 0, ! 103: ! 104: NULL, NULL ! 105: }; ! 106: ! 107: /* */ ! 108: ! 109: static char drft[BUFSIZ]; ! 110: ! 111: static char delim3[] = ! 112: "\n------------------------------------------------------------\n\n"; ! 113: static char delim4[] = "\n------------------------------\n\n"; ! 114: ! 115: ! 116: static struct msgs *mp = NULL; /* used a lot */ ! 117: ! 118: ! 119: long lseek(), time(); ! 120: ! 121: static void mhl_draft(), copy_draft(); ! 122: static int build_form(); ! 123: ! 124: /* */ ! 125: ! 126: /* ARGSUSED */ ! 127: ! 128: main(argc, argv) ! 129: int argc; ! 130: char *argv[]; ! 131: { ! 132: int msgp = 0, ! 133: anot = 0, ! 134: inplace = 0, ! 135: issue = 0, ! 136: volume = 0, ! 137: dashflg = 1, ! 138: #ifdef MHE ! 139: buildsw = 0, ! 140: #endif MHE ! 141: nedit = 0, ! 142: nwhat = 0, ! 143: i, ! 144: in, ! 145: out, ! 146: isdf = 0, ! 147: msgnum; ! 148: char *cp, ! 149: *cwd, ! 150: *maildir, ! 151: *dfolder = NULL, ! 152: *dmsg = NULL, ! 153: *digest = NULL, ! 154: *ed = NULL, ! 155: *file = NULL, ! 156: *filter = NULL, ! 157: *folder = NULL, ! 158: *form = NULL, ! 159: buf[100], ! 160: value[10], ! 161: **ap, ! 162: **argp, ! 163: *arguments[MAXARGS], ! 164: *msgs[MAXARGS]; ! 165: struct stat st; ! 166: ! 167: invo_name = r1bindex (argv[0], '/'); ! 168: if ((cp = m_find (invo_name)) != NULL) { ! 169: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 170: ap = copyip (ap, arguments); ! 171: } ! 172: else ! 173: ap = arguments; ! 174: (void) copyip (argv + 1, ap); ! 175: argp = arguments; ! 176: ! 177: /* */ ! 178: ! 179: while (cp = *argp++) { ! 180: if (*cp == '-') ! 181: switch (smatch (++cp, switches)) { ! 182: case AMBIGSW: ! 183: ambigsw (cp, switches); ! 184: done (1); ! 185: case UNKWNSW: ! 186: adios (NULLCP, "-%s unknown", cp); ! 187: case HELPSW: ! 188: (void) sprintf (buf, "%s [+folder] [msgs] [switches]", ! 189: invo_name); ! 190: help (buf, switches); ! 191: done (1); ! 192: ! 193: case ANNOSW: ! 194: anot++; ! 195: continue; ! 196: case NANNOSW: ! 197: anot = 0; ! 198: continue; ! 199: ! 200: case EDITRSW: ! 201: if (!(ed = *argp++) || *ed == '-') ! 202: adios (NULLCP, "missing argument to %s", argp[-2]); ! 203: nedit = 0; ! 204: continue; ! 205: case NEDITSW: ! 206: nedit++; ! 207: continue; ! 208: ! 209: case WHATSW: ! 210: if (!(whatnowproc = *argp++) || *whatnowproc == '-') ! 211: adios (NULLCP, "missing argument to %s", argp[-2]); ! 212: nwhat = 0; ! 213: continue; ! 214: #ifdef MHE ! 215: case BILDSW: ! 216: buildsw++; /* fall... */ ! 217: #endif MHE ! 218: case NWHATSW: ! 219: nwhat++; ! 220: continue; ! 221: ! 222: case FILESW: ! 223: if (file) ! 224: adios (NULLCP, "only one file at a time!"); ! 225: if (!(cp = *argp++) || *cp == '-') ! 226: adios (NULLCP, "missing argument to %s", argp[-2]); ! 227: file = path (cp, TFILE); ! 228: continue; ! 229: case FILTSW: ! 230: if (!(cp = *argp++) || *cp == '-') ! 231: adios (NULLCP, "missing argument to %s", argp[-2]); ! 232: filter = getcpy (libpath (cp)); ! 233: continue; ! 234: case FORMSW: ! 235: if (!(form = *argp++) || *form == '-') ! 236: adios (NULLCP, "missing argument to %s", argp[-2]); ! 237: continue; ! 238: ! 239: case FRMTSW: ! 240: filter = getcpy (libpath (mhlforward)); ! 241: continue; ! 242: case NFRMTSW: ! 243: filter = NULL; ! 244: continue; ! 245: ! 246: case INPLSW: ! 247: inplace++; ! 248: continue; ! 249: case NINPLSW: ! 250: inplace = 0; ! 251: continue; ! 252: ! 253: case DGSTSW: ! 254: if (!(digest = *argp++) || *digest == '-') ! 255: adios (NULLCP, "missing argument to %s", argp[-2]); ! 256: continue; ! 257: case ISSUESW: ! 258: if (!(cp = *argp++) || *cp == '-') ! 259: adios (NULLCP, "missing argument to %s", argp[-2]); ! 260: if ((issue = atoi (cp)) < 1) ! 261: adios (NULLCP, "bad argument %s %s", argp[-2], cp); ! 262: continue; ! 263: case VOLUMSW: ! 264: if (!(cp = *argp++) || *cp == '-') ! 265: adios (NULLCP, "missing argument to %s", argp[-2]); ! 266: if ((volume = atoi (cp)) < 1) ! 267: adios (NULLCP, "bad argument %s %s", argp[-2], cp); ! 268: continue; ! 269: ! 270: case DFOLDSW: ! 271: if (dfolder) ! 272: adios (NULLCP, "only one draft folder at a time!"); ! 273: if (!(cp = *argp++) || *cp == '-') ! 274: adios (NULLCP, "missing argument to %s", argp[-2]); ! 275: dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, ! 276: *cp != '@' ? TFOLDER : TSUBCWF); ! 277: continue; ! 278: case DMSGSW: ! 279: if (dmsg) ! 280: adios (NULLCP, "only one draft message at a time!"); ! 281: if (!(dmsg = *argp++) || *dmsg == '-') ! 282: adios (NULLCP, "missing argument to %s", argp[-2]); ! 283: continue; ! 284: case NDFLDSW: ! 285: dfolder = NULL; ! 286: isdf = NOTOK; ! 287: continue; ! 288: ! 289: case DASHSW: ! 290: dashflg++; ! 291: continue; ! 292: case NDASHSW: ! 293: dashflg = 0; ! 294: continue; ! 295: } ! 296: if (*cp == '+' || *cp == '@') { ! 297: if (folder) ! 298: adios (NULLCP, "only one folder at a time!"); ! 299: else ! 300: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 301: } ! 302: else ! 303: msgs[msgp++] = cp; ! 304: } ! 305: ! 306: /* */ ! 307: ! 308: cwd = getcpy (pwd ()); ! 309: ! 310: if (!m_find ("path")) ! 311: free (path ("./", TFOLDER)); ! 312: if (file && (msgp || folder)) ! 313: adios (NULLCP, "can't mix files and folders/msgs"); ! 314: ! 315: try_it_again: ; ! 316: #ifndef MHE ! 317: (void) strcpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf)); ! 318: if (stat (drft, &st) != NOTOK) ! 319: #else MHE ! 320: (void) strcpy (drft, buildsw ? m_maildir ("draft") ! 321: : m_draft (dfolder, NULLCP, NOUSE, &isdf)); ! 322: if (!buildsw && stat (drft, &st) != NOTOK) ! 323: #endif MHE ! 324: { ! 325: printf ("Draft \"%s\" exists (%ld bytes).", drft, st.st_size); ! 326: for (i = LISTDSW; i != YESW;) { ! 327: if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl))) ! 328: done (1); ! 329: switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) { ! 330: case NOSW: ! 331: done (0); ! 332: case NEWSW: ! 333: dmsg = NULL; ! 334: goto try_it_again; ! 335: case YESW: ! 336: break; ! 337: case LISTDSW: ! 338: (void) showfile (++argp, drft); ! 339: break; ! 340: case REFILSW: ! 341: if (refile (++argp, drft) == 0) ! 342: i = YESW; ! 343: break; ! 344: default: ! 345: advise (NULLCP, "say what?"); ! 346: break; ! 347: } ! 348: } ! 349: } ! 350: ! 351: /* */ ! 352: ! 353: if (file) { ! 354: anot = 0; ! 355: goto go_to_it; ! 356: } ! 357: ! 358: if (!msgp) ! 359: msgs[msgp++] = "cur"; ! 360: if (!folder) ! 361: folder = m_getfolder (); ! 362: maildir = m_maildir (folder); ! 363: ! 364: if (chdir (maildir) == NOTOK) ! 365: adios (maildir, "unable to change directory to"); ! 366: if (!(mp = m_gmsg (folder))) ! 367: adios (NULLCP, "unable to read folder %s", folder); ! 368: if (mp -> hghmsg == 0) ! 369: adios (NULLCP, "no messages in %s", folder); ! 370: ! 371: for (msgnum = 0; msgnum < msgp; msgnum++) ! 372: if (!m_convert (mp, msgs[msgnum])) ! 373: done (1); ! 374: m_setseq (mp); ! 375: ! 376: /* */ ! 377: ! 378: go_to_it: ; ! 379: if (filter && access (filter, 04) == NOTOK) ! 380: adios (filter, "unable to read"); ! 381: ! 382: if (digest) { ! 383: if (issue == 0) { ! 384: (void) sprintf (buf, IFMT, digest); ! 385: if (volume == 0 ! 386: && (cp = m_find (buf)) ! 387: && ((issue = atoi (cp)) < 0)) ! 388: issue = 0; ! 389: issue++; ! 390: } ! 391: if (volume == 0) ! 392: (void) sprintf (buf, VFMT, digest); ! 393: if ((cp = m_find (buf)) == NULL || (volume = atoi (cp)) <= 0) ! 394: volume = 1; ! 395: if (!form) ! 396: form = digestcomps; ! 397: in = build_form (form, digest, volume, issue); ! 398: } ! 399: else ! 400: if (form) { ! 401: if ((in = open (libpath (form), 0)) == NOTOK) ! 402: adios (form, "unable to open form file"); ! 403: } ! 404: else { ! 405: if ((in = open (libpath (forwcomps), 0)) == NOTOK) ! 406: adios (forwcomps, "unable to open default components file"); ! 407: form = forwcomps; ! 408: } ! 409: ! 410: if ((out = creat (drft, m_gmprot ())) == NOTOK) ! 411: adios (drft, "unable to create"); ! 412: ! 413: cpydata (in, out, form, drft); ! 414: (void) close (in); ! 415: ! 416: /* */ ! 417: ! 418: if (file) { ! 419: if ((in = open (file, 0)) == NOTOK) ! 420: adios (file, "unable to open"); ! 421: cpydata (in, out, file, drft); ! 422: (void) close (in); ! 423: (void) close (out); ! 424: goto edit_it; ! 425: } ! 426: ! 427: if (filter) ! 428: mhl_draft (out, digest, drft, filter, dashflg); ! 429: else ! 430: copy_draft (out, digest, drft); ! 431: (void) close (out); ! 432: ! 433: if (digest) { ! 434: (void) sprintf (buf, IFMT, digest); ! 435: (void) sprintf (value, "%d", issue); ! 436: m_replace (buf, getcpy (value)); ! 437: (void) sprintf (buf, VFMT, digest); ! 438: (void) sprintf (value, "%d", volume); ! 439: m_replace (buf, getcpy (value)); ! 440: } ! 441: ! 442: m_replace (pfolder, folder); ! 443: if (mp -> lowsel != mp -> curmsg) ! 444: m_setcur (mp, mp -> lowsel); ! 445: m_sync (mp); ! 446: m_update (); ! 447: ! 448: edit_it: ; ! 449: if (nwhat) ! 450: done (0); ! 451: (void) m_whatnow (ed, nedit, NOUSE, drft, NULLCP, 0, mp, ! 452: anot ? "Forwarded" : NULLCP, inplace, cwd); ! 453: done (1); ! 454: } ! 455: ! 456: /* */ ! 457: ! 458: static void ! 459: mhl_draft(out, digest, file, filter, dashflg) ! 460: int out; ! 461: register char *digest, *file, *filter; ! 462: int dashflg; ! 463: { ! 464: int i, ! 465: child_id, ! 466: msgnum, ! 467: pd[2]; ! 468: char *vec[MAXARGS]; ! 469: ! 470: if (pipe (pd) == NOTOK) ! 471: adios ("pipe", "unable to create"); ! 472: ! 473: vec[0] = r1bindex (mhlproc, '/'); ! 474: ! 475: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) ! 476: sleep (5); ! 477: switch (child_id) { ! 478: case NOTOK: ! 479: adios ("fork", "unable to"); ! 480: ! 481: case OK: ! 482: (void) close (pd[0]); ! 483: (void) dup2 (pd[1], 1); ! 484: (void) close (pd[1]); ! 485: ! 486: i = 1; ! 487: vec[i++] = "-forwall"; ! 488: vec[i++] = "-form"; ! 489: vec[i++] = filter; ! 490: if (digest) { ! 491: vec[i++] = "-digest"; ! 492: vec[i++] = digest; ! 493: } ! 494: if (dashflg) ! 495: vec[i++] = "-dashmunging"; ! 496: else ! 497: vec[i++] = "-nodashmunging"; ! 498: if (mp -> numsel >= MAXARGS - i) ! 499: adios (NULLCP, "more than %d messages for %s exec", ! 500: vec[0], MAXARGS - i); ! 501: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 502: if (mp -> msgstats[msgnum] & SELECTED) ! 503: vec[i++] = getcpy (m_name (msgnum)); ! 504: vec[i] = NULL; ! 505: ! 506: execvp (mhlproc, vec); ! 507: fprintf (stderr, "unable to exec "); ! 508: perror (mhlproc); ! 509: _exit (-1); ! 510: ! 511: default: ! 512: (void) close (pd[1]); ! 513: cpydata (pd[0], out, vec[0], file); ! 514: (void) close (pd[0]); ! 515: (void) pidXwait (child_id, mhlproc); ! 516: break; ! 517: } ! 518: } ! 519: ! 520: /* */ ! 521: ! 522: static void ! 523: copy_draft(out, digest, file) ! 524: int out; ! 525: register char *digest, *file; ! 526: { ! 527: int fd,i, ! 528: msgcnt, ! 529: msgnum; ! 530: register char *bp, ! 531: *msgnam; ! 532: char buffer[BUFSIZ]; ! 533: ! 534: msgcnt = 1; ! 535: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 536: if (mp -> msgstats[msgnum] & SELECTED) { ! 537: if (digest) ! 538: (void) strcpy (buffer, ! 539: msgnum == mp -> lowsel ? delim3 : delim4); ! 540: else { ! 541: (void) strcpy (bp = buffer, "\n-------"), bp += strlen (bp); ! 542: if (msgnum == mp -> lowsel) ! 543: (void) sprintf (bp, " Forwarded Message%s", ! 544: mp -> numsel > 1 ? "s" : ""); ! 545: else ! 546: (void) sprintf (bp, " Message %d", msgcnt); ! 547: bp += strlen (bp); ! 548: (void) strcpy (bp, "\n\n"); ! 549: } ! 550: (void) write (out, buffer, strlen (buffer)); ! 551: ! 552: if ((fd = open (msgnam = m_name (msgnum), 0)) == NOTOK) { ! 553: admonish (msgnam, "unable to read message"); ! 554: continue; ! 555: } ! 556: cpydgst (fd, out, msgnam, file); ! 557: (void) close (fd); ! 558: ! 559: msgcnt++; ! 560: } ! 561: ! 562: if (digest) ! 563: (void) strcpy (buffer, delim4); ! 564: else ! 565: (void) sprintf (buffer, "\n------- End of Forwarded Message%s\n\n", ! 566: mp -> numsel > 1 ? "s" : ""); ! 567: (void) write (out, buffer, strlen (buffer)); ! 568: ! 569: if (digest) { ! 570: (void) sprintf (buffer, "End of %s Digest\n", digest); ! 571: i = strlen (buffer); ! 572: for (bp = buffer + i; i > 1; i--) ! 573: *bp++ = '*'; ! 574: *bp++ = '\n'; ! 575: *bp = NULL; ! 576: (void) write (out, buffer, strlen (buffer)); ! 577: } ! 578: } ! 579: ! 580: /* */ ! 581: ! 582: static int ! 583: build_form(form, digest, volume, issue) ! 584: register char *form, *digest; ! 585: int volume, issue; ! 586: { ! 587: int in; ! 588: int fmtsize; ! 589: register char *nfs; ! 590: char *line, ! 591: tmpfil[BUFSIZ]; ! 592: register FILE *tmp; ! 593: register struct comp *cptr; ! 594: struct format *fmt; ! 595: int dat[4]; ! 596: ! 597: nfs = new_fs (form, NULLCP, NULLCP); ! 598: fmtsize = strlen (nfs) + 256; ! 599: (void) fmt_compile (nfs, &fmt); ! 600: ! 601: FINDCOMP (cptr, "digest"); ! 602: if (cptr) ! 603: cptr->c_text = digest; ! 604: FINDCOMP (cptr, "date"); ! 605: if (cptr) ! 606: cptr->c_text = getcpy(dtimenow ()); ! 607: ! 608: dat[0] = issue; ! 609: dat[1] = volume; ! 610: dat[2] = 0; ! 611: dat[3] = fmtsize; ! 612: ! 613: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 614: if ((tmp = fopen (tmpfil, "w+")) == NULL) ! 615: adios (tmpfil, "unable to create"); ! 616: (void) unlink (tmpfil); ! 617: if ((in = dup (fileno (tmp))) == NOTOK) ! 618: adios ("dup", "unable to"); ! 619: ! 620: if ((line = malloc ((unsigned) fmtsize)) == NULLCP) ! 621: adios (NULLCP, "unable to allocate format line storage"); ! 622: (void) fmtscan (fmt, line, fmtsize, dat); ! 623: (void) fputs (line, tmp); ! 624: (void) free (line); ! 625: if (fclose (tmp)) ! 626: adios (tmpfil, "error writing"); ! 627: ! 628: (void) lseek (in, 0L, 0); ! 629: return in; ! 630: } ! 631: ! 632: /* ! 633: * XXX We need to force WhatNow() to be linked in to get around ! 634: * library order problems ! 635: */ ! 636: /* XXX don't bother if linking with the shared library */ ! 637: #ifndef SHARED ! 638: static void ! 639: kludge() ! 640: { ! 641: WhatNow(0, (char **)0); ! 642: } ! 643: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.