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