[BACK]Return to collect.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mail

Diff for /src/usr.bin/mail/collect.c between version 1.21 and 1.22

version 1.21, 2001/06/23 23:04:21 version 1.22, 2001/11/20 20:50:00
Line 63 
Line 63 
  * away on dead.letter.   * away on dead.letter.
  */   */
   
 static  sig_t   saveint;                /* Previous SIGINT value */  
 static  sig_t   savehup;                /* Previous SIGHUP value */  
 static  sig_t   savetstp;               /* Previous SIGTSTP value */  
 static  sig_t   savettou;               /* Previous SIGTTOU value */  
 static  sig_t   savettin;               /* Previous SIGTTIN value */  
 static  FILE    *collf;                 /* File for saving away */  static  FILE    *collf;                 /* File for saving away */
 static  int     hadintr;                /* Have seen one SIGINT so far */  static  int     hadintr;                /* Have seen one SIGINT so far */
   
 static  sigjmp_buf      colljmp;        /* To get back to work */  
 static  int             colljmp_p;      /* whether to long jump */  
 static  sigjmp_buf      collabort;      /* To end collection with error */  
   
 FILE *  FILE *
 collect(hp, printheaders)  collect(hp, printheaders)
         struct header *hp;          struct header *hp;
         int printheaders;          int printheaders;
 {  {
         FILE *fbuf;          FILE *fbuf;
         int lc, cc, fd, c, t, lastlong, rc;          int lc, cc, fd, c, t, lastlong, rc, sig;
         volatile int escape, eofcount, longline;          int escape, eofcount, longline;
         volatile char getsub;          char getsub;
         char linebuf[LINESIZE], tempname[PATHSIZE], *cp;          char linebuf[LINESIZE], tempname[PATHSIZE], *cp;
         sigset_t oset, nset;  
   
         collf = NULL;          collf = NULL;
         /*          eofcount = 0;
          * Start catching signals from here, but we're still die on interrupts          hadintr = 0;
          * until we're in the main loop.          lastlong = 0;
          */          longline = 0;
         sigemptyset(&nset);          if ((cp = value("escape")) != NULL)
         sigaddset(&nset, SIGINT);                  escape = *cp;
         sigaddset(&nset, SIGHUP);          else
         sigprocmask(SIG_BLOCK, &nset, &oset);                  escape = ESCAPE;
         if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)  
                 (void)signal(SIGINT, collint);  
         if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)  
                 (void)signal(SIGHUP, collhup);  
         savetstp = signal(SIGTSTP, collstop);  
         savettou = signal(SIGTTOU, collstop);  
         savettin = signal(SIGTTIN, collstop);  
         if (sigsetjmp(collabort, 1) || sigsetjmp(colljmp, 1)) {  
                 (void)rm(tempname);  
                 goto err;  
         }  
         sigdelset(&oset, SIGINT);  
         sigdelset(&oset, SIGHUP);  
         sigprocmask(SIG_SETMASK, &oset, NULL);  
   
         noreset++;          noreset++;
   
         (void)snprintf(tempname, sizeof(tempname),          (void)snprintf(tempname, sizeof(tempname),
             "%s/mail.RsXXXXXXXXXX", tmpdir);              "%s/mail.RsXXXXXXXXXX", tmpdir);
         if ((fd = mkstemp(tempname)) == -1 ||          if ((fd = mkstemp(tempname)) == -1 ||
Line 135 
Line 111 
                 puthead(hp, stdout, t);                  puthead(hp, stdout, t);
                 fflush(stdout);                  fflush(stdout);
         }          }
         if ((cp = value("escape")) != NULL)          if (getsub && gethfromtty(hp, GSUBJECT) == -1)
                 escape = *cp;                  goto err;
         else  
                 escape = ESCAPE;  
         eofcount = 0;  
         hadintr = 0;  
         lastlong = 0;  
         longline = 0;  
   
         if (!sigsetjmp(colljmp, 1)) {          if (0) {
                 if (getsub)  
                         gethfromtty(hp, GSUBJECT);  
         } else {  
                 /*  
                  * Come here for printing the after-signal message.  
                  * Duplicate messages won't be printed because  
                  * the write is aborted if we get a SIGTTOU.  
                  */  
 cont:  cont:
                 if (hadintr) {                  /* Come here for printing the after-suspend message. */
                   if (isatty(0)) {
                           puts("(continue)");
                         fflush(stdout);                          fflush(stdout);
                         fputs("\n(Interrupt -- one more to kill letter)\n",  
                             stderr);  
                 } else {  
                         if (isatty(0)) {  
                                 puts("(continue)");  
                                 fflush(stdout);  
                         }  
                 }                  }
         }          }
         for (;;) {          for (;;) {
                 colljmp_p = 1;                  c = readline(stdin, linebuf, LINESIZE, &sig);
                 c = readline(stdin, linebuf, LINESIZE);  
                 colljmp_p = 0;                  /* Act on any signal caught during readline() ignoring 'c' */
                   switch (sig) {
                   case 0:
                           break;
                   case SIGINT:
                           if (collabort())
                                   goto err;
                           continue;
                   case SIGHUP:
                           rewind(collf);
                           savedeadletter(collf);
                           /*
                            * Let's pretend nobody else wants to clean up,
                            * a true statement at this time.
                            */
                           exit(1);
                   default:
                           /* Stopped due to job control */
                           (void)kill(0, sig);
                           goto cont;
                   }
   
                   /* No signal, check for error */
                 if (c < 0) {                  if (c < 0) {
                         if (value("interactive") != NULL &&                          if (value("interactive") != NULL &&
                             value("ignoreeof") != NULL && ++eofcount < 25) {                              value("ignoreeof") != NULL && ++eofcount < 25) {
Line 236 
Line 215 
                          * Act like an interrupt happened.                           * Act like an interrupt happened.
                          */                           */
                         hadintr++;                          hadintr++;
                         collint(SIGINT);                          collabort();
                         exit(1);                          fputs("Interrupt\n", stderr);
                           goto err;
                 case 'h':                  case 'h':
                         /*                          /*
                          * Grab a bunch of headers.                           * Grab a bunch of headers.
Line 304 
Line 284 
                         fflush(stdout);                          fflush(stdout);
                         lc = 0;                          lc = 0;
                         cc = 0;                          cc = 0;
                         while ((rc = readline(fbuf, linebuf, LINESIZE)) >= 0) {                          while ((rc = readline(fbuf, linebuf, LINESIZE, NULL)) >= 0) {
                                 if (rc != LINESIZE - 1)                                  if (rc != LINESIZE - 1)
                                         lc++;                                          lc++;
                                 if ((t = putline(collf, linebuf,                                  if ((t = putline(collf, linebuf,
Line 389 
Line 369 
   
         if (value("interactive") != NULL) {          if (value("interactive") != NULL) {
                 if (value("askcc") != NULL || value("askbcc") != NULL) {                  if (value("askcc") != NULL || value("askbcc") != NULL) {
                         if (value("askcc") != NULL)                          if (value("askcc") != NULL) {
                                 gethfromtty(hp, GCC);                                  if (gethfromtty(hp, GCC) == -1)
                         if (value("askbcc") != NULL)                                          goto err;
                                 gethfromtty(hp, GBCC);                          }
                           if (value("askbcc") != NULL) {
                                   if (gethfromtty(hp, GBCC) == -1)
                                           goto err;
                           }
                 } else {                  } else {
                         puts("EOT");                          puts("EOT");
                         (void)fflush(stdout);                          (void)fflush(stdout);
Line 408 
Line 392 
         if (collf != NULL)          if (collf != NULL)
                 rewind(collf);                  rewind(collf);
         noreset--;          noreset--;
         (void)sigemptyset(&nset);  
         (void)sigaddset(&nset, SIGINT);  
         (void)sigaddset(&nset, SIGHUP);  
         (void)sigprocmask(SIG_BLOCK, &nset, &oset);  
         (void)signal(SIGINT, saveint);  
         (void)signal(SIGHUP, savehup);  
         (void)signal(SIGTSTP, savetstp);  
         (void)signal(SIGTTOU, savettou);  
         (void)signal(SIGTTIN, savettin);  
         (void)sigprocmask(SIG_SETMASK, &oset, NULL);  
         return(collf);          return(collf);
 }  }
   
Line 477 
Line 451 
         FILE *fp;          FILE *fp;
         int c;          int c;
 {  {
         sig_t sigint = signal(SIGINT, SIG_IGN);          FILE *nf;
         FILE *nf = run_editor(fp, (off_t)-1, c, 0);          struct sigaction oact;
           sigset_t oset;
   
           (void)ignoresig(SIGINT, &oact, &oset);
           nf = run_editor(fp, (off_t)-1, c, 0);
         if (nf != NULL) {          if (nf != NULL) {
                 fseek(nf, 0L, 2);                  fseek(nf, 0L, 2);
                 collf = nf;                  collf = nf;
                 (void)Fclose(fp);                  (void)Fclose(fp);
         }          }
         (void)signal(SIGINT, sigint);          (void)sigprocmask(SIG_SETMASK, &oset, NULL);
           (void)sigaction(SIGINT, &oact, NULL);
 }  }
   
 /*  /*
Line 501 
Line 479 
 {  {
         FILE *nf;          FILE *nf;
         int fd;          int fd;
         sig_t sigint = signal(SIGINT, SIG_IGN);  
         char *shell, tempname[PATHSIZE];          char *shell, tempname[PATHSIZE];
           struct sigaction oact;
           sigset_t oset;
   
           (void)ignoresig(SIGINT, &oact, &oset);
         (void)snprintf(tempname, sizeof(tempname),          (void)snprintf(tempname, sizeof(tempname),
             "%s/mail.ReXXXXXXXXXX", tmpdir);              "%s/mail.ReXXXXXXXXXX", tmpdir);
         if ((fd = mkstemp(tempname)) == -1 ||          if ((fd = mkstemp(tempname)) == -1 ||
Line 534 
Line 514 
         collf = nf;          collf = nf;
         (void)Fclose(fp);          (void)Fclose(fp);
 out:  out:
         (void)signal(SIGINT, sigint);          (void)sigprocmask(SIG_SETMASK, &oset, NULL);
           (void)sigaction(SIGINT, &oact, NULL);
 }  }
   
 /*  /*
Line 590 
Line 571 
 }  }
   
 /*  /*
  * Print (continue) when continued after ^Z.   * User aborted during message composition.
    * Save the partial message in ~/dead.letter.
  */   */
 /*ARGSUSED*/  int
 void  collabort()
 collstop(s)  
         int s;  
 {  {
         sig_t old_action = signal(s, SIG_DFL);  
         sigset_t nset;  
   
         (void)sigemptyset(&nset);  
         (void)sigaddset(&nset, s);  
         (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);  
         (void)kill(0, s);  
         (void)sigprocmask(SIG_BLOCK, &nset, NULL);  
         (void)signal(s, old_action);  
         if (colljmp_p) {  
                 colljmp_p = 0;  
                 hadintr = 0;  
                 siglongjmp(colljmp, 1);  
         }  
 }  
   
 /*  
  * On interrupt, come here to save the partial message in ~/dead.letter.  
  * Then jump out of the collection loop.  
  */  
 /*ARGSUSED*/  
 void  
 collint(s)  
         int s;  
 {  
         /*          /*
          * the control flow is subtle, because we can be called from ~q.           * the control flow is subtle, because we can be called from ~q.
          */           */
Line 630 
Line 585 
                         puts("@");                          puts("@");
                         fflush(stdout);                          fflush(stdout);
                         clearerr(stdin);                          clearerr(stdin);
                         return;                  } else {
                           fflush(stdout);
                           fputs("\n(Interrupt -- one more to kill letter)\n",
                               stderr);
                           hadintr++;
                 }                  }
                 hadintr = 1;                  return(0);
                 siglongjmp(colljmp, 1);  
         }          }
           fflush(stdout);
         rewind(collf);          rewind(collf);
         if (value("nosave") == NULL)          if (value("nosave") == NULL)
                 savedeadletter(collf);                  savedeadletter(collf);
         siglongjmp(collabort, 1);          return(1);
 }  }
   
 /*ARGSUSED*/  
 void  void
 collhup(s)  
         int s;  
 {  
         rewind(collf);  
         savedeadletter(collf);  
         /*  
          * Let's pretend nobody else wants to clean up,  
          * a true statement at this time.  
          */  
         exit(1);  
 }  
   
 void  
 savedeadletter(fp)  savedeadletter(fp)
         FILE *fp;          FILE *fp;
 {  {
Line 677 
Line 622 
         rewind(fp);          rewind(fp);
 }  }
   
 void  int
 gethfromtty(hp, gflags)  gethfromtty(hp, gflags)
         struct header *hp;          struct header *hp;
         int gflags;          int gflags;
 {  {
         if (grabh(hp, gflags) == SIGINT) {  
                 fflush(stdout);          hadintr = 0;
                 fputs("\n(Interrupt -- one more to kill letter)\n",          while (grabh(hp, gflags) != 0) {
                     stderr);                  if (collabort())
                 if (grabh(hp, gflags) == SIGINT) {                          return(-1);
                         hadintr++;  
                         collint(SIGINT);  
                         exit(1);  
                 }  
         }          }
           return(0);
 }  }

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22