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