|
|
1.1 ! root 1: /* sendsbr.c - routines to help WhatNow/Send along */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include <setjmp.h> ! 5: #include <stdio.h> ! 6: #include <signal.h> ! 7: #include <sys/types.h> ! 8: #include <sys/stat.h> ! 9: ! 10: /* */ ! 11: ! 12: int debugsw = 0; /* global */ ! 13: int forwsw = 1; ! 14: int inplace = 0; ! 15: int pushsw = 0; ! 16: int unique = 0; ! 17: ! 18: char *altmsg = NULL; /* .. */ ! 19: char *annotext = NULL; ! 20: char *distfile = NULL; ! 21: ! 22: ! 23: static int armed = 0; ! 24: static jmp_buf env; ! 25: ! 26: ! 27: char *getusr (); ! 28: long lseek (); ! 29: ! 30: /* */ ! 31: ! 32: int sendsbr (vec, vecp, drft, st) ! 33: register char **vec, ! 34: *drft; ! 35: int vecp; ! 36: register struct stat *st; ! 37: { ! 38: int status; ! 39: ! 40: armed++; ! 41: switch (setjmp (env)) { ! 42: case OK: ! 43: status = sendaux (vec, vecp, drft, st) ? NOTOK : OK; ! 44: break; ! 45: ! 46: default: ! 47: status = DONE; ! 48: break; ! 49: } ! 50: armed = 0; ! 51: if (distfile) ! 52: (void) unlink (distfile); ! 53: ! 54: return status; ! 55: } ! 56: ! 57: /* */ ! 58: ! 59: int sendaux (vec, vecp, drft, st) ! 60: register char **vec, ! 61: *drft; ! 62: int vecp; ! 63: register struct stat *st; ! 64: { ! 65: int child_id, ! 66: i, ! 67: status, ! 68: fd, ! 69: fd2; ! 70: char backup[BUFSIZ], ! 71: buf[BUFSIZ], ! 72: file[BUFSIZ]; ! 73: ! 74: fd = pushsw ? tmp_fd () : NOTOK; ! 75: fd2 = NOTOK; ! 76: ! 77: if (pushsw && unique) { ! 78: if (rename (drft, strcpy (file, m_scratch (drft, invo_name))) ! 79: == NOTOK) ! 80: adios (file, "unable to rename %s to", drft); ! 81: drft = file; ! 82: } ! 83: vec[vecp++] = drft; ! 84: if (annotext) ! 85: if ((fd2 = tmp_fd ()) != NOTOK) { ! 86: vec[vecp++] = "-idanno"; ! 87: (void) sprintf (buf, "%d", fd2); ! 88: vec[vecp++] = buf; ! 89: } ! 90: else ! 91: admonish (NULLCP, "unable to create file for annotation list"); ! 92: if (distfile && distout (drft, distfile, backup) == NOTOK) ! 93: done (1); ! 94: vec[vecp] = NULL; ! 95: ! 96: for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++) ! 97: sleep (5); ! 98: switch (child_id) { ! 99: case NOTOK: /* oops */ ! 100: adios ("fork", "unable to"); ! 101: ! 102: case OK: /* send it */ ! 103: if (fd != NOTOK) { ! 104: (void) dup2 (fd, fileno (stdout)); ! 105: (void) dup2 (fd, fileno (stderr)); ! 106: (void) close (fd); ! 107: } ! 108: execvp (postproc, vec); ! 109: fprintf (stderr, "unable to exec "); ! 110: perror (postproc); ! 111: _exit (-1); ! 112: ! 113: default: /* wait for it */ ! 114: if ((status = pidwait (child_id, NOTOK)) == 0) { ! 115: if (annotext && fd2 != NOTOK) ! 116: anno (fd2, st); ! 117: if (rename (drft, strcpy (buf, m_backup (drft))) == NOTOK) ! 118: advise (buf, "unable to rename %s to", drft); ! 119: } ! 120: else { ! 121: if (fd != NOTOK) { ! 122: alert (drft, fd); ! 123: (void) close (fd); ! 124: } ! 125: else ! 126: advise (NULLCP, "message not delivered to anyone"); ! 127: if (fd2 != NOTOK) ! 128: (void) close (fd2); ! 129: if (distfile) { ! 130: (void) unlink (drft); ! 131: if (rename (backup, drft) == NOTOK) ! 132: advise (drft, "unable to rename %s to", backup); ! 133: } ! 134: } ! 135: break; ! 136: } ! 137: ! 138: return status; ! 139: } ! 140: ! 141: /* */ ! 142: ! 143: static alert (file, out) ! 144: register char *file; ! 145: int out; ! 146: { ! 147: int child_id, ! 148: i, ! 149: in; ! 150: char buf[BUFSIZ]; ! 151: ! 152: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) ! 153: sleep (5); ! 154: switch (child_id) { ! 155: case NOTOK: /* oops */ ! 156: advise ("fork", "unable to"); ! 157: ! 158: case OK: /* send it */ ! 159: (void) signal (SIGHUP, SIG_IGN); ! 160: (void) signal (SIGINT, SIG_IGN); ! 161: (void) signal (SIGQUIT, SIG_IGN); ! 162: (void) signal (SIGTERM, SIG_IGN); ! 163: if (forwsw) ! 164: if ((in = open (file, 0)) == NOTOK) ! 165: admonish (file, "unable to re-open"); ! 166: else { ! 167: (void) lseek (out, 0L, 2); ! 168: (void) strcpy (buf, "\nMessage not delivered to anyone.\n"); ! 169: (void) write (out, buf, strlen (buf)); ! 170: (void) strcpy (buf, "\n------- Unsent Draft\n\n"); ! 171: (void) write (out, buf, strlen (buf)); ! 172: cpydgst (in, out, file, "temporary file"); ! 173: (void) close (in); ! 174: (void) strcpy (buf, "\n------- End of Unsent Draft\n"); ! 175: (void) write (out, buf, strlen (buf)); ! 176: if (rename (file, strcpy (buf, m_backup (file))) == NOTOK) ! 177: admonish (buf, "unable to rename %s to", file); ! 178: } ! 179: (void) lseek (out, 0L, 0); ! 180: (void) dup2 (out, fileno (stdin)); ! 181: (void) close (out); ! 182: (void) sprintf (buf, "send failed on %s", ! 183: forwsw ? "enclosed draft" : file); ! 184: ! 185: execlp (mailproc, r1bindex (mailproc, '/'), getusr (), ! 186: "-subject", buf, NULLCP); ! 187: fprintf (stderr, "unable to exec "); ! 188: perror (mailproc); ! 189: _exit (-1); ! 190: ! 191: default: /* no waiting... */ ! 192: break; ! 193: } ! 194: } ! 195: ! 196: /* */ ! 197: ! 198: static int tmp_fd () { ! 199: int fd; ! 200: char tmpfil[BUFSIZ]; ! 201: ! 202: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 203: if ((fd = creat (tmpfil, 0600)) == NOTOK) ! 204: return NOTOK; ! 205: (void) close (fd); ! 206: ! 207: if ((fd = open (tmpfil, 2)) == NOTOK) ! 208: return NOTOK; ! 209: if (debugsw) ! 210: advise (NULLCP, "temporary file %s selected", tmpfil); ! 211: else ! 212: if (unlink (tmpfil) == NOTOK) ! 213: advise (tmpfil, "unable to remove"); ! 214: ! 215: return fd; ! 216: } ! 217: ! 218: /* */ ! 219: ! 220: static anno (fd, st) ! 221: int fd; ! 222: register struct stat *st; ! 223: { ! 224: int child_id; ! 225: int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) (); ! 226: static char *cwd = NULL; ! 227: struct stat st2; ! 228: ! 229: if (altmsg && ! 230: (stat (altmsg, &st2) == NOTOK ! 231: || st -> st_mtime != st2.st_mtime ! 232: || st -> st_dev != st2.st_dev ! 233: || st -> st_ino != st2.st_ino)) { ! 234: if (debugsw) ! 235: admonish (NULLCP, "$mhaltmsg mismatch"); ! 236: return; ! 237: } ! 238: ! 239: child_id = debugsw ? NOTOK : fork (); ! 240: switch (child_id) { ! 241: case NOTOK: /* oops */ ! 242: if (!debugsw) ! 243: advise (NULLCP, ! 244: "unable to fork, so doing annotations by hand..."); ! 245: if (cwd == NULL) ! 246: cwd = getcpy (pwd ()); ! 247: ! 248: case OK: ! 249: hstat = signal (SIGHUP, SIG_IGN); ! 250: istat = signal (SIGINT, SIG_IGN); ! 251: qstat = signal (SIGQUIT, SIG_IGN); ! 252: tstat = signal (SIGTERM, SIG_IGN); ! 253: annoaux (fd); ! 254: if (child_id == OK) ! 255: _exit (0); ! 256: (void) signal (SIGHUP, hstat); ! 257: (void) signal (SIGINT, istat); ! 258: (void) signal (SIGQUIT, qstat); ! 259: (void) signal (SIGTERM, tstat); ! 260: (void) chdir (cwd); ! 261: break; ! 262: ! 263: default: /* no waiting... */ ! 264: (void) close (fd); ! 265: break; ! 266: } ! 267: } ! 268: ! 269: /* */ ! 270: ! 271: static annoaux (fd) ! 272: int fd; ! 273: { ! 274: int fd2, ! 275: fd3, ! 276: msgnum; ! 277: char *cp, ! 278: *folder, ! 279: *maildir, ! 280: buffer[BUFSIZ], ! 281: **ap; ! 282: FILE *fp; ! 283: struct msgs *mp; ! 284: ! 285: if ((folder = getenv ("mhfolder")) == NULL || *folder == NULL) { ! 286: if (debugsw) ! 287: admonish (NULLCP, "$mhfolder not set"); ! 288: return; ! 289: } ! 290: maildir = m_maildir (folder); ! 291: if (chdir (maildir) == NOTOK) { ! 292: if (debugsw) ! 293: admonish (maildir, "unable to change directory to"); ! 294: return; ! 295: } ! 296: if (!(mp = m_gmsg (folder))) { ! 297: if (debugsw) ! 298: admonish (NULLCP, "unable to read folder %s"); ! 299: return; ! 300: } ! 301: if (mp -> hghmsg == 0) { ! 302: if (debugsw) ! 303: admonish (NULLCP, "no messages in %s", folder); ! 304: goto oops; ! 305: } ! 306: ! 307: if ((cp = getenv ("mhmessages")) == NULL || *cp == NULL) { ! 308: if (debugsw) ! 309: admonish (NULLCP, "$mhmessages not set"); ! 310: goto oops; ! 311: } ! 312: if (!debugsw /* MOBY HACK... */ ! 313: && pushsw ! 314: && (fd3 = open ("/dev/null", 2)) != NOTOK ! 315: && (fd2 = dup (fileno (stderr))) != NOTOK) { ! 316: (void) dup2 (fd3, fileno (stderr)); ! 317: (void) close (fd3); ! 318: } ! 319: else ! 320: fd2 = NOTOK; ! 321: for (ap = brkstring (cp = getcpy (cp), " ", NULLCP); *ap; ap++) ! 322: (void) m_convert (mp, *ap); ! 323: free (cp); ! 324: if (fd2 != NOTOK) ! 325: (void) dup2 (fd2, fileno (stderr)); ! 326: if (mp -> numsel == 0) { ! 327: if (debugsw) ! 328: admonish (NULLCP, "no messages to annotate"); ! 329: goto oops; ! 330: } ! 331: ! 332: (void) lseek (fd, 0L, 0); ! 333: if ((fp = fdopen (fd, "r")) == NULL) { ! 334: if (debugsw) ! 335: admonish (NULLCP, "unable to fdopen annotation list"); ! 336: goto oops; ! 337: } ! 338: cp = NULL; ! 339: while (fgets (buffer, sizeof buffer, fp) != NULL) ! 340: cp = add (buffer, cp); ! 341: (void) fclose (fp); ! 342: ! 343: if (debugsw) ! 344: advise (NULLCP, "annotate%s with %s: \"%s\"", ! 345: inplace ? " inplace" : "", annotext, cp); ! 346: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 347: if (mp -> msgstats[msgnum] & SELECTED) { ! 348: if (debugsw) ! 349: advise (NULLCP, "annotate message %d", msgnum); ! 350: (void) annotate (m_name (msgnum), annotext, cp, inplace); ! 351: } ! 352: ! 353: free (cp); ! 354: ! 355: oops: ; ! 356: m_fmsg (mp); ! 357: } ! 358: ! 359: /* */ ! 360: ! 361: void done (status) ! 362: int status; ! 363: { ! 364: if (armed) ! 365: longjmp (env, status ? status : NOTOK); ! 366: ! 367: exit (status); ! 368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.