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: }

Defined functions

alert defined in line 143; used 1 times
anno defined in line 220; used 1 times
annoaux defined in line 271; used 1 times
done defined in line 361; used 1 times
  • in line 93
sendaux defined in line 59; used 1 times
  • in line 43
sendsbr defined in line 32; used 2 times
tmp_fd defined in line 198; used 2 times

Defined variables

altmsg defined in line 18; used 34 times
annotext defined in line 19; used 14 times
armed defined in line 23; used 3 times
debugsw defined in line 12; used 17 times
distfile defined in line 20; used 14 times
env defined in line 24; used 2 times
forwsw defined in line 13; used 7 times
inplace defined in line 14; used 5 times
pushsw defined in line 15; used 11 times
unique defined in line 16; used 6 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1038
Valid CSS Valid XHTML 1.0 Strict