2010-09-01 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / iobuf.c
index e3ea0b4..b9bed32 100644 (file)
@@ -1,6 +1,6 @@
 /* iobuf.c  -  File Handling for OpenPGP.
- * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006,
- *               2007, 2008, 2009  Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
+ *               2009, 2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -37,6 +37,8 @@
 # include <swis.h>
 #endif /* __riscos__ */
 
+#include <assuan.h>
+
 #include "util.h"
 #include "sysutils.h"
 #include "iobuf.h"
    test "armored_key_8192" in armor.test! */
 #define IOBUF_BUFFER_SIZE  8192
 
-/* We don't want to use the STDIO based backend.  If you change this
-   be aware that there is no fsync support for the stdio backend.  */
-#undef FILE_FILTER_USES_STDIO
-
 /*-- End configurable part.  --*/
 
 
-/* Under W32 the default is to use the setmode call.  Define a macro
-   which allows us to enable this call.  */
 #ifdef HAVE_W32_SYSTEM
-# define USE_SETMODE 1
-#endif /*HAVE_W32_SYSTEM*/
-
+# ifdef HAVE_W32CE_SYSTEM
+#  define FD_FOR_STDIN  (es_fileno (es_stdin))
+#  define FD_FOR_STDOUT (es_fileno (es_stdout))
+# else
+#  define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
+#  define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
+# endif
+#else /*!HAVE_W32_SYSTEM*/
+# define FD_FOR_STDIN  (0)
+# define FD_FOR_STDOUT (1)
+#endif /*!HAVE_W32_SYSTEM*/
 
-/* Definition of constants and macros used by our file filter
-   implementation.  What we define here are 3 macros to make the
-   appropriate calls:
-
-   my_fileno 
-     Is expanded to fileno(a) if using a stdion backend and to a if we
-     are using the low-level backend.
-
-   my_fopen 
-     Is defined to fopen for the stdio backend and to direct_open if
-     we are using the low-evel backend.
-
-   my_fopen_ro 
-     Is defined to fopen for the stdio backend and to fd_cache_open if
-     we are using the low-evel backend.
-
-   fp_or_fd_t
-     Is the type we use for the backend stream or file descriptor.
-
-   INVALID_FP, FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT
-     Are macros defined depending on the used backend.
-
-*/
-#ifdef FILE_FILTER_USES_STDIO
-# define my_fileno(a)     fileno ((a))
-# define my_fopen_ro(a,b) fopen ((a),(b))
-# define my_fopen(a,b)    fopen ((a),(b))
-  typedef FILE *fp_or_fd_t;
-# define INVALID_FP              NULL
-# define FILEP_OR_FD_FOR_STDIN   (stdin)
-# define FILEP_OR_FD_FOR_STDOUT  (stdout)
-#else /*!FILE_FILTER_USES_STDIO*/
-# define my_fopen_ro(a,b) fd_cache_open ((a),(b))
-# define my_fopen(a,b)    direct_open ((a),(b))
-# ifdef HAVE_W32_SYSTEM
-   /* (We assume that a HANDLE first into an int.)  */
-#  define my_fileno(a)  ((int)(a))
-   typedef HANDLE fp_or_fd_t;
-#  define INVALID_FP             ((HANDLE)-1)
-#  define FILEP_OR_FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
-#  define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
-#  undef USE_SETMODE
-# else /*!HAVE_W32_SYSTEM*/
-#  define my_fileno(a)  (a)
-   typedef int fp_or_fd_t;
-#  define INVALID_FP             (-1)
-#  define FILEP_OR_FD_FOR_STDIN  (0)
-#  define FILEP_OR_FD_FOR_STDOUT (1)
-# endif /*!HAVE_W32_SYSTEM*/
-#endif /*!FILE_FILTER_USES_STDIO*/
 
 /* The context used by the file filter.  */
 typedef struct
 {
-  fp_or_fd_t fp;       /* Open file pointer or handle.  */
+  gnupg_fd_t fp;       /* Open file pointer or handle.  */
   int keep_open; 
   int no_cache;
   int eof_seen;
   int print_only_name; /* Flags indicating that fname is not a real file.  */
   char fname[1];       /* Name of the file.  */
-}
-file_filter_ctx_t;
+} file_filter_ctx_t;
 
 
-/* If we are not using stdio as the backend we make use of a "close
-   cache".  */
-#ifndef FILE_FILTER_USES_STDIO
+/* Object to control the "close cache".  */
 struct close_cache_s
 {
   struct close_cache_s *next;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   char fname[1];
 };
 typedef struct close_cache_s *close_cache_t;
 static close_cache_t close_cache;
-#endif /*!FILE_FILTER_USES_STDIO*/
 
 
 
@@ -150,8 +100,8 @@ typedef struct
   int eof_seen;
   int print_only_name; /* Flag indicating that fname is not a real file.  */
   char fname[1];       /* Name of the file */
-}
-sock_filter_ctx_t;
+
+sock_filter_ctx_t;
 #endif /*HAVE_W32_SYSTEM*/
 
 /* The first partial length header block must be of size 512
@@ -187,7 +137,6 @@ static int translate_file_handle (int fd, int for_write);
 
 
 \f
-#ifndef FILE_FILTER_USES_STDIO
 /* This is a replacement for strcmp.  Under W32 it does not
    distinguish between backslash and slash.  */
 static int
@@ -221,7 +170,7 @@ fd_cache_invalidate (const char *fname)
 
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          if (DBG_IOBUF)
            log_debug ("                did (%s)\n", cc->fname);
@@ -231,7 +180,7 @@ fd_cache_invalidate (const char *fname)
 #else
          rc = close (cc->fp);
 #endif
-         cc->fp = INVALID_FP;
+         cc->fp = GNUPG_INVALID_FD;
        }
     }
   return rc;
@@ -254,7 +203,7 @@ fd_cache_synchronize (const char *fname)
 
   for (cc=close_cache; cc; cc = cc->next )
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          if (DBG_IOBUF)
            log_debug ("                 did (%s)\n", cc->fname);
@@ -270,7 +219,7 @@ fd_cache_synchronize (const char *fname)
 }
 
 
-static fp_or_fd_t
+static gnupg_fd_t
 direct_open (const char *fname, const char *mode)
 {
 #ifdef HAVE_W32_SYSTEM
@@ -286,7 +235,7 @@ direct_open (const char *fname, const char *mode)
   if (strchr (mode, '+'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       da = GENERIC_READ | GENERIC_WRITE;
       cd = OPEN_EXISTING;
       sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
@@ -294,7 +243,7 @@ direct_open (const char *fname, const char *mode)
   else if (strchr (mode, 'w'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       da = GENERIC_WRITE;
       cd = CREATE_ALWAYS;
       sm = FILE_SHARE_WRITE;
@@ -306,7 +255,21 @@ direct_open (const char *fname, const char *mode)
       sm = FILE_SHARE_READ;
     }
 
+#ifdef HAVE_W32CE_SYSTEM
+  {
+    wchar_t *wfname = utf8_to_wchar (fname);
+    if (wfname)
+      {
+        hfile = CreateFile (wfname, da, sm, NULL, cd,
+                            FILE_ATTRIBUTE_NORMAL, NULL);
+        xfree (wfname);
+      }
+    else
+      hfile = INVALID_HANDLE_VALUE;
+  }
+#else
   hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
   return hfile;
 #else /*!HAVE_W32_SYSTEM*/
   int oflag;
@@ -316,13 +279,13 @@ direct_open (const char *fname, const char *mode)
   if (strchr (mode, '+'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       oflag = O_RDWR;
     }
   else if (strchr (mode, 'w'))
     {
       if (fd_cache_invalidate (fname))
-        return INVALID_FP;
+        return GNUPG_INVALID_FD;
       oflag = O_WRONLY | O_CREAT | O_TRUNC;
     }
   else
@@ -357,7 +320,7 @@ direct_open (const char *fname, const char *mode)
  * Note that this caching strategy only works if the process does not chdir.
  */
 static void
-fd_cache_close (const char *fname, fp_or_fd_t fp)
+fd_cache_close (const char *fname, gnupg_fd_t fp)
 {
   close_cache_t cc;
 
@@ -376,7 +339,7 @@ fd_cache_close (const char *fname, fp_or_fd_t fp)
   /* try to reuse a slot */
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
          cc->fp = fp;
          if (DBG_IOBUF)
@@ -397,7 +360,7 @@ fd_cache_close (const char *fname, fp_or_fd_t fp)
 /*
  * Do an direct_open on FNAME but first try to reuse one from the fd_cache
  */
-static fp_or_fd_t
+static gnupg_fd_t
 fd_cache_open (const char *fname, const char *mode)
 {
   close_cache_t cc;
@@ -405,10 +368,10 @@ fd_cache_open (const char *fname, const char *mode)
   assert (fname);
   for (cc = close_cache; cc; cc = cc->next)
     {
-      if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname))
+      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
        {
-         fp_or_fd_t fp = cc->fp;
-         cc->fp = INVALID_FP;
+         gnupg_fd_t fp = cc->fp;
+         cc->fp = GNUPG_INVALID_FD;
          if (DBG_IOBUF)
            log_debug ("fd_cache_open (%s) using cached fp\n", fname);
 #ifdef HAVE_W32_SYSTEM
@@ -416,13 +379,13 @@ fd_cache_open (const char *fname, const char *mode)
            {
              log_error ("rewind file failed on handle %p: ec=%d\n",
                         fp, (int) GetLastError ());
-             fp = INVALID_FP;
+             fp = GNUPG_INVALID_FD;
            }
 #else
          if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
            {
              log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
-             fp = INVALID_FP;
+             fp = GNUPG_INVALID_FD;
            }
 #endif
          return fp;
@@ -433,8 +396,6 @@ fd_cache_open (const char *fname, const char *mode)
   return direct_open (fname, mode);
 }
 
-#endif /*FILE_FILTER_USES_STDIO */
-
 
 /****************
  * Read data from a file into buf which has an allocated length of *LEN.
@@ -465,78 +426,13 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
             size_t * ret_len)
 {
   file_filter_ctx_t *a = opaque;
-  fp_or_fd_t f = a->fp;
+  gnupg_fd_t f = a->fp;
   size_t size = *ret_len;
   size_t nbytes = 0;
   int rc = 0;
 
   (void)chain; /* Not used.  */
 
-#ifdef FILE_FILTER_USES_STDIO
-  if (control == IOBUFCTRL_UNDERFLOW)
-    {
-      assert (size);  /* We need a buffer. */
-      if (feof (f))
-       { 
-          /* On terminals you could easily read as many EOFs as you
-             call fread() or fgetc() repeatly.  Every call will block
-             until you press CTRL-D. So we catch this case before we
-             call fread() again.  */
-         rc = -1;              
-         *ret_len = 0;         
-       }
-      else
-       {
-         clearerr (f);
-         nbytes = fread (buf, 1, size, f);
-         if (feof (f) && !nbytes)
-           {
-             rc = -1;  /* Okay: we can return EOF now. */
-           }
-         else if (ferror (f) && errno != EPIPE)
-           {
-             rc = gpg_error_from_syserror ();
-             log_error ("%s: read error: %s\n", a->fname, strerror (errno));
-           }
-         *ret_len = nbytes;
-       }
-    }
-  else if (control == IOBUFCTRL_FLUSH)
-    {
-      if (size)
-       {
-         clearerr (f);
-         nbytes = fwrite (buf, 1, size, f);
-         if (ferror (f))
-           {
-             rc = gpg_error_from_syserror ();
-             log_error ("%s: write error: %s\n", a->fname, strerror (errno));
-           }
-       }
-      *ret_len = nbytes;
-    }
-  else if (control == IOBUFCTRL_INIT)
-    {
-      a->keep_open = a->no_cache = 0;
-    }
-  else if (control == IOBUFCTRL_DESC)
-    {
-      *(char **) buf = "file_filter";
-    }
-  else if (control == IOBUFCTRL_FREE)
-    {
-      if (f != stdin && f != stdout)
-       {
-         if (DBG_IOBUF)
-           log_debug ("%s: close fd %d\n", a->fname, fileno (f));
-         if (!a->keep_open)
-           fclose (f);
-       }
-      f = NULL;
-      xfree (a); /* We can free our context now. */
-    }
-#else /* !stdio implementation */
-
   if (control == IOBUFCTRL_UNDERFLOW)
     {
       assert (size); /* We need a buffer.  */
@@ -666,27 +562,17 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     }
   else if (control == IOBUFCTRL_FREE)
     {
-#ifdef HAVE_W32_SYSTEM
-      if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT)
-       {
-         if (DBG_IOBUF)
-           log_debug ("%s: close handle %p\n", a->fname, f);
-         if (!a->keep_open)
-           fd_cache_close (a->no_cache ? NULL : a->fname, f);
-       }
-#else
-      if ((int) f != 0 && (int) f != 1)
+      if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
        {
          if (DBG_IOBUF)
-           log_debug ("%s: close fd %d\n", a->fname, f);
+           log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f));
          if (!a->keep_open)
            fd_cache_close (a->no_cache ? NULL : a->fname, f);
        }
-      f = INVALID_FP;
-#endif
+      f = GNUPG_INVALID_FD;
       xfree (a); /* We can free our context now. */
     }
-#endif /* !stdio implementation. */
+
   return rc;
 }
 
@@ -1188,7 +1074,14 @@ iobuf_cancel (iobuf_t a)
     {
       /* Argg, MSDOS does not allow to remove open files.  So
        * we have to do it here */
+#ifdef HAVE_W32CE_SYSTEM
+      wchar_t *wtmp = utf8_to_wchar (remove_name);
+      if (wtmp)
+        DeleteFile (wtmp);
+      xfree (wtmp);
+#else
       remove (remove_name);
+#endif
       xfree (remove_name);
     }
 #endif
@@ -1262,9 +1155,9 @@ iobuf_is_pipe_filename (const char *fname)
 
 
 /* Either open the file specified by the file descriptor FD or - if FD
-   is GNUPG_INVALID_FD - the file with name FNAME.  As of now MODE is
-   assumed to be "rb" if FNAME is used.  In contrast to iobuf_fdopen
-   the fiel descriptor FD will not be closed during an iobuf_close. */
+   is -1, the file with name FNAME.  As of now MODE is assumed to be
+   "rb" if FNAME is used.  In contrast to iobuf_fdopen the file
+   descriptor FD will not be closed during an iobuf_close.  */
 iobuf_t
 iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode)
 {
@@ -1273,15 +1166,7 @@ iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode)
   if (fd == GNUPG_INVALID_FD)
     a = iobuf_open (fname);
   else
-    {
-      gnupg_fd_t fd2;
-
-      fd2 = dup (fd);
-      if (fd2 == GNUPG_INVALID_FD)
-        a = NULL;
-      else
-        a = iobuf_fdopen (fd2, mode);
-    }
+    a = iobuf_fdopen_nc (FD2INT(fd), mode);
   return a;
 }
 
@@ -1294,7 +1179,7 @@ iobuf_t
 iobuf_open (const char *fname)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
   int print_only = 0;
@@ -1302,16 +1187,13 @@ iobuf_open (const char *fname)
 
   if (!fname || (*fname == '-' && !fname[1]))
     {
-      fp = FILEP_OR_FD_FOR_STDIN;
-#ifdef USE_SETMODE
-      setmode (my_fileno (fp), O_BINARY);
-#endif
+      fp = FD_FOR_STDIN;
       fname = "[stdin]";
       print_only = 1;
     }
   else if ((fd = check_special_filename (fname)) != -1)
     return iobuf_fdopen (translate_file_handle (fd, 0), "rb");
-  else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP)
+  else if ((fp = fd_cache_open (fname, "rb")) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (1, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1326,45 +1208,55 @@ iobuf_open (const char *fname)
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
     log_debug ("iobuf-%d.%d: open `%s' fd=%d\n",
-              a->no, a->subno, fname, (int) my_fileno (fcx->fp));
+              a->no, a->subno, fname, FD2INT (fcx->fp));
 
   return a;
 }
 
-/****************
- * Create a head iobuf for reading or writing from/to a file
- * Returns: NULL if an error occures and sets ERRNO.
- */
-iobuf_t
-iobuf_fdopen (int fd, const char *mode)
+
+static iobuf_t
+do_iobuf_fdopen (int fd, const char *mode, int keep_open)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
 
-#ifdef FILE_FILTER_USES_STDIO
-  if (!(fp = fdopen (fd, mode)))
-    return NULL;
-#else
-  fp = (fp_or_fd_t) fd;
-#endif
+  fp = INT2FD (fd);
+
   a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + 20);
   fcx->fp = fp;
   fcx->print_only_name = 1;
+  fcx->keep_open = keep_open;
   sprintf (fcx->fname, "[fd %d]", fd);
   a->filter = file_filter;
   a->filter_ov = fcx;
   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+    log_debug ("iobuf-%d.%d: fdopen%s `%s'\n",
+               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
   return a;
 }
 
 
+/* Create a head iobuf for reading or writing from/to a file Returns:
+ * NULL and sets ERRNO if an error occured.  */
+iobuf_t
+iobuf_fdopen (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 0);
+}
+
+iobuf_t
+iobuf_fdopen_nc (int fd, const char *mode)
+{
+  return do_iobuf_fdopen (fd, mode, 1);
+}
+
+
 iobuf_t
 iobuf_sockopen (int fd, const char *mode)
 {
@@ -1384,7 +1276,7 @@ iobuf_sockopen (int fd, const char *mode)
   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
   if (DBG_IOBUF)
     log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
-  iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
+  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
 #else
   a = iobuf_fdopen (fd, mode);
 #endif
@@ -1398,7 +1290,7 @@ iobuf_t
 iobuf_create (const char *fname)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
   int print_only = 0;
@@ -1406,16 +1298,13 @@ iobuf_create (const char *fname)
 
   if (!fname || (*fname == '-' && !fname[1]))
     {
-      fp = FILEP_OR_FD_FOR_STDOUT;
-#ifdef USE_SETMODE
-      setmode (my_fileno (fp), O_BINARY);
-#endif
+      fp = FD_FOR_STDOUT;
       fname = "[stdout]";
       print_only = 1;
     }
   else if ((fd = check_special_filename (fname)) != -1)
     return iobuf_fdopen (translate_file_handle (fd, 1), "wb");
-  else if ((fp = my_fopen (fname, "wb")) == INVALID_FP)
+  else if ((fp = direct_open (fname, "wb")) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1435,52 +1324,18 @@ iobuf_create (const char *fname)
   return a;
 }
 
-/****************
- * append to an iobuf; if the file does not exist, create it.
- * cannot be used for stdout.
- * Note: This is not used.
- */
-#if 0                          /* not used */
-iobuf_t
-iobuf_append (const char *fname)
-{
-  iobuf_t a;
-  FILE *fp;
-  file_filter_ctx_t *fcx;
-  size_t len;
-
-  if (!fname)
-    return NULL;
-  else if (!(fp = my_fopen (fname, "ab")))
-    return NULL;
-  a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
-  fcx = m_alloc (sizeof *fcx + strlen (fname));
-  fcx->fp = fp;
-  strcpy (fcx->fname, fname);
-  a->real_fname = m_strdup (fname);
-  a->filter = file_filter;
-  a->filter_ov = fcx;
-  file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
-  file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
-  if (DBG_IOBUF)
-    log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno,
-               a->desc?a->desc:"?");
-
-  return a;
-}
-#endif
 
 iobuf_t
 iobuf_openrw (const char *fname)
 {
   iobuf_t a;
-  fp_or_fd_t fp;
+  gnupg_fd_t fp;
   file_filter_ctx_t *fcx;
   size_t len;
 
   if (!fname)
     return NULL;
-  else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP)
+  else if ((fp = direct_open (fname, "r+b")) == GNUPG_INVALID_FD)
     return NULL;
   a = iobuf_alloc (2, IOBUF_BUFFER_SIZE);
   fcx = xmalloc (sizeof *fcx + strlen (fname));
@@ -1500,12 +1355,15 @@ iobuf_openrw (const char *fname)
 
 
 int
-iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
+iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
 {
-  if (cmd == 1)
-    {                          /* keep system filepointer/descriptor open */
+  if (cmd == IOBUF_IOCTL_KEEP_OPEN)
+    {                          
+      /* Keep system filepointer/descriptor open.  This was used in
+         the past by http.c; this ioctl is not directly used
+         anymore.  */
       if (DBG_IOBUF)
-       log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n",
+       log_debug ("iobuf-%d.%d: ioctl `%s' keep_open=%d\n",
                   a ? a->no : -1, a ? a->subno : -1, 
                    a && a->desc ? a->desc : "?",
                   intval);
@@ -1525,22 +1383,20 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 2)
-    {                          /* invalidate cache */
+  else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
+    {
       if (DBG_IOBUF)
        log_debug ("iobuf-*.*: ioctl `%s' invalidate\n",
                   ptrval ? (char *) ptrval : "?");
       if (!a && !intval && ptrval)
        {
-#ifndef FILE_FILTER_USES_STDIO
          if (fd_cache_invalidate (ptrval))
             return -1;
-#endif
          return 0;
        }
     }
-  else if (cmd == 3)
-    {                          /* disallow/allow caching */
+  else if (cmd == IOBUF_IOCTL_NO_CACHE)
+    {
       if (DBG_IOBUF)
        log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
                   a ? a->no : -1, a ? a->subno : -1, 
@@ -1562,7 +1418,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
          }
 #endif
     }
-  else if (cmd == 4)
+  else if (cmd == IOBUF_IOCTL_FSYNC)
     {
       /* Do a fsync on the open fd and return any errors to the caller
          of iobuf_ioctl.  Note that we work on a file name here. */
@@ -1572,11 +1428,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
 
        if (!a && !intval && ptrval)
          {
-#ifndef FILE_FILTER_USES_STDIO
            return fd_cache_synchronize (ptrval);
-#else
-           return 0;
-#endif
          }
       }
 
@@ -2186,9 +2038,9 @@ iobuf_get_filelength (iobuf_t a, int *overflow)
     if ( !a->chain && a->filter == file_filter )
       {
         file_filter_ctx_t *b = a->filter_ov;
-        fp_or_fd_t fp = b->fp;
+        gnupg_fd_t fp = b->fp;
         
-#if defined(HAVE_W32_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
+#if defined(HAVE_W32_SYSTEM)
         ulong size;
         static int (* __stdcall get_file_size_ex) (void *handle,
                                                    LARGE_INTEGER *r_size);
@@ -2232,7 +2084,7 @@ iobuf_get_filelength (iobuf_t a, int *overflow)
         log_error ("GetFileSize for handle %p failed: %s\n",
                    fp, w32_strerror (0));
 #else
-        if ( !fstat(my_fileno(fp), &st) )
+        if ( !fstat (FD2INT (fp), &st) )
           return st.st_size;
         log_error("fstat() failed: %s\n", strerror(errno) );
 #endif
@@ -2255,9 +2107,9 @@ iobuf_get_fd (iobuf_t a)
     if (!a->chain && a->filter == file_filter)
       {
         file_filter_ctx_t *b = a->filter_ov;
-        fp_or_fd_t fp = b->fp;
+        gnupg_fd_t fp = b->fp;
 
-        return my_fileno (fp);
+        return FD2INT (fp);
       }
 
   return -1;
@@ -2336,13 +2188,6 @@ iobuf_seek (iobuf_t a, off_t newpos)
        }
       if (!a)
        return -1;
-#ifdef FILE_FILTER_USES_STDIO
-      if (fseeko (b->fp, newpos, SEEK_SET))
-       {
-         log_error ("can't fseek: %s\n", strerror (errno));
-         return -1;
-       }
-#else
 #ifdef HAVE_W32_SYSTEM
       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
        {
@@ -2357,7 +2202,6 @@ iobuf_seek (iobuf_t a, off_t newpos)
          return -1;
        }
 #endif
-#endif
     }
   a->d.len = 0;                        /* discard buffer */
   a->d.start = 0;
@@ -2524,10 +2368,12 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
 static int
 translate_file_handle (int fd, int for_write)
 {
-#ifdef HAVE_W32_SYSTEM
-# ifdef FILE_FILTER_USES_STDIO
-  fd = translate_sys2libc_fd (fd, for_write);
-# else
+#if defined(HAVE_W32CE_SYSTEM)
+  /* This is called only with one of the special filenames.  Under
+     W32CE the FD here is not a file descriptor but a rendezvous id,
+     thus we need to finish the pipe first.  */
+  fd = _assuan_w32ce_finish_pipe (fd, for_write);
+#elif defined(HAVE_W32_SYSTEM)
   {
     int x;
     
@@ -2548,7 +2394,6 @@ translate_file_handle (int fd, int for_write)
 
     fd = x;
   }
-# endif
 #else
   (void)for_write;
 #endif