commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-225-g9df6386


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-225-g9df6386
Date: Thu, 25 Nov 2010 18:37:19 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=9df638667be69868851e0882eb172b1476ff962d

The branch, master has been updated
       via  9df638667be69868851e0882eb172b1476ff962d (commit)
       via  bf613ed8c4661faa1e9c1de7f28a7e03c5652ec0 (commit)
       via  8acde412feee7235b342196182c69d0ed25fe1fc (commit)
      from  80bb8b2fc30ba04dda9eb652519c65897542437e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9df638667be69868851e0882eb172b1476ff962d
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Nov 25 20:16:38 2010 +0200

    Remove obsolete function.
    
    * include/mailutils/body.h (mu_body_get_filename): Remove proto.
    * include/mailutils/sys/body.h (_mu_body) <filename>: Remove.
    * libmailutils/mailbox/body.c (mu_body_get_filename): Remove
    obsolete function.
    (_body_get_stream): Use mu_temp_file_stream_create.
    * libmailutils/stream/temp_file_stream.c (mu_temp_file_stream_create):
    Return EINVAL if flags is set, but hints is NULL.
    * libmu_scm/mu_body.c (mu_scm_body_print): Don't use mu_body_get_filename.

commit bf613ed8c4661faa1e9c1de7f28a7e03c5652ec0
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Nov 25 19:32:07 2010 +0200

    temp_file_stream: Use mu_tempfile_hints to control how the file name is 
created.
    
    * include/mailutils/stream.h (mu_temp_file_stream_create): Change signature.
    * include/mailutils/sys/Makefile.am (sysinclude_HEADERS): Add 
temp_file_stream.h
    * include/mailutils/util.h (mu_tempfile_hints): Remove const qualifiers.
    * libmailutils/stream/temp_file_stream.c: Include sys/temp_file_stream.h.
    (fd_temp_open): Use data from struct _mu_temp_file_stream.
    (fd_temp_done): New function.
    (mu_temp_file_stream_create): Take hints and flags as arguments.
    
    * examples/mta.c: Update calls to mu_temp_file_stream_create.
    * libproto/mbox/mbox.c: Likewise.
    * libproto/pop/mbox.c: Likewise.
    * maidag/deliver.c: Likewise.
    * maidag/lmtp.c: Likewise.
    * mh/burst.c: Likewise.
    * mh/prompter.c: Likewise.

commit 8acde412feee7235b342196182c69d0ed25fe1fc
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Nov 25 17:12:32 2010 +0200

    Rewrite temporary file handling.
    
    * include/mailutils/util.h (mu_make_file_name_suf): New proto.
    (mu_make_file_name): Replace with a macro.
    (MU_TEMPFILE_TMPDIR,MU_TEMPFILE_SUFFIX)
    (MU_TEMPFILE_MKDIR): New flags.
    (mu_tempfile_hints): New struct.
    (mu_tempfile): Change signature.
    * libmailutils/base/tempfile.c (mu_create_temp_file): New function.
    (mu_tempfile): Rewrite from scratch.  Change signature.  All callers
    changed.
    * libmailutils/string/mkfilename.c (mu_make_file_name): Remove.
    (mu_make_file_name_suf): New function.
    
    * libmailutils/stream/streamcpy.c (mu_stream_copy): Don't return EIO
    on EOF.
    * libmailutils/stream/file_stream.c (mu_fd_stream_create): If
    MU_STREAM_SEEK is set, position fd to 0.
    
    * guimb/collect.c: Update calls to mu_tempfile.
    * lib/mailcap.c: Likewise.
    * libmailutils/base/amd.c (_amd_tempfile): Rewrite using mu_tempfile.
    
    * libmailutils/tests/tempfile.c: New file.
    * libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add tempfile.

-----------------------------------------------------------------------

Summary of changes:
 examples/mta.c                                     |    2 +-
 guimb/collect.c                                    |    3 +-
 include/mailutils/body.h                           |    2 -
 include/mailutils/stream.h                         |    4 +-
 include/mailutils/sys/Makefile.am                  |    1 +
 include/mailutils/sys/body.h                       |    1 -
 .../sys/{prog_stream.h => temp_file_stream.h}      |   26 ++--
 include/mailutils/util.h                           |   22 ++-
 lib/mailcap.c                                      |    5 +-
 libmailutils/base/amd.c                            |   23 ++-
 libmailutils/base/tempfile.c                       |  204 ++++++++++++++++----
 libmailutils/mailbox/body.c                        |   32 +---
 libmailutils/stream/file_stream.c                  |   14 +-
 libmailutils/stream/streamcpy.c                    |    9 +-
 libmailutils/stream/temp_file_stream.c             |   54 ++++--
 libmailutils/string/mkfilename.c                   |   11 +-
 libmailutils/tests/Makefile.am                     |    1 +
 libmailutils/tests/tempfile.c                      |  169 ++++++++++++++++
 libmu_scm/mu_body.c                                |    9 +-
 libproto/mbox/mbox.c                               |    2 +-
 libproto/pop/mbox.c                                |    2 +-
 maidag/deliver.c                                   |    2 +-
 maidag/lmtp.c                                      |    2 +-
 mail/escape.c                                      |   15 +-
 mail/send.c                                        |   22 ++-
 mh/burst.c                                         |    2 +-
 mh/prompter.c                                      |    2 +-
 27 files changed, 491 insertions(+), 150 deletions(-)
 copy include/mailutils/sys/{prog_stream.h => temp_file_stream.h} (68%)
 create mode 100644 libmailutils/tests/tempfile.c

diff --git a/examples/mta.c b/examples/mta.c
index bff83d5..15a0de7 100644
--- a/examples/mta.c
+++ b/examples/mta.c
@@ -198,7 +198,7 @@ make_tmp (mu_stream_t in)
   size_t size = 0, n;
   mu_message_t mesg;
   
-  rc = mu_temp_file_stream_create (&out, NULL);
+  rc = mu_temp_file_stream_create (&out, NULL, 0);
   if (rc)
     {
       mu_error (_("unable to open temporary file: %s"), mu_strerror (rc));
diff --git a/guimb/collect.c b/guimb/collect.c
index 342e593..8530095 100644
--- a/guimb/collect.c
+++ b/guimb/collect.c
@@ -55,8 +55,7 @@ collect_open_mailbox_file ()
   int fd;
 
   /* Create input mailbox */
-  fd = mu_tempfile (NULL, &temp_filename);
-  if (fd == -1)
+  if (mu_tempfile (NULL, 0, &fd, &temp_filename))
     exit (1);
 
   temp_file = fdopen (fd, "w");
diff --git a/include/mailutils/body.h b/include/mailutils/body.h
index 2a116e8..3256765 100644
--- a/include/mailutils/body.h
+++ b/include/mailutils/body.h
@@ -39,8 +39,6 @@ extern int mu_body_set_get_stream (mu_body_t,
                                   int (*) (mu_body_t, mu_stream_t *),
                                   void *owner);
   
-extern int mu_body_get_filename   (mu_body_t, char *, size_t, size_t *);
-
 extern int mu_body_size           (mu_body_t, size_t *);
 extern int mu_body_set_size       (mu_body_t,
                                int (*_size) (mu_body_t, size_t*), void *owner);
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index ba8c9bc..de980d3 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -192,7 +192,9 @@ int mu_stream_copy (mu_stream_t dst, mu_stream_t src, 
mu_off_t size,
 
 
 int mu_file_stream_create (mu_stream_t *pstream, const char *filename, int 
flags);
-int mu_temp_file_stream_create (mu_stream_t *pstream, const char *dir);
+struct mu_tempfile_hints;  
+int mu_temp_file_stream_create (mu_stream_t *pstream,
+                               struct mu_tempfile_hints *hints, int flags);
 int mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd,
                         int flags);
 
diff --git a/include/mailutils/sys/Makefile.am 
b/include/mailutils/sys/Makefile.am
index 0ef9f33..7904561 100644
--- a/include/mailutils/sys/Makefile.am
+++ b/include/mailutils/sys/Makefile.am
@@ -53,6 +53,7 @@ sysinclude_HEADERS = \
  streamref.h\
  streamtrans.h\
  stream.h\
+ temp_file_stream.h\
  tls-stream.h\
  url.h\
  xscript-stream.h
diff --git a/include/mailutils/sys/body.h b/include/mailutils/sys/body.h
index a7be7eb..5de5e56 100644
--- a/include/mailutils/sys/body.h
+++ b/include/mailutils/sys/body.h
@@ -32,7 +32,6 @@ extern "C" {
 struct _mu_body
 {
   void *owner;
-  char *filename;
   mu_stream_t stream;
   mu_stream_t fstream;
   int flags;
diff --git a/include/mailutils/sys/prog_stream.h 
b/include/mailutils/sys/temp_file_stream.h
similarity index 68%
copy from include/mailutils/sys/prog_stream.h
copy to include/mailutils/sys/temp_file_stream.h
index fa042f2..fdb1725 100644
--- a/include/mailutils/sys/prog_stream.h
+++ b/include/mailutils/sys/temp_file_stream.h
@@ -14,22 +14,22 @@
    You should have received a copy of the GNU Lesser General Public License
    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
 
-#ifndef _MAILUTILS_SYS_PROG_STREAM_H
-#define _MAILUTILS_SYS_PROG_STREAM_H
+#ifndef _MAILUTILS_SYS_TEMP_FILE_STREAM_H
+#define _MAILUTILS_SYS_TEMP_FILE_STREAM_H
 
-#include <mailutils/sys/stream.h>
+#include <mailutils/types.h>
+#include <mailutils/stream.h>
+#include <mailutils/sys/file_stream.h>
+#include <mailutils/util.h>
 
-struct _mu_prog_stream
+struct _mu_temp_file_stream
 {
-  struct _mu_stream stream;
-  pid_t pid;
-  int status;
-  pid_t writer_pid;
-  int argc;
-  char **argv;
-  mu_stream_t in, out;
-
-  mu_stream_t input;
+  struct _mu_file_stream stream;
+  struct mu_tempfile_hints hints;
+  int hflags;
+  void (*file_done) (struct _mu_stream *str);
 };
 
 #endif
+
+  
diff --git a/include/mailutils/util.h b/include/mailutils/util.h
index 9d3fff4..0df84a8 100644
--- a/include/mailutils/util.h
+++ b/include/mailutils/util.h
@@ -82,9 +82,27 @@ char *mu_tilde_expansion (const char *ref, const char *delim,
 int mu_readlink (const char *name, char **pbuf, size_t *psize, size_t *plen);
 int mu_unroll_symlink (const char *name, char **pout);
 char *mu_getcwd (void);
-int mu_tempfile (const char *tmpdir, char **namep);
+char *mu_make_file_name_suf (const char *dir, const char *file,
+                            const char *suf);
+#define mu_make_file_name(dir, file) mu_make_file_name_suf (dir, file, NULL)
+
+  /* ------------------------ */
+  /* Temporary file creation. */
+  /* ------------------------ */
+#define MU_TEMPFILE_TMPDIR  0x01   /* tmpdir is set */
+#define MU_TEMPFILE_SUFFIX  0x02   /* suffix is set */  
+#define MU_TEMPFILE_MKDIR   0x04   /* create a directory, not a file */
+  
+struct mu_tempfile_hints
+{
+  char *tmpdir;
+  char *suffix;
+};
+
+  /*int mu_tempfile (const char *tmpdir, char **namep);*/
+int mu_tempfile (struct mu_tempfile_hints *hints, int flags,
+                int *pfd, char **namep);
 char *mu_tempname (const char *tmpdir);
-char *mu_make_file_name (const char *dir, const char *file);
   
   /* ----------------------- */
   /* Current user email.     */
diff --git a/lib/mailcap.c b/lib/mailcap.c
index c0396d2..cbe9e1e 100644
--- a/lib/mailcap.c
+++ b/lib/mailcap.c
@@ -197,6 +197,7 @@ mime_context_get_content_type_value (struct mime_context 
*ctx,
   return rc;
 }
 
+/* FIXME: Rewrite via mu_stream_copy */
 static void
 mime_context_write_input (struct mime_context *ctx, int fd)
 {
@@ -219,8 +220,8 @@ mime_context_get_temp_file (struct mime_context *ctx, char 
**ptr)
 {
   if (!ctx->temp_file)
     {
-      int fd = mu_tempfile (NULL, &ctx->temp_file);
-      if (fd == -1)
+      int fd;
+      if (mu_tempfile (NULL, 0, &fd, &ctx->temp_file))
        return -1;
       mime_context_write_input (ctx, fd);
       close (fd);
diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c
index d51f941..db665b4 100644
--- a/libmailutils/base/amd.c
+++ b/libmailutils/base/amd.c
@@ -597,13 +597,18 @@ amd_quick_get_message (mu_mailbox_t mailbox, 
mu_message_qid_t qid,
   return ENOSYS;
 }
 
-static FILE *
-_amd_tempfile(struct _amd_data *amd, char **namep)
+static int
+_amd_tempfile (struct _amd_data *amd, FILE **pfile, char **namep)
 {
-  int fd = mu_tempfile (amd->name, namep);
-  if (fd == -1)
-      return NULL;
-  return fdopen (fd, "w");
+  struct mu_tempfile_hints hints;
+  int fd, rc;
+
+  hints.tmpdir = amd->name;
+  rc = mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, namep);
+  if (rc == 0)
+    if ((*pfile = fdopen (fd, "w")) == NULL)
+      rc = errno;
+  return rc;
 }
 
 static int
@@ -658,11 +663,11 @@ _amd_message_save (struct _amd_data *amd, struct 
_amd_message *mhm,
       return status;
     }      
     
-  fp = _amd_tempfile (mhm->amd, &name);
-  if (!fp)
+  status = _amd_tempfile (mhm->amd, &fp, &name);
+  if (status)
     {
       free (msg_name);
-      return errno;
+      return status;
     }
 
   /* Try to allocate large buffer */
diff --git a/libmailutils/base/tempfile.c b/libmailutils/base/tempfile.c
index 951e039..f494a3a 100644
--- a/libmailutils/base/tempfile.c
+++ b/libmailutils/base/tempfile.c
@@ -22,6 +22,8 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -33,62 +35,177 @@
 #include <mailutils/errno.h>
 #include <mailutils/util.h>
 
-/* Create and open a temporary file. Be very careful about it, since we
-   may be running with extra privilege i.e setgid().
-   Returns file descriptor of the open file.
-   If namep is not NULL, the pointer to the malloced file name will
-   be stored there. Otherwise, the file is unlinked right after open,
-   i.e. it will disappear after close(fd). */
-
 #ifndef P_tmpdir
 # define P_tmpdir "/tmp"
 #endif
 
+/* Lower level call.
+
+   Create a temporary file with the name according to the pattern FILENAME.
+   FILENAME must end with any amount of Xs, optionally followed by
+   SUFLEN other characters.
+
+   If ISDIR is not 0, create a directory (privileges 0700), otherwise
+   create a file (privileges 0600).
+
+   On success, return 0.  If pfd is not NULL (and ISDIR is 0), open the
+   created file and store the descriptor in *PFD.  Return actual file
+   name in FILENAME.
+
+   On error, return error code.
+*/   
 int
-mu_tempfile (const char *tmpdir, char **namep)
+mu_create_temp_file (char *filename, size_t suflen, int *pfd, int isdir)
 {
-  char *filename;
-  int fd;
+  int rc;
+  size_t len;
+  char *carrybuf;
+  char *p, *cp, *start, *end;
+  struct stat st;
+  static int first_call;
+  static char randstate[256];
+  static const unsigned char alphabet[] =
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+  if (!first_call)
+    {
+      /* Initialize random number generator */
+      struct timeval tv;
+      gettimeofday (&tv, NULL);
+      initstate (((unsigned long) tv.tv_usec << 16) ^ tv.tv_sec,
+                randstate, sizeof (randstate));
+      first_call = 1;
+    }
+  setstate (randstate);
   
-  if (!tmpdir)
-    tmpdir = (getenv ("TMPDIR")) ? getenv ("TMPDIR") : P_tmpdir;
-
-  filename = mu_make_file_name (tmpdir, "muXXXXXX");
-  if (!filename)
+  /* Start with the last filename character before suffix */
+  end = filename + strlen (filename) - suflen - 1;
+  /* Fill X's with random characters */
+  for (p = end; p >= filename && *p == 'X'; p--)
+    *p = alphabet[random () % (sizeof (alphabet) - 1)];
+  len = end - p;
+  if (len == 0)
+    return EINVAL;
+  start = p + 1;
+
+  carrybuf = malloc (len);
+  if (!carrybuf)
+    return ENOMEM;
+
+  /* Fill in the carry buffer */
+  memcpy (carrybuf, start, len);
+
+  for (;;)
     {
-      mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM);
-      return -1;
+      if (isdir)
+       {
+         if (mkdir (filename, 0700) == 0)
+           {
+             rc = 0;
+             break;
+           }
+       }
+      else if (pfd)
+       {
+         if ((*pfd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
+           {
+             rc = 0;
+             break;
+           }
+       }
+      else if (lstat (filename, &st) && errno == ENOENT)
+       {
+         rc = 0;
+         break;
+       }
+      
+      if (errno != EEXIST)
+       {
+         rc = errno;
+         break;
+       }
+
+      for (p = start, cp = carrybuf;; p++, cp++)
+       {
+         char *q;
+         
+         if (p == end)
+           /* All permutation exhausted */
+           return EEXIST;
+         q = strchr ((char*)alphabet, *p);
+         if (!q)
+           abort (); /* should not happen */
+         *p = (q[1] == 0) ? alphabet[0] : q[1];
+         if (*p != *cp)
+           break;
+       }
     }
+  free (carrybuf);
+  return rc;
+}
 
-#ifdef HAVE_MKSTEMP
-  {
-    int save_mask = umask (077);
-    fd = mkstemp (filename);
-    umask (save_mask);
-  }
-#else
-  if (mktemp (filename))
-    fd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0600);
-  else
-    fd = -1;
-#endif
+/* Create a temporary file according to HINTS.
+
+   If MU_TEMPFILE_MKDIR flag is set, create a directory instead of file.
+
+   On success, return 0.  If PFD is not NULL (and MU_TEMPFILE_MKDIR flag
+   is not set), open the file and store its descriptor in *PFD.  If
+   NAMEP is not NULL, store there a pointer to the allocated file name.
+   At least one of PFD and NAMEP must be set, otherwise EINVAL is returned.
 
-  if (fd == -1)
+   On error, returns error code describing the problem.
+
+   If hints is NULL, any flags except MU_TEMPFILE_MKDIR are ignored.
+   Otherwise:
+   
+   * If MU_TEMPFILE_TMPDIR is set, hints->tmpdir points to the name of
+     a directory where to create the temporary.
+   * If MU_TEMPFILE_SUFFIX is set, hints->suffix defines a suffix to
+     append to the created file name.
+ */
+int
+mu_tempfile (struct mu_tempfile_hints *hints, int flags,
+            int *pfd, char **namep)
+{
+  char *filename;
+  const char *tmpdir = getenv ("TMPDIR");
+  const char *suf = NULL;
+  int create_dir = 0;
+  int rc;
+  struct stat st;
+
+  if (pfd == NULL && namep == NULL)
+    return EINVAL;
+  if (hints)
     {
-      mu_error (_("cannot open temporary file: %s"), mu_strerror (errno));
-      free (filename);
-      return -1;
+      if (flags & MU_TEMPFILE_TMPDIR)
+       tmpdir = hints->tmpdir;
+      if (flags & MU_TEMPFILE_SUFFIX)
+       suf = hints->suffix;
+      create_dir = flags & MU_TEMPFILE_MKDIR;
     }
+      
+  if (!tmpdir)
+    tmpdir = P_tmpdir;
+
+  /* First, see if tmpdir exists */
+  if (stat (tmpdir, &st))
+    return errno;
 
-  if (namep)
-    *namep = filename;
-  else
+  /* Create a name template */
+  filename = mu_make_file_name_suf (tmpdir, "muXXXXXX", suf);
+  rc = mu_create_temp_file (filename, suf ? strlen (suf) : 0, pfd, create_dir);
+  if (rc == 0)
     {
-      unlink (filename);
-      free (filename);
+      if (namep)
+       *namep = filename;
+      else
+       {
+         unlink (filename);
+         free (filename);
+       }
     }
-
-  return fd;
+  return rc;
 }
 
 /* Create a unique temporary file name in tmpdir. The function
@@ -100,10 +217,13 @@ mu_tempfile (const char *tmpdir, char **namep)
 char *
 mu_tempname (const char *tmpdir)
 {
+  struct mu_tempfile_hints hints;
   char *filename = NULL;
-  int fd = mu_tempfile (tmpdir, &filename);
+  int fd;
+  hints.tmpdir = tmpdir;
+  if (mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, &filename))
+    return NULL;
   close (fd);
   return filename;
 }
 
-
diff --git a/libmailutils/mailbox/body.c b/libmailutils/mailbox/body.c
index e2c2bcd..5db2216 100644
--- a/libmailutils/mailbox/body.c
+++ b/libmailutils/mailbox/body.c
@@ -79,13 +79,6 @@ mu_body_destroy (mu_body_t *pbody, void *owner)
       mu_body_t body = *pbody;
       if (body->owner == owner)
        {
-         if (body->filename)
-           {
-             /* FIXME: should we do this?  */
-             remove (body->filename);
-             free (body->filename);
-           }
-
          if (body->stream)
            mu_stream_destroy (&body->stream);
 
@@ -123,26 +116,6 @@ mu_body_clear_modified (mu_body_t body)
   return 0;
 }
 
-int
-mu_body_get_filename (mu_body_t body, char *filename, size_t len, size_t *pn)
-{
-  int n = 0;
-  if (body == NULL)
-    return EINVAL;
-  if (body->filename)
-    {
-      n = strlen (body->filename);
-      if (filename && len > 0)
-       {
-         len--; /* Space for the null.  */
-         strncpy (filename, body->filename, len)[len] = '\0';
-       }
-    }
-  if (pn)
-    *pn = n;
-  return 0;
-}
-
 
 struct _mu_body_stream
 {
@@ -177,9 +150,8 @@ _body_get_stream (mu_body_t body, mu_stream_t *pstream, int 
ref)
            return ENOMEM;
          
          /* Create the temporary file.  */
-         body->filename = mu_tempname (NULL);
-         status = mu_file_stream_create (&body->fstream, 
-                                         body->filename, MU_STREAM_RDWR);
+
+         status = mu_temp_file_stream_create (&body->fstream, NULL, 0);
          if (status != 0)
            return status;
          mu_stream_set_buffer (body->fstream, mu_buffer_full, 0);
diff --git a/libmailutils/stream/file_stream.c 
b/libmailutils/stream/file_stream.c
index 6f9723a..73a2990 100644
--- a/libmailutils/stream/file_stream.c
+++ b/libmailutils/stream/file_stream.c
@@ -388,9 +388,17 @@ int
 mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd, int flags)
 {
   struct _mu_file_stream *fstr;
-  int rc = _mu_file_stream_create (&fstr,
-                                  sizeof (struct _mu_file_stream),
-                                  filename, fd, flags|_MU_STR_OPEN);
+  int rc;
+
+  if (flags & MU_STREAM_SEEK)
+    {
+      if (lseek (fd, 0, SEEK_SET))
+       return errno;
+    }
+
+  rc = _mu_file_stream_create (&fstr,
+                              sizeof (struct _mu_file_stream),
+                              filename, fd, flags|_MU_STR_OPEN);
   if (rc == 0)
     {
       mu_stream_t stream = (mu_stream_t) fstr;
diff --git a/libmailutils/stream/streamcpy.c b/libmailutils/stream/streamcpy.c
index 2020fad..38d3c90 100644
--- a/libmailutils/stream/streamcpy.c
+++ b/libmailutils/stream/streamcpy.c
@@ -98,10 +98,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t 
size,
        if (status)
          break;
        if (n == 0)
-         {
-           status = EIO;
-           break;
-         }
+         break;
        status = mu_stream_write (dst, buf, n, NULL);
        if (status)
          break;
@@ -120,6 +117,10 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t 
size,
 
   if (pcsz)
     *pcsz = total;
+  /* FIXME: When EOF error code is implemented:
+  else if (total == 0)
+    status = EOF;
+  */
   free (buf);
   return status;
 }
diff --git a/libmailutils/stream/temp_file_stream.c 
b/libmailutils/stream/temp_file_stream.c
index 29ca359..c1dfacd 100644
--- a/libmailutils/stream/temp_file_stream.c
+++ b/libmailutils/stream/temp_file_stream.c
@@ -29,37 +29,67 @@
 #include <mailutils/nls.h>
 #include <mailutils/stream.h>
 #include <mailutils/sys/stream.h>
-#include <mailutils/sys/file_stream.h>
+#include <mailutils/sys/temp_file_stream.h>
 #include <mailutils/util.h>
 
 
 static int
 fd_temp_open (struct _mu_stream *str)
 {
-  struct _mu_file_stream *fstr = (struct _mu_file_stream *) str;
-  int fd = mu_tempfile (fstr->filename, NULL);
-  if (fd == -1)
-    return errno;
-  fstr->fd = fd;
-  return 0;
+  struct _mu_temp_file_stream *fstr = (struct _mu_temp_file_stream *) str;
+  return mu_tempfile (&fstr->hints, fstr->hflags, &fstr->stream.fd, NULL);
+}
+
+static void
+fd_temp_done (struct _mu_stream *str)
+{
+  struct _mu_temp_file_stream *fstr = (struct _mu_temp_file_stream *) str;
+  if (fstr->hflags & MU_TEMPFILE_TMPDIR)
+    free (fstr->hints.tmpdir);
+  if (fstr->hflags & MU_TEMPFILE_SUFFIX)
+    free (fstr->hints.suffix);
+  if (fstr->file_done)
+    fstr->file_done (&fstr->stream.stream);
 }
-  
+
 int
-mu_temp_file_stream_create (mu_stream_t *pstream, const char *dir)
+mu_temp_file_stream_create (mu_stream_t *pstream,
+                           struct mu_tempfile_hints *hints, int flags)
 {
   int rc;
   struct _mu_file_stream *str;
   mu_stream_t stream;
+
+  if (flags && !hints)
+    return EINVAL;
   rc = _mu_file_stream_create (&str,
-                              sizeof (struct _mu_file_stream),
-                              dir,
+                              sizeof (struct _mu_temp_file_stream),
+                              NULL,
                               -1,
                               MU_STREAM_RDWR | MU_STREAM_SEEK |
                               MU_STREAM_CREAT | 
                               MU_STREAM_AUTOCLOSE);
   if (rc == 0)
     {
-      str->stream.open = fd_temp_open;
+      struct _mu_temp_file_stream *tstr = (struct _mu_temp_file_stream *)str;
+      tstr->stream.stream.open = fd_temp_open;
+      tstr->file_done = tstr->stream.stream.done;
+      tstr->stream.stream.done = fd_temp_done;
+
+      if ((flags & MU_TEMPFILE_TMPDIR) &&
+         (tstr->hints.tmpdir = strdup (hints->tmpdir)) == NULL)
+       {
+         mu_stream_unref ((mu_stream_t) str);
+         return ENOMEM;
+       }
+      if ((flags & MU_TEMPFILE_SUFFIX) &&
+         (tstr->hints.suffix = strdup (hints->suffix)) == NULL)
+       {
+         mu_stream_unref ((mu_stream_t) str);
+         return ENOMEM;
+       }
+      tstr->hflags = flags & ~MU_TEMPFILE_MKDIR;
+      
       str->flags = _MU_FILE_STREAM_TEMP;
       stream = (mu_stream_t) str;
       rc = mu_stream_open (stream);
diff --git a/libmailutils/string/mkfilename.c b/libmailutils/string/mkfilename.c
index 7bf0665..d815e0b 100644
--- a/libmailutils/string/mkfilename.c
+++ b/libmailutils/string/mkfilename.c
@@ -25,22 +25,27 @@
 #include <mailutils/util.h>
 
 char *
-mu_make_file_name (const char *dir, const char *file)
+mu_make_file_name_suf (const char *dir, const char *file, const char *suf)
 {
   char *tmp;
   size_t dirlen = strlen (dir);
+  size_t suflen = suf ? strlen (suf) : 0;
+  size_t fillen = strlen (file);
   size_t len;
 
   while (dirlen > 0 && dir[dirlen-1] == '/')
     dirlen--;
   
-  len = dirlen + 1 + strlen (file);
+  len = dirlen + 1 + fillen + suflen;
   tmp = mu_alloc (len + 1);
   if (tmp)
     {
       memcpy (tmp, dir, dirlen);
       tmp[dirlen++] = '/';
-      strcpy (tmp + dirlen, file);
+      memcpy (tmp + dirlen, file, fillen);
+      if (suf)
+       memcpy (tmp + dirlen + fillen, suf, suflen);
+      tmp[len] = 0;
     }
   return tmp;
 }
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 67b62fc..cfcea39 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -48,6 +48,7 @@ noinst_PROGRAMS = \
  listop\
  mailcap\
  prop\
+ tempfile\
  url-parse\
  wicket\
  wsp
diff --git a/libmailutils/tests/tempfile.c b/libmailutils/tests/tempfile.c
new file mode 100644
index 0000000..0df762f
--- /dev/null
+++ b/libmailutils/tests/tempfile.c
@@ -0,0 +1,169 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+   GNU Mailutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GNU Mailutils is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mailutils/util.h>
+#include <mailutils/errno.h>
+#include <mailutils/error.h>
+#include <mailutils/stream.h>
+
+char *progname;
+
+void
+usage (FILE *fp, int code)
+{
+  fprintf (fp,
+          "usage: %s [-tmpdir=DIR] [-suffix=SUF] [-dry-run | -unlink] { file | 
dir }\n",
+          progname);
+  exit (code);
+}
+
+int
+main (int argc, char **argv)
+{
+  struct mu_tempfile_hints hints, *phints;
+  int flags = 0;
+  int fd;
+  int *pfd = &fd;
+  char *filename;
+  char **pname = &filename;
+  char *infile = NULL;
+  int verify = 0;
+  int verbose = 0;
+
+  progname = argv[0];
+  
+  if (argc == 1)
+    usage (stdout, 0);
+  
+  while (--argc)
+    {
+      char *arg = *++argv;
+
+      if (strncmp (arg, "-tmpdir=", 8) == 0)
+       {
+         hints.tmpdir = arg + 8;
+         flags |= MU_TEMPFILE_TMPDIR;
+       }
+      else if (strncmp (arg, "-suffix=", 8) == 0)
+       {
+         hints.suffix = arg + 8;
+         flags |= MU_TEMPFILE_SUFFIX;
+       }
+      else if (strcmp (arg, "-dry-run") == 0)
+       pfd = NULL;
+      else if (strcmp (arg, "-unlink") == 0)
+       pname = NULL;
+      else if (strncmp (arg, "-infile=", 8) == 0)
+       infile = arg + 8;
+      else if (strncmp (arg, "-verify", 7) == 0)
+       verify = 1;
+      else if (strncmp (arg, "-verbose", 8) == 0)
+       verbose = 1;
+      else
+       break;
+    }
+
+  if (argv[0] == NULL)
+    usage (stderr, 1);
+  if (strcmp (argv[0], "file") == 0)
+    /* nothing */;
+  else if (strcmp (argv[0], "dir") == 0)
+    flags |= MU_TEMPFILE_MKDIR;
+  else
+    usage (stderr, 1);
+
+  if (pname == NULL && pfd == NULL)
+    {
+      mu_error ("both -unlink and -dry-run given");
+      exit (1);
+    }
+
+  if (infile)
+    {
+      if (flags & MU_TEMPFILE_MKDIR)
+       {
+         mu_error ("-infile is useless with dir");
+         exit (1);
+       }
+      else if (pfd == NULL)
+       {
+         mu_error ("-infile is useless with -dry-run");
+         exit (1);
+       }
+    }
+
+  if (verify && pfd == NULL)
+    {
+      mu_error ("-verify is useless with -dry-run");
+      exit (1);
+    }
+  
+  phints = flags ? &hints : NULL;
+  
+  MU_ASSERT (mu_tempfile (phints, flags, pfd, pname));
+
+  if (filename)
+    printf ("created file name %s\n", filename);
+    
+  if (!pfd)
+    return 0;
+  
+  if (infile)
+    {
+      mu_stream_t in, out;
+      mu_off_t size;
+      
+      if (strcmp (infile, "-") == 0)
+       MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
+      else
+       MU_ASSERT (mu_file_stream_create (&in, infile, MU_STREAM_READ));
+
+      MU_ASSERT (mu_fd_stream_create (&out, filename, fd, MU_STREAM_WRITE));
+      MU_ASSERT (mu_stream_copy (out, in, 0, &size));
+      if (verbose)
+       printf ("copied %lu bytes to the temporary\n", (unsigned long) size);
+      mu_stream_unref (out);
+      mu_stream_unref (in);
+    }
+
+  if (verify)
+    {
+      mu_stream_t in, out;
+      mu_off_t size;
+
+      MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));
+      MU_ASSERT (mu_fd_stream_create (&in, filename, fd,
+                                     MU_STREAM_READ|MU_STREAM_SEEK));
+      MU_ASSERT (mu_stream_copy (out, in, 0, &size));
+      if (verbose)
+       printf ("dumped %lu bytes\n", (unsigned long) size);
+      mu_stream_unref (out);
+      mu_stream_unref (in);
+    }
+
+  close (fd);
+  
+  return 0;
+}
+
+         
diff --git a/libmu_scm/mu_body.c b/libmu_scm/mu_body.c
index 7f3d85c..4d56f73 100644
--- a/libmu_scm/mu_body.c
+++ b/libmu_scm/mu_body.c
@@ -55,18 +55,13 @@ static int
 mu_scm_body_print (SCM body_smob, SCM port, scm_print_state * pstate)
 {
   struct mu_body *mbp = (struct mu_body *) SCM_CDR (body_smob);
-  size_t b_size = 0, b_lines = 0, len = 0;
+  size_t b_size = 0, b_lines = 0;
   char buffer[512];
 
   mu_body_size (mbp->body, &b_size);
   mu_body_lines (mbp->body, &b_lines);
-  buffer[0] = 0;
-  mu_body_get_filename (mbp->body, buffer, sizeof (buffer), &len);
-
-  scm_puts ("#<body \"", port);
-  scm_puts (buffer, port);
-  scm_puts ("\" ", port);
 
+  scm_puts ("#<body ", port);
   snprintf (buffer, sizeof (buffer), "%3lu %-5lu",
            (unsigned long) b_lines, (unsigned long) b_size);
   scm_puts (buffer, port);
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 5c0dd1b..b4f2935 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -1391,7 +1391,7 @@ mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted)
       (status = mu_locker_lock (mailbox->locker)) != 0)
     return status;
 
-  status = mu_temp_file_stream_create (&tempstr, NULL);
+  status = mu_temp_file_stream_create (&tempstr, NULL, 0);
   if (status == 0)
     {
       sigset_t signalset;
diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c
index 9b658bc..dd44816 100644
--- a/libproto/pop/mbox.c
+++ b/libproto/pop/mbox.c
@@ -361,7 +361,7 @@ _pop_message_get_stream (struct _pop3_message *mpm, 
mu_stream_t *pstr)
          
          if (!mpd->cache)
            {
-             status = mu_temp_file_stream_create (&mpd->cache, NULL);
+             status = mu_temp_file_stream_create (&mpd->cache, NULL, 0);
              if (status)
                /* FIXME: Try to recover first */
                break;
diff --git a/maidag/deliver.c b/maidag/deliver.c
index 47d9a54..568ec51 100644
--- a/maidag/deliver.c
+++ b/maidag/deliver.c
@@ -34,7 +34,7 @@ make_tmp (const char *from)
       exit (EX_TEMPFAIL);
     } 
 
-  rc = mu_temp_file_stream_create (&out, NULL);
+  rc = mu_temp_file_stream_create (&out, NULL, 0);
   if (rc)
     {
       maidag_error (_("unable to open temporary file: %s"), mu_strerror (rc));
diff --git a/maidag/lmtp.c b/maidag/lmtp.c
index 77a54a4..4360e9f 100644
--- a/maidag/lmtp.c
+++ b/maidag/lmtp.c
@@ -366,7 +366,7 @@ cfun_data (mu_stream_t iostr, char *arg)
       return 1;
     }
 
-  rc = mu_temp_file_stream_create (&tempstr, NULL);
+  rc = mu_temp_file_stream_create (&tempstr, NULL, 0);
   if (rc)
     {
       maidag_error (_("unable to open temporary file: %s"), mu_strerror (rc));
diff --git a/mail/escape.c b/mail/escape.c
index efa2d79..27d8c2f 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -324,11 +324,19 @@ escape_run_editor (char *ed, int argc, char **argv, 
compose_env_t *env)
   if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
     {
       char *filename;
-      int fd = mu_tempfile (NULL, &filename);
-      FILE *fp = fdopen (fd, "w+");
+      int fd;
+      FILE *fp;
       char buffer[512];
       int rc;
       
+      rc = mu_tempfile (NULL, 0, &fd, &filename);
+      if (rc)
+        {
+           mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc);
+           return rc;
+        }
+
+      fp = fdopen (fd, "w+");
       dump_headers (fp, env);
 
       rewind (env->file);
@@ -639,8 +647,7 @@ escape_pipe (int argc, char **argv, compose_env_t *env)
       return 1;
     }
 
-  fd = mu_tempfile (NULL, NULL);
-  if (fd == -1)
+  if (mu_tempfile (NULL, 0, &fd, NULL))
     return 1;
 
   if ((pid = fork ()) < 0)
diff --git a/mail/send.c b/mail/send.c
index 4594309..62437b4 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -305,8 +305,18 @@ fill_body (mu_message_t msg, mu_stream_t instr)
   mu_stream_t stream = NULL;
   mu_off_t n;
   
-  mu_message_get_body (msg, &body);
-  mu_body_get_streamref (body, &stream);
+  rc = mu_message_get_body (msg, &body);
+  if (rc)
+    {
+      mu_error (_("cannot get message body: %s"), mu_strerror (rc));
+      return 1;
+    }
+  rc = mu_body_get_streamref (body, &stream);
+  if (rc)
+    {
+      mu_error (_("cannot get body: %s"), mu_strerror (rc));
+      return 1;
+    }
 
   rc = mu_stream_copy (stream, instr, 0, &n);
   mu_stream_destroy (&stream);
@@ -428,16 +438,16 @@ int
 mail_send0 (compose_env_t * env, int save_to)
 {
   int done = 0;
-  int fd;
+  int fd, rc;
   char *filename;
   char *savefile = NULL;
   int int_cnt;
   char *escape;
 
-  fd = mu_tempfile (NULL, &filename);
-  if (fd == -1)
+  rc = mu_tempfile (NULL, 0, &fd, &filename);
+  if (rc)
     {
-      util_error (_("Cannot open temporary file"));
+      util_error (_("Cannot open temporary file: %s"), mu_strerror (rc));
       return 1;
     }
 
diff --git a/mh/burst.c b/mh/burst.c
index 03b7eb7..8396106 100644
--- a/mh/burst.c
+++ b/mh/burst.c
@@ -396,7 +396,7 @@ flush_stream (struct burst_stream *bs, char *buf, size_t 
size)
     return;
   if (!bs->stream)
     {
-      if ((rc = mu_temp_file_stream_create (&bs->stream, NULL))) 
+      if ((rc = mu_temp_file_stream_create (&bs->stream, NULL, 0))) 
        {
          mu_error (_("Cannot open temporary file: %s"),
                    mu_strerror (rc));
diff --git a/mh/prompter.c b/mh/prompter.c
index 062bd9c..4a1ede2 100644
--- a/mh/prompter.c
+++ b/mh/prompter.c
@@ -193,7 +193,7 @@ main (int argc, char **argv)
       return 1;
     }
   
-  if ((rc = mu_temp_file_stream_create (&tmp, NULL))) 
+  if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0))) 
     {
       mu_error (_("Cannot open temporary file: %s"),
                mu_strerror (rc));


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]