]> granicus.if.org Git - neomutt/commitdiff
feature: fmemopen
authorJulius Plenz <plenz@cis.fu-berlin.de>
Sat, 30 Jan 2016 16:20:14 +0000 (16:20 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 4 Apr 2016 02:33:15 +0000 (03:33 +0100)
Replace some temporary files with memory buffers

configure.ac
handler.c
pattern.c

index fe18ecce4e09bb23ce93762a409df8d82b3e00eb..139bc6ed8b8f3774af9ab3cef016a9723d06398d 100644 (file)
@@ -1301,6 +1301,8 @@ if test $mutt_cv_langinfo_yesexpr = yes; then
   AC_DEFINE(HAVE_LANGINFO_YESEXPR,1,[ Define if you have <langinfo.h> and nl_langinfo(YESEXPR). ])
 fi
 
+AC_CHECK_FUNCS(fmemopen open_memstream)
+
 dnl Documentation tools
 have_openjade="no"
 AC_PATH_PROG([OSPCAT], [ospcat], [none])
index 4944d49aee3f62fb2c3ec27111ab4776683d68cb..307f747d186826deb85d6db8e322e53403fb93eb 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -1595,7 +1595,9 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
   int origType;
   char *savePrefix = NULL;
   FILE *fp = NULL;
+#ifndef HAVE_FMEMOPEN
   char tempfile[_POSIX_PATH_MAX];
+#endif
   size_t tmplength = 0;
   LOFF_T tmpoffset = 0;
   int decode = 0;
@@ -1603,6 +1605,11 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
 
   fseeko (s->fpin, b->offset, 0);
 
+#ifdef HAVE_FMEMOPEN
+  char *temp;
+  size_t tempsize;
+#endif
+
   /* see if we need to decode this part before processing it */
   if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE ||
       b->encoding == ENCUUENCODED || plaintext ||
@@ -1618,6 +1625,14 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
     {
       /* decode to a tempfile, saving the original destination */
       fp = s->fpout;
+#ifdef HAVE_FMEMOPEN
+     if ((s->fpout = open_memstream(&temp, &tempsize)) == NULL)
+     {
+       mutt_error _("Unable to open memory stream!");
+       dprint (1, (debugfile, "Can't open memory stream.\n"));
+       return -1;
+     }
+#else
       mutt_mktemp (tempfile, sizeof (tempfile));
       if ((s->fpout = safe_fopen (tempfile, "w")) == NULL)
       {
@@ -1625,6 +1640,7 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
         dprint (1, (debugfile, "Can't open %s.\n", tempfile));
         return -1;
       }
+#endif
       /* decoding the attachment changes the size and offset, so save a copy
         * of the "real" values now, and restore them after processing
         */
@@ -1653,9 +1669,19 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
       /* restore final destination and substitute the tempfile for input */
       s->fpout = fp;
       fp = s->fpin;
+#ifdef HAVE_FMEMOPEN
+      if(tempsize)
+        s->fpin = fmemopen(temp, tempsize, "r");
+      else /* fmemopen cannot handle zero-length buffers */
+        s->fpin = safe_fopen ("/dev/null", "r");
+      if(s->fpin == NULL) {
+       mutt_perror("failed to re-open memstream!");
+       return (-1);
+      }
+#else
       s->fpin = fopen (tempfile, "r");
       unlink (tempfile);
-
+#endif
       /* restore the prefix */
       s->prefix = savePrefix;
     }
@@ -1680,6 +1706,10 @@ static int run_decode_and_handler (BODY *b, STATE *s, handler_t handler, int pla
 
       /* restore the original source stream */
       safe_fclose (&s->fpin);
+#ifdef HAVE_FMEMOPEN
+      if(tempsize)
+          FREE(&temp);
+#endif
       s->fpin = fp;
     }
   }
index d954cdc3bbd7a23b41360ed7f74ae55d0bf73e87..13f0e203fe3566ad29456597f44a92a7f0b726e1 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -144,16 +144,21 @@ int mutt_which_case (const char *s)
 static int
 msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
 {
-  char tempfile[_POSIX_PATH_MAX];
   MESSAGE *msg = NULL;
   STATE s;
-  struct stat st;
   FILE *fp = NULL;
   long lng = 0;
   int match = 0;
   HEADER *h = ctx->hdrs[msgno];
   char *buf;
   size_t blen;
+#ifdef HAVE_FMEMOPEN
+  char *temp;
+  size_t tempsize;
+#else
+  char tempfile[_POSIX_PATH_MAX];
+  struct stat st;
+#endif
 
   if ((msg = mx_open_message (ctx, msgno)) != NULL)
   {
@@ -163,12 +168,20 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
       memset (&s, 0, sizeof (s));
       s.fpin = msg->fp;
       s.flags = M_CHARCONV;
+#ifdef HAVE_FMEMOPEN
+      if((s.fpout = open_memstream(&temp, &tempsize)) == NULL)
+      {
+       mutt_perror ("Error opening memstream");
+       return (0);
+      }
+#else
       mutt_mktemp (tempfile, sizeof (tempfile));
       if ((s.fpout = safe_fopen (tempfile, "w+")) == NULL)
       {
        mutt_perror (tempfile);
        return (0);
       }
+#endif
 
       if (pat->op != M_BODY)
        mutt_copy_header (msg->fp, h, s.fpout, CH_FROM | CH_DECODE, NULL);
@@ -184,7 +197,11 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
          if (s.fpout)
          {
            safe_fclose (&s.fpout);
+#ifdef HAVE_FMEMOPEN
+            FREE(&temp);
+#else
            unlink (tempfile);
+#endif
          }
          return (0);
        }
@@ -193,11 +210,28 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
        mutt_body_handler (h->content, &s);
       }
 
+#ifdef HAVE_FMEMOPEN
+      fclose(s.fpout);
+      lng = tempsize;
+
+      if(tempsize) {
+          if ((fp = fmemopen(temp, tempsize, "r")) == NULL) {
+            mutt_perror ("Error re-opening memstream");
+            return (0);
+          }
+      } else { /* fmemopen cannot handle empty buffers */
+          if ((fp = safe_fopen ("/dev/null", "r")) == NULL) {
+            mutt_perror ("Error opening /dev/null");
+            return (0);
+          }
+      }
+#else
       fp = s.fpout;
       fflush (fp);
       fseek (fp, 0, 0);
       fstat (fileno (fp), &st);
       lng = (long) st.st_size;
+#endif
     }
     else
     {
@@ -244,7 +278,12 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
     if (option (OPTTHOROUGHSRC))
     {
       safe_fclose (&fp);
+#ifdef HAVE_FMEMOPEN
+      if(tempsize)
+          FREE (&temp);
+#else
       unlink (tempfile);
+#endif
     }
   }