LCOV - code coverage report
Current view: top level - common - iobuf.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 584 976 59.8 %
Date: 2015-11-05 17:10:59 Functions: 39 57 68.4 %

          Line data    Source code
       1             : /* iobuf.c  -  File Handling for OpenPGP.
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
       3             :  *               2009, 2010, 2011  Free Software Foundation, Inc.
       4             :  * Copyright (C) 2015  g10 Code GmbH
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * This file is free software; you can redistribute it and/or modify
       9             :  * it under the terms of either
      10             :  *
      11             :  *   - the GNU Lesser General Public License as published by the Free
      12             :  *     Software Foundation; either version 3 of the License, or (at
      13             :  *     your option) any later version.
      14             :  *
      15             :  * or
      16             :  *
      17             :  *   - the GNU General Public License as published by the Free
      18             :  *     Software Foundation; either version 2 of the License, or (at
      19             :  *     your option) any later version.
      20             :  *
      21             :  * or both in parallel, as here.
      22             :  *
      23             :  * This file is distributed in the hope that it will be useful,
      24             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      25             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      26             :  * GNU General Public License for more details.
      27             :  *
      28             :  * You should have received a copy of the GNU General Public License
      29             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      30             :  */
      31             : 
      32             : #include <config.h>
      33             : #include <stdio.h>
      34             : #include <stdlib.h>
      35             : #include <string.h>
      36             : #include <errno.h>
      37             : #include <ctype.h>
      38             : #include <assert.h>
      39             : #include <sys/types.h>
      40             : #include <sys/stat.h>
      41             : #include <fcntl.h>
      42             : #include <unistd.h>
      43             : #ifdef HAVE_W32_SYSTEM
      44             : # ifdef HAVE_WINSOCK2_H
      45             : #  include <winsock2.h>
      46             : # endif
      47             : # include <windows.h>
      48             : #endif
      49             : #ifdef __riscos__
      50             : # include <kernel.h>
      51             : # include <swis.h>
      52             : #endif /* __riscos__ */
      53             : 
      54             : #include <assuan.h>
      55             : 
      56             : #include "util.h"
      57             : #include "sysutils.h"
      58             : #include "iobuf.h"
      59             : 
      60             : /*-- Begin configurable part.  --*/
      61             : 
      62             : /* The size of the internal buffers.
      63             :    NOTE: If you change this value you MUST also adjust the regression
      64             :    test "armored_key_8192" in armor.test! */
      65             : #define IOBUF_BUFFER_SIZE  8192
      66             : 
      67             : /* To avoid a potential DoS with compression packets we better limit
      68             :    the number of filters in a chain.  */
      69             : #define MAX_NESTING_FILTER 64
      70             : 
      71             : /*-- End configurable part.  --*/
      72             : 
      73             : 
      74             : #ifdef HAVE_W32_SYSTEM
      75             : # ifdef HAVE_W32CE_SYSTEM
      76             : #  define FD_FOR_STDIN  (es_fileno (es_stdin))
      77             : #  define FD_FOR_STDOUT (es_fileno (es_stdout))
      78             : # else
      79             : #  define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
      80             : #  define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
      81             : # endif
      82             : #else /*!HAVE_W32_SYSTEM*/
      83             : # define FD_FOR_STDIN  (0)
      84             : # define FD_FOR_STDOUT (1)
      85             : #endif /*!HAVE_W32_SYSTEM*/
      86             : 
      87             : 
      88             : /* The context used by the file filter.  */
      89             : typedef struct
      90             : {
      91             :   gnupg_fd_t fp;       /* Open file pointer or handle.  */
      92             :   int keep_open;
      93             :   int no_cache;
      94             :   int eof_seen;
      95             :   int print_only_name; /* Flags indicating that fname is not a real file.  */
      96             :   char fname[1];       /* Name of the file.  */
      97             : } file_filter_ctx_t;
      98             : 
      99             : /* The context used by the estream filter.  */
     100             : typedef struct
     101             : {
     102             :   estream_t fp;        /* Open estream handle.  */
     103             :   int keep_open;
     104             :   int no_cache;
     105             :   int eof_seen;
     106             :   int print_only_name; /* Flags indicating that fname is not a real file.  */
     107             :   char fname[1];       /* Name of the file.  */
     108             : } file_es_filter_ctx_t;
     109             : 
     110             : 
     111             : /* Object to control the "close cache".  */
     112             : struct close_cache_s
     113             : {
     114             :   struct close_cache_s *next;
     115             :   gnupg_fd_t fp;
     116             :   char fname[1];
     117             : };
     118             : typedef struct close_cache_s *close_cache_t;
     119             : static close_cache_t close_cache;
     120             : 
     121             : 
     122             : 
     123             : #ifdef HAVE_W32_SYSTEM
     124             : typedef struct
     125             : {
     126             :   int sock;
     127             :   int keep_open;
     128             :   int no_cache;
     129             :   int eof_seen;
     130             :   int print_only_name;  /* Flag indicating that fname is not a real file.  */
     131             :   char fname[1];        /* Name of the file */
     132             : 
     133             : } sock_filter_ctx_t;
     134             : #endif /*HAVE_W32_SYSTEM*/
     135             : 
     136             : /* The first partial length header block must be of size 512 to make
     137             :  * it easier (and more efficient) we use a min. block size of 512 for
     138             :  * all chunks (but the last one) */
     139             : #define OP_MIN_PARTIAL_CHUNK      512
     140             : #define OP_MIN_PARTIAL_CHUNK_2POW 9
     141             : 
     142             : /* The context we use for the block filter (used to handle OpenPGP
     143             :    length information header).  */
     144             : typedef struct
     145             : {
     146             :   int use;
     147             :   size_t size;
     148             :   size_t count;
     149             :   int partial;     /* 1 = partial header, 2 in last partial packet.  */
     150             :   char *buffer;    /* Used for partial header.  */
     151             :   size_t buflen;   /* Used size of buffer.  */
     152             :   int first_c;     /* First character of a partial header (which is > 0).  */
     153             :   int eof;
     154             : }
     155             : block_filter_ctx_t;
     156             : 
     157             : 
     158             : /* Global flag to tell whether special file names are enabled.  See
     159             :    gpg.c for an explanation of these file names.  FIXME: This does not
     160             :    belong in the iobuf subsystem. */
     161             : static int special_names_enabled;
     162             : 
     163             : /* Local prototypes.  */
     164             : static int underflow (iobuf_t a, int clear_pending_eof);
     165             : static int translate_file_handle (int fd, int for_write);
     166             : 
     167             : /* Sends any pending data to the filter's FILTER function.  Note: this
     168             :    works on the filter and not on the whole pipeline.  That is,
     169             :    iobuf_flush doesn't necessarily cause data to be written to any
     170             :    underlying file; it just causes any data buffered at the filter A
     171             :    to be sent to A's filter function.
     172             : 
     173             :    If A is a IOBUF_OUTPUT_TEMP filter, then this also enlarges the
     174             :    buffer by IOBUF_BUFFER_SIZE.
     175             : 
     176             :    May only be called on an IOBUF_OUTPUT or IOBUF_OUTPUT_TEMP filters.  */
     177             : static int filter_flush (iobuf_t a);
     178             : 
     179             : 
     180             : 
     181             : /* This is a replacement for strcmp.  Under W32 it does not
     182             :    distinguish between backslash and slash.  */
     183             : static int
     184         268 : fd_cache_strcmp (const char *a, const char *b)
     185             : {
     186             : #ifdef HAVE_DOSISH_SYSTEM
     187             :   for (; *a && *b; a++, b++)
     188             :     {
     189             :       if (*a != *b && !((*a == '/' && *b == '\\')
     190             :                         || (*a == '\\' && *b == '/')) )
     191             :         break;
     192             :     }
     193             :   return *(const unsigned char *)a - *(const unsigned char *)b;
     194             : #else
     195         268 :   return strcmp (a, b);
     196             : #endif
     197             : }
     198             : 
     199             : /*
     200             :  * Invalidate (i.e. close) a cached iobuf
     201             :  */
     202             : static int
     203         546 : fd_cache_invalidate (const char *fname)
     204             : {
     205             :   close_cache_t cc;
     206         546 :   int rc = 0;
     207             : 
     208         546 :   assert (fname);
     209         546 :   if (DBG_IOBUF)
     210           0 :     log_debug ("fd_cache_invalidate (%s)\n", fname);
     211             : 
     212         772 :   for (cc = close_cache; cc; cc = cc->next)
     213             :     {
     214         226 :       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
     215             :         {
     216          20 :           if (DBG_IOBUF)
     217           0 :             log_debug ("                did (%s)\n", cc->fname);
     218             : #ifdef HAVE_W32_SYSTEM
     219             :           if (!CloseHandle (cc->fp))
     220             :             rc = -1;
     221             : #else
     222          20 :           rc = close (cc->fp);
     223             : #endif
     224          20 :           cc->fp = GNUPG_INVALID_FD;
     225             :         }
     226             :     }
     227         546 :   return rc;
     228             : }
     229             : 
     230             : 
     231             : /* Try to sync changes to the disk.  This is to avoid data loss during
     232             :    a system crash in write/close/rename cycle on some file
     233             :    systems.  */
     234             : static int
     235           0 : fd_cache_synchronize (const char *fname)
     236             : {
     237           0 :   int err = 0;
     238             : 
     239             : #ifdef HAVE_FSYNC
     240             :   close_cache_t cc;
     241             : 
     242           0 :   if (DBG_IOBUF)
     243           0 :     log_debug ("fd_cache_synchronize (%s)\n", fname);
     244             : 
     245           0 :   for (cc=close_cache; cc; cc = cc->next )
     246             :     {
     247           0 :       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
     248             :         {
     249           0 :           if (DBG_IOBUF)
     250           0 :             log_debug ("                 did (%s)\n", cc->fname);
     251             : 
     252           0 :           err = fsync (cc->fp);
     253             :         }
     254             :     }
     255             : #else
     256             :   (void)fname;
     257             : #endif /*HAVE_FSYNC*/
     258             : 
     259           0 :   return err;
     260             : }
     261             : 
     262             : 
     263             : static gnupg_fd_t
     264        2003 : direct_open (const char *fname, const char *mode, int mode700)
     265             : {
     266             : #ifdef HAVE_W32_SYSTEM
     267             :   unsigned long da, cd, sm;
     268             :   HANDLE hfile;
     269             : 
     270             :   /* Note, that we do not handle all mode combinations */
     271             : 
     272             :   /* According to the ReactOS source it seems that open() of the
     273             :    * standard MSW32 crt does open the file in shared mode which is
     274             :    * something new for MS applications ;-)
     275             :    */
     276             :   if (strchr (mode, '+'))
     277             :     {
     278             :       if (fd_cache_invalidate (fname))
     279             :         return GNUPG_INVALID_FD;
     280             :       da = GENERIC_READ | GENERIC_WRITE;
     281             :       cd = OPEN_EXISTING;
     282             :       sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
     283             :     }
     284             :   else if (strchr (mode, 'w'))
     285             :     {
     286             :       if (fd_cache_invalidate (fname))
     287             :         return GNUPG_INVALID_FD;
     288             :       da = GENERIC_WRITE;
     289             :       cd = CREATE_ALWAYS;
     290             :       sm = FILE_SHARE_WRITE;
     291             :     }
     292             :   else
     293             :     {
     294             :       da = GENERIC_READ;
     295             :       cd = OPEN_EXISTING;
     296             :       sm = FILE_SHARE_READ;
     297             :     }
     298             : 
     299             : #ifdef HAVE_W32CE_SYSTEM
     300             :   {
     301             :     wchar_t *wfname = utf8_to_wchar (fname);
     302             :     if (wfname)
     303             :       {
     304             :         hfile = CreateFile (wfname, da, sm, NULL, cd,
     305             :                             FILE_ATTRIBUTE_NORMAL, NULL);
     306             :         xfree (wfname);
     307             :       }
     308             :     else
     309             :       hfile = INVALID_HANDLE_VALUE;
     310             :   }
     311             : #else
     312             :   hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
     313             : #endif
     314             :   return hfile;
     315             : 
     316             : #else /*!HAVE_W32_SYSTEM*/
     317             : 
     318             :   int oflag;
     319        2003 :   int cflag = S_IRUSR | S_IWUSR;
     320             : 
     321        2003 :   if (!mode700)
     322        2001 :     cflag |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
     323             : 
     324             :   /* Note, that we do not handle all mode combinations */
     325        2003 :   if (strchr (mode, '+'))
     326             :     {
     327           0 :       if (fd_cache_invalidate (fname))
     328           0 :         return GNUPG_INVALID_FD;
     329           0 :       oflag = O_RDWR;
     330             :     }
     331        2003 :   else if (strchr (mode, 'w'))
     332             :     {
     333         525 :       if (fd_cache_invalidate (fname))
     334           0 :         return GNUPG_INVALID_FD;
     335         525 :       oflag = O_WRONLY | O_CREAT | O_TRUNC;
     336             :     }
     337             :   else
     338             :     {
     339        1478 :       oflag = O_RDONLY;
     340             :     }
     341             : #ifdef O_BINARY
     342             :   if (strchr (mode, 'b'))
     343             :     oflag |= O_BINARY;
     344             : #endif
     345             : 
     346             : #ifdef __riscos__
     347             :   {
     348             :     struct stat buf;
     349             : 
     350             :     /* Don't allow iobufs on directories */
     351             :     if (!stat (fname, &buf) && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
     352             :       return __set_errno (EISDIR);
     353             :   }
     354             : #endif
     355        2003 :   return open (fname, oflag, cflag);
     356             : 
     357             : #endif /*!HAVE_W32_SYSTEM*/
     358             : }
     359             : 
     360             : 
     361             : /*
     362             :  * Instead of closing an FD we keep it open and cache it for later reuse
     363             :  * Note that this caching strategy only works if the process does not chdir.
     364             :  */
     365             : static void
     366        2003 : fd_cache_close (const char *fname, gnupg_fd_t fp)
     367             : {
     368             :   close_cache_t cc;
     369             : 
     370        2003 :   assert (fp);
     371        2003 :   if (!fname || !*fname)
     372             :     {
     373             : #ifdef HAVE_W32_SYSTEM
     374             :       CloseHandle (fp);
     375             : #else
     376         931 :       close (fp);
     377             : #endif
     378         931 :       if (DBG_IOBUF)
     379           0 :         log_debug ("fd_cache_close (%d) real\n", (int)fp);
     380         931 :       return;
     381             :     }
     382             :   /* try to reuse a slot */
     383        1117 :   for (cc = close_cache; cc; cc = cc->next)
     384             :     {
     385          45 :       if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
     386             :         {
     387           0 :           cc->fp = fp;
     388           0 :           if (DBG_IOBUF)
     389           0 :             log_debug ("fd_cache_close (%s) used existing slot\n", fname);
     390           0 :           return;
     391             :         }
     392             :     }
     393             :   /* add a new one */
     394        1072 :   if (DBG_IOBUF)
     395           0 :     log_debug ("fd_cache_close (%s) new slot created\n", fname);
     396        1072 :   cc = xcalloc (1, sizeof *cc + strlen (fname));
     397        1072 :   strcpy (cc->fname, fname);
     398        1072 :   cc->fp = fp;
     399        1072 :   cc->next = close_cache;
     400        1072 :   close_cache = cc;
     401             : }
     402             : 
     403             : /*
     404             :  * Do a direct_open on FNAME but first try to reuse one from the fd_cache
     405             :  */
     406             : static gnupg_fd_t
     407        1478 : fd_cache_open (const char *fname, const char *mode)
     408             : {
     409             :   close_cache_t cc;
     410             : 
     411        1478 :   assert (fname);
     412        1523 :   for (cc = close_cache; cc; cc = cc->next)
     413             :     {
     414          45 :       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
     415             :         {
     416           0 :           gnupg_fd_t fp = cc->fp;
     417           0 :           cc->fp = GNUPG_INVALID_FD;
     418           0 :           if (DBG_IOBUF)
     419           0 :             log_debug ("fd_cache_open (%s) using cached fp\n", fname);
     420             : #ifdef HAVE_W32_SYSTEM
     421             :           if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff)
     422             :             {
     423             :               log_error ("rewind file failed on handle %p: ec=%d\n",
     424             :                          fp, (int) GetLastError ());
     425             :               fp = GNUPG_INVALID_FD;
     426             :             }
     427             : #else
     428           0 :           if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
     429             :             {
     430           0 :               log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
     431           0 :               fp = GNUPG_INVALID_FD;
     432             :             }
     433             : #endif
     434           0 :           return fp;
     435             :         }
     436             :     }
     437        1478 :   if (DBG_IOBUF)
     438           0 :     log_debug ("fd_cache_open (%s) not cached\n", fname);
     439        1478 :   return direct_open (fname, mode, 0);
     440             : }
     441             : 
     442             : 
     443             : static int
     444       10731 : file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     445             :              size_t * ret_len)
     446             : {
     447       10731 :   file_filter_ctx_t *a = opaque;
     448       10731 :   gnupg_fd_t f = a->fp;
     449       10731 :   size_t size = *ret_len;
     450       10731 :   size_t nbytes = 0;
     451       10731 :   int rc = 0;
     452             : 
     453             :   (void)chain; /* Not used.  */
     454             : 
     455       10731 :   if (control == IOBUFCTRL_UNDERFLOW)
     456             :     {
     457        4248 :       assert (size); /* We need a buffer.  */
     458        4248 :       if (a->eof_seen)
     459             :         {
     460           0 :           rc = -1;
     461           0 :           *ret_len = 0;
     462             :         }
     463             :       else
     464             :         {
     465             : #ifdef HAVE_W32_SYSTEM
     466             :           unsigned long nread;
     467             : 
     468             :           nbytes = 0;
     469             :           if (!ReadFile (f, buf, size, &nread, NULL))
     470             :             {
     471             :               int ec = (int) GetLastError ();
     472             :               if (ec != ERROR_BROKEN_PIPE)
     473             :                 {
     474             :                   rc = gpg_error_from_errno (ec);
     475             :                   log_error ("%s: read error: ec=%d\n", a->fname, ec);
     476             :                 }
     477             :             }
     478             :           else if (!nread)
     479             :             {
     480             :               a->eof_seen = 1;
     481             :               rc = -1;
     482             :             }
     483             :           else
     484             :             {
     485             :               nbytes = nread;
     486             :             }
     487             : 
     488             : #else
     489             : 
     490             :           int n;
     491             : 
     492        4248 :           nbytes = 0;
     493             :           do
     494             :             {
     495        4248 :               n = read (f, buf, size);
     496             :             }
     497        4248 :           while (n == -1 && errno == EINTR);
     498        4248 :           if (n == -1)
     499             :             {                   /* error */
     500           0 :               if (errno != EPIPE)
     501             :                 {
     502           0 :                   rc = gpg_error_from_syserror ();
     503           0 :                   log_error ("%s: read error: %s\n",
     504           0 :                              a->fname, strerror (errno));
     505             :                 }
     506             :             }
     507        4248 :           else if (!n)
     508             :             {                   /* eof */
     509        1194 :               a->eof_seen = 1;
     510        1194 :               rc = -1;
     511             :             }
     512             :           else
     513             :             {
     514        3054 :               nbytes = n;
     515             :             }
     516             : #endif
     517        4248 :           *ret_len = nbytes;
     518             :         }
     519             :     }
     520        6483 :   else if (control == IOBUFCTRL_FLUSH)
     521             :     {
     522        2249 :       if (size)
     523             :         {
     524             : #ifdef HAVE_W32_SYSTEM
     525             :           byte *p = buf;
     526             :           unsigned long n;
     527             : 
     528             :           nbytes = size;
     529             :           do
     530             :             {
     531             :               if (size && !WriteFile (f, p, nbytes, &n, NULL))
     532             :                 {
     533             :                   int ec = (int) GetLastError ();
     534             :                   rc = gpg_error_from_errno (ec);
     535             :                   log_error ("%s: write error: ec=%d\n", a->fname, ec);
     536             :                   break;
     537             :                 }
     538             :               p += n;
     539             :               nbytes -= n;
     540             :             }
     541             :           while (nbytes);
     542             :           nbytes = p - buf;
     543             : #else
     544        2144 :           byte *p = buf;
     545             :           int n;
     546             : 
     547        2144 :           nbytes = size;
     548             :           do
     549             :             {
     550             :               do
     551             :                 {
     552        2144 :                   n = write (f, p, nbytes);
     553             :                 }
     554        2144 :               while (n == -1 && errno == EINTR);
     555        2144 :               if (n > 0)
     556             :                 {
     557        2144 :                   p += n;
     558        2144 :                   nbytes -= n;
     559             :                 }
     560             :             }
     561        2144 :           while (n != -1 && nbytes);
     562        2144 :           if (n == -1)
     563             :             {
     564           0 :               rc = gpg_error_from_syserror ();
     565           0 :               log_error ("%s: write error: %s\n", a->fname, strerror (errno));
     566             :             }
     567        2144 :           nbytes = p - buf;
     568             : #endif
     569             :         }
     570        2249 :       *ret_len = nbytes;
     571             :     }
     572        4234 :   else if (control == IOBUFCTRL_INIT)
     573             :     {
     574        2117 :       a->eof_seen = 0;
     575        2117 :       a->keep_open = 0;
     576        2117 :       a->no_cache = 0;
     577             :     }
     578        2117 :   else if (control == IOBUFCTRL_DESC)
     579             :     {
     580           0 :       *(char **) buf = "file_filter(fd)";
     581             :     }
     582        2117 :   else if (control == IOBUFCTRL_FREE)
     583             :     {
     584        2117 :       if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
     585             :         {
     586        2003 :           if (DBG_IOBUF)
     587           0 :             log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f));
     588        2003 :           if (!a->keep_open)
     589        2003 :             fd_cache_close (a->no_cache ? NULL : a->fname, f);
     590             :         }
     591        2117 :       f = GNUPG_INVALID_FD;
     592        2117 :       xfree (a); /* We can free our context now. */
     593             :     }
     594             : 
     595       10731 :   return rc;
     596             : }
     597             : 
     598             : 
     599             : /* Similar to file_filter but using the estream system.  */
     600             : static int
     601           0 : file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     602             :                 size_t * ret_len)
     603             : {
     604           0 :   file_es_filter_ctx_t *a = opaque;
     605           0 :   estream_t f = a->fp;
     606           0 :   size_t size = *ret_len;
     607           0 :   size_t nbytes = 0;
     608           0 :   int rc = 0;
     609             : 
     610             :   (void)chain; /* Not used.  */
     611             : 
     612           0 :   if (control == IOBUFCTRL_UNDERFLOW)
     613             :     {
     614           0 :       assert (size); /* We need a buffer.  */
     615           0 :       if (a->eof_seen)
     616             :         {
     617           0 :           rc = -1;
     618           0 :           *ret_len = 0;
     619             :         }
     620             :       else
     621             :         {
     622           0 :           nbytes = 0;
     623           0 :           rc = es_read (f, buf, size, &nbytes);
     624           0 :           if (rc == -1)
     625             :             {                   /* error */
     626           0 :               rc = gpg_error_from_syserror ();
     627           0 :               log_error ("%s: read error: %s\n", a->fname, strerror (errno));
     628             :             }
     629           0 :           else if (!nbytes)
     630             :             {                   /* eof */
     631           0 :               a->eof_seen = 1;
     632           0 :               rc = -1;
     633             :             }
     634           0 :           *ret_len = nbytes;
     635             :         }
     636             :     }
     637           0 :   else if (control == IOBUFCTRL_FLUSH)
     638             :     {
     639           0 :       if (size)
     640             :         {
     641           0 :           byte *p = buf;
     642             :           size_t nwritten;
     643             : 
     644           0 :           nbytes = size;
     645             :           do
     646             :             {
     647           0 :               nwritten = 0;
     648           0 :               if (es_write (f, p, nbytes, &nwritten))
     649             :                 {
     650           0 :                   rc = gpg_error_from_syserror ();
     651           0 :                   log_error ("%s: write error: %s\n",
     652           0 :                              a->fname, strerror (errno));
     653           0 :                   break;
     654             :                 }
     655           0 :               p += nwritten;
     656           0 :               nbytes -= nwritten;
     657             :             }
     658           0 :           while (nbytes);
     659           0 :           nbytes = p - buf;
     660             :         }
     661           0 :       *ret_len = nbytes;
     662             :     }
     663           0 :   else if (control == IOBUFCTRL_INIT)
     664             :     {
     665           0 :       a->eof_seen = 0;
     666           0 :       a->no_cache = 0;
     667             :     }
     668           0 :   else if (control == IOBUFCTRL_DESC)
     669             :     {
     670           0 :       *(char **) buf = "estream_filter";
     671             :     }
     672           0 :   else if (control == IOBUFCTRL_FREE)
     673             :     {
     674           0 :       if (f != es_stdin && f != es_stdout)
     675             :         {
     676           0 :           if (DBG_IOBUF)
     677           0 :             log_debug ("%s: es_fclose %p\n", a->fname, f);
     678           0 :           if (!a->keep_open)
     679           0 :             es_fclose (f);
     680             :         }
     681           0 :       f = NULL;
     682           0 :       xfree (a); /* We can free our context now. */
     683             :     }
     684             : 
     685           0 :   return rc;
     686             : }
     687             : 
     688             : 
     689             : #ifdef HAVE_W32_SYSTEM
     690             : /* Because network sockets are special objects under Lose32 we have to
     691             :    use a dedicated filter for them. */
     692             : static int
     693             : sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     694             :              size_t * ret_len)
     695             : {
     696             :   sock_filter_ctx_t *a = opaque;
     697             :   size_t size = *ret_len;
     698             :   size_t nbytes = 0;
     699             :   int rc = 0;
     700             : 
     701             :   (void)chain;
     702             : 
     703             :   if (control == IOBUFCTRL_UNDERFLOW)
     704             :     {
     705             :       assert (size);            /* need a buffer */
     706             :       if (a->eof_seen)
     707             :         {
     708             :           rc = -1;
     709             :           *ret_len = 0;
     710             :         }
     711             :       else
     712             :         {
     713             :           int nread;
     714             : 
     715             :           nread = recv (a->sock, buf, size, 0);
     716             :           if (nread == SOCKET_ERROR)
     717             :             {
     718             :               int ec = (int) WSAGetLastError ();
     719             :               rc = gpg_error_from_errno (ec);
     720             :               log_error ("socket read error: ec=%d\n", ec);
     721             :             }
     722             :           else if (!nread)
     723             :             {
     724             :               a->eof_seen = 1;
     725             :               rc = -1;
     726             :             }
     727             :           else
     728             :             {
     729             :               nbytes = nread;
     730             :             }
     731             :           *ret_len = nbytes;
     732             :         }
     733             :     }
     734             :   else if (control == IOBUFCTRL_FLUSH)
     735             :     {
     736             :       if (size)
     737             :         {
     738             :           byte *p = buf;
     739             :           int n;
     740             : 
     741             :           nbytes = size;
     742             :           do
     743             :             {
     744             :               n = send (a->sock, p, nbytes, 0);
     745             :               if (n == SOCKET_ERROR)
     746             :                 {
     747             :                   int ec = (int) WSAGetLastError ();
     748             :                   rc = gpg_error_from_errno (ec);
     749             :                   log_error ("socket write error: ec=%d\n", ec);
     750             :                   break;
     751             :                 }
     752             :               p += n;
     753             :               nbytes -= n;
     754             :             }
     755             :           while (nbytes);
     756             :           nbytes = p - buf;
     757             :         }
     758             :       *ret_len = nbytes;
     759             :     }
     760             :   else if (control == IOBUFCTRL_INIT)
     761             :     {
     762             :       a->eof_seen = 0;
     763             :       a->keep_open = 0;
     764             :       a->no_cache = 0;
     765             :     }
     766             :   else if (control == IOBUFCTRL_DESC)
     767             :     {
     768             :       *(char **) buf = "sock_filter";
     769             :     }
     770             :   else if (control == IOBUFCTRL_FREE)
     771             :     {
     772             :       if (!a->keep_open)
     773             :         closesocket (a->sock);
     774             :       xfree (a);                /* we can free our context now */
     775             :     }
     776             :   return rc;
     777             : }
     778             : #endif /*HAVE_W32_SYSTEM*/
     779             : 
     780             : /****************
     781             :  * This is used to implement the block write mode.
     782             :  * Block reading is done on a byte by byte basis in readbyte(),
     783             :  * without a filter
     784             :  */
     785             : static int
     786        3958 : block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
     787             :               size_t * ret_len)
     788             : {
     789        3958 :   block_filter_ctx_t *a = opaque;
     790        3958 :   char *buf = (char *)buffer;
     791        3958 :   size_t size = *ret_len;
     792        3958 :   int c, needed, rc = 0;
     793             :   char *p;
     794             : 
     795        3958 :   if (control == IOBUFCTRL_UNDERFLOW)
     796             :     {
     797        1300 :       size_t n = 0;
     798             : 
     799        1300 :       p = buf;
     800        1300 :       assert (size);            /* need a buffer */
     801        1300 :       if (a->eof)            /* don't read any further */
     802         299 :         rc = -1;
     803        4455 :       while (!rc && size)
     804             :         {
     805        2154 :           if (!a->size)
     806             :             {                   /* get the length bytes */
     807        2130 :               if (a->partial == 2)
     808             :                 {
     809         299 :                   a->eof = 1;
     810         299 :                   if (!n)
     811           0 :                     rc = -1;
     812         299 :                   break;
     813             :                 }
     814        1831 :               else if (a->partial)
     815             :                 {
     816             :                   /* These OpenPGP introduced huffman like encoded length
     817             :                    * bytes are really a mess :-( */
     818        1831 :                   if (a->first_c)
     819             :                     {
     820         299 :                       c = a->first_c;
     821         299 :                       a->first_c = 0;
     822             :                     }
     823        1532 :                   else if ((c = iobuf_get (chain)) == -1)
     824             :                     {
     825           0 :                       log_error ("block_filter: 1st length byte missing\n");
     826           0 :                       rc = GPG_ERR_BAD_DATA;
     827           0 :                       break;
     828             :                     }
     829        1831 :                   if (c < 192)
     830             :                     {
     831          86 :                       a->size = c;
     832          86 :                       a->partial = 2;
     833          86 :                       if (!a->size)
     834             :                         {
     835           0 :                           a->eof = 1;
     836           0 :                           if (!n)
     837           0 :                             rc = -1;
     838           0 :                           break;
     839             :                         }
     840             :                     }
     841        1745 :                   else if (c < 224)
     842             :                     {
     843         213 :                       a->size = (c - 192) * 256;
     844         213 :                       if ((c = iobuf_get (chain)) == -1)
     845             :                         {
     846           0 :                           log_error
     847             :                             ("block_filter: 2nd length byte missing\n");
     848           0 :                           rc = GPG_ERR_BAD_DATA;
     849           0 :                           break;
     850             :                         }
     851         213 :                       a->size += c + 192;
     852         213 :                       a->partial = 2;
     853         213 :                       if (!a->size)
     854             :                         {
     855           0 :                           a->eof = 1;
     856           0 :                           if (!n)
     857           0 :                             rc = -1;
     858           0 :                           break;
     859             :                         }
     860             :                     }
     861        1532 :                   else if (c == 255)
     862             :                     {
     863           0 :                       a->size = (size_t)iobuf_get (chain) << 24;
     864           0 :                       a->size |= iobuf_get (chain) << 16;
     865           0 :                       a->size |= iobuf_get (chain) << 8;
     866           0 :                       if ((c = iobuf_get (chain)) == -1)
     867             :                         {
     868           0 :                           log_error ("block_filter: invalid 4 byte length\n");
     869           0 :                           rc = GPG_ERR_BAD_DATA;
     870           0 :                           break;
     871             :                         }
     872           0 :                       a->size |= c;
     873           0 :                       a->partial = 2;
     874           0 :                       if (!a->size)
     875             :                         {
     876           0 :                           a->eof = 1;
     877           0 :                           if (!n)
     878           0 :                             rc = -1;
     879           0 :                           break;
     880             :                         }
     881             :                     }
     882             :                   else
     883             :                     { /* Next partial body length. */
     884        1532 :                       a->size = 1 << (c & 0x1f);
     885             :                     }
     886             :                   /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
     887             :                 }
     888             :               else
     889           0 :                 BUG ();
     890             :             }
     891             : 
     892        5565 :           while (!rc && size && a->size)
     893             :             {
     894        1855 :               needed = size < a->size ? size : a->size;
     895        1855 :               c = iobuf_read (chain, p, needed);
     896        1855 :               if (c < needed)
     897             :                 {
     898           0 :                   if (c == -1)
     899           0 :                     c = 0;
     900           0 :                   log_error
     901             :                     ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
     902           0 :                      a, (ulong) size + c, (ulong) a->size + c);
     903           0 :                   rc = GPG_ERR_BAD_DATA;
     904             :                 }
     905             :               else
     906             :                 {
     907        1855 :                   size -= c;
     908        1855 :                   a->size -= c;
     909        1855 :                   p += c;
     910        1855 :                   n += c;
     911             :                 }
     912             :             }
     913             :         }
     914        1300 :       *ret_len = n;
     915             :     }
     916        2658 :   else if (control == IOBUFCTRL_FLUSH)
     917             :     {
     918        1096 :       if (a->partial)
     919             :         {                       /* the complicated openpgp scheme */
     920        1096 :           size_t blen, n, nbytes = size + a->buflen;
     921             : 
     922        1096 :           assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
     923        1096 :           if (nbytes < OP_MIN_PARTIAL_CHUNK)
     924             :             {
     925             :               /* not enough to write a partial block out; so we store it */
     926         227 :               if (!a->buffer)
     927         227 :                 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
     928         227 :               memcpy (a->buffer + a->buflen, buf, size);
     929         227 :               a->buflen += size;
     930             :             }
     931             :           else
     932             :             {                   /* okay, we can write out something */
     933             :               /* do this in a loop to use the most efficient block lengths */
     934         869 :               p = buf;
     935             :               do
     936             :                 {
     937             :                   /* find the best matching block length - this is limited
     938             :                    * by the size of the internal buffering */
     939        6035 :                   for (blen = OP_MIN_PARTIAL_CHUNK * 2,
     940        1015 :                        c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
     941        2990 :                        blen *= 2, c++)
     942             :                     ;
     943        1015 :                   blen /= 2;
     944        1015 :                   c--;
     945             :                   /* write the partial length header */
     946        1015 :                   assert (c <= 0x1f);        /*;-) */
     947        1015 :                   c |= 0xe0;
     948        1015 :                   iobuf_put (chain, c);
     949        1015 :                   if ((n = a->buflen))
     950             :                     {           /* write stuff from the buffer */
     951           0 :                       assert (n == OP_MIN_PARTIAL_CHUNK);
     952           0 :                       if (iobuf_write (chain, a->buffer, n))
     953           0 :                         rc = gpg_error_from_syserror ();
     954           0 :                       a->buflen = 0;
     955           0 :                       nbytes -= n;
     956             :                     }
     957        1015 :                   if ((n = nbytes) > blen)
     958         401 :                     n = blen;
     959        1015 :                   if (n && iobuf_write (chain, p, n))
     960           0 :                     rc = gpg_error_from_syserror ();
     961        1015 :                   p += n;
     962        1015 :                   nbytes -= n;
     963             :                 }
     964        1015 :               while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
     965             :               /* store the rest in the buffer */
     966         869 :               if (!rc && nbytes)
     967             :                 {
     968         255 :                   assert (!a->buflen);
     969         255 :                   assert (nbytes < OP_MIN_PARTIAL_CHUNK);
     970         255 :                   if (!a->buffer)
     971         255 :                     a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
     972         255 :                   memcpy (a->buffer, p, nbytes);
     973         255 :                   a->buflen = nbytes;
     974             :                 }
     975             :             }
     976             :         }
     977             :       else
     978           0 :         BUG ();
     979             :     }
     980        1562 :   else if (control == IOBUFCTRL_INIT)
     981             :     {
     982         781 :       if (DBG_IOBUF)
     983           0 :         log_debug ("init block_filter %p\n", a);
     984         781 :       if (a->partial)
     985         781 :         a->count = 0;
     986           0 :       else if (a->use == IOBUF_INPUT)
     987           0 :         a->count = a->size = 0;
     988             :       else
     989           0 :         a->count = a->size;       /* force first length bytes */
     990         781 :       a->eof = 0;
     991         781 :       a->buffer = NULL;
     992         781 :       a->buflen = 0;
     993             :     }
     994         781 :   else if (control == IOBUFCTRL_DESC)
     995             :     {
     996           0 :       *(char **) buf = "block_filter";
     997             :     }
     998         781 :   else if (control == IOBUFCTRL_FREE)
     999             :     {
    1000         781 :       if (a->use == IOBUF_OUTPUT)
    1001             :         {                       /* write the end markers */
    1002         482 :           if (a->partial)
    1003             :             {
    1004             :               u32 len;
    1005             :               /* write out the remaining bytes without a partial header
    1006             :                * the length of this header may be 0 - but if it is
    1007             :                * the first block we are not allowed to use a partial header
    1008             :                * and frankly we can't do so, because this length must be
    1009             :                * a power of 2. This is _really_ complicated because we
    1010             :                * have to check the possible length of a packet prior
    1011             :                * to it's creation: a chain of filters becomes complicated
    1012             :                * and we need a lot of code to handle compressed packets etc.
    1013             :                *   :-(((((((
    1014             :                */
    1015             :               /* construct header */
    1016         482 :               len = a->buflen;
    1017             :               /*log_debug("partial: remaining length=%u\n", len ); */
    1018         482 :               if (len < 192)
    1019         281 :                 rc = iobuf_put (chain, len);
    1020         201 :               else if (len < 8384)
    1021             :                 {
    1022         201 :                   if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
    1023         201 :                     rc = iobuf_put (chain, ((len - 192) % 256));
    1024             :                 }
    1025             :               else
    1026             :                 {               /* use a 4 byte header */
    1027           0 :                   if (!(rc = iobuf_put (chain, 0xff)))
    1028           0 :                     if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
    1029           0 :                       if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
    1030           0 :                         if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
    1031           0 :                           rc = iobuf_put (chain, len & 0xff);
    1032             :                 }
    1033         482 :               if (!rc && len)
    1034         482 :                 rc = iobuf_write (chain, a->buffer, len);
    1035         482 :               if (rc)
    1036             :                 {
    1037           0 :                   log_error ("block_filter: write error: %s\n",
    1038           0 :                              strerror (errno));
    1039           0 :                   rc = gpg_error_from_syserror ();
    1040             :                 }
    1041         482 :               xfree (a->buffer);
    1042         482 :               a->buffer = NULL;
    1043         482 :               a->buflen = 0;
    1044             :             }
    1045             :           else
    1046           0 :             BUG ();
    1047             :         }
    1048         299 :       else if (a->size)
    1049             :         {
    1050           0 :           log_error ("block_filter: pending bytes!\n");
    1051             :         }
    1052         781 :       if (DBG_IOBUF)
    1053           0 :         log_debug ("free block_filter %p\n", a);
    1054         781 :       xfree (a);                /* we can free our context now */
    1055             :     }
    1056             : 
    1057        3958 :   return rc;
    1058             : }
    1059             : 
    1060             : static const char *
    1061           0 : iobuf_desc (iobuf_t a)
    1062             : {
    1063           0 :   size_t dummy_len = 0;
    1064           0 :   const char *desc = "?";
    1065             : 
    1066           0 :   if (! a || ! a->filter)
    1067           0 :     return desc;
    1068             : 
    1069           0 :   a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
    1070             :              (byte *) & desc, &dummy_len);
    1071             : 
    1072           0 :   return desc;
    1073             : }
    1074             : 
    1075             : static void
    1076        1564 : print_chain (iobuf_t a)
    1077             : {
    1078        1564 :   if (!DBG_IOBUF)
    1079        3128 :     return;
    1080           0 :   for (; a; a = a->chain)
    1081             :     {
    1082             : 
    1083           0 :       log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
    1084             :                  a->no, a->subno, iobuf_desc (a), a->filter_eof,
    1085           0 :                  (int) a->d.start, (int) a->d.len);
    1086             :     }
    1087             : }
    1088             : 
    1089             : int
    1090           0 : iobuf_print_chain (iobuf_t a)
    1091             : {
    1092           0 :   print_chain (a);
    1093           0 :   return 0;
    1094             : }
    1095             : 
    1096             : iobuf_t
    1097        5722 : iobuf_alloc (int use, size_t bufsize)
    1098             : {
    1099             :   iobuf_t a;
    1100             :   static int number = 0;
    1101             : 
    1102        5722 :   assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
    1103             :           || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
    1104        5722 :   if (bufsize == 0)
    1105             :     {
    1106           0 :       log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
    1107             :       bufsize = IOBUF_BUFFER_SIZE;
    1108             :     }
    1109             : 
    1110        5722 :   a = xcalloc (1, sizeof *a);
    1111        5722 :   a->use = use;
    1112        5722 :   a->d.buf = xmalloc (bufsize);
    1113        5722 :   a->d.size = bufsize;
    1114        5722 :   a->no = ++number;
    1115        5722 :   a->subno = 0;
    1116        5722 :   a->real_fname = NULL;
    1117        5722 :   return a;
    1118             : }
    1119             : 
    1120             : int
    1121       10779 : iobuf_close (iobuf_t a)
    1122             : {
    1123             :   iobuf_t a_chain;
    1124       10779 :   size_t dummy_len = 0;
    1125       10779 :   int rc = 0;
    1126             : 
    1127       17892 :   for (; a; a = a_chain)
    1128             :     {
    1129        7113 :       int rc2 = 0;
    1130             : 
    1131        7113 :       a_chain = a->chain;
    1132             : 
    1133        7113 :       if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
    1134           0 :         log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
    1135             : 
    1136        7113 :       if (DBG_IOBUF)
    1137           0 :         log_debug ("iobuf-%d.%d: close '%s'\n",
    1138             :                    a->no, a->subno, iobuf_desc (a));
    1139             : 
    1140        7113 :       if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
    1141             :                                          a->chain, NULL, &dummy_len)))
    1142           0 :         log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
    1143        7113 :       if (! rc && rc2)
    1144             :         /* Whoops!  An error occured.  Save it in RC if we haven't
    1145             :            already recorded an error.  */
    1146           0 :         rc = rc2;
    1147             : 
    1148        7113 :       xfree (a->real_fname);
    1149        7113 :       if (a->d.buf)
    1150             :         {
    1151        7113 :           memset (a->d.buf, 0, a->d.size);        /* erase the buffer */
    1152        7113 :           xfree (a->d.buf);
    1153             :         }
    1154        7113 :       xfree (a);
    1155             :     }
    1156       10779 :   return rc;
    1157             : }
    1158             : 
    1159             : int
    1160           0 : iobuf_cancel (iobuf_t a)
    1161             : {
    1162             :   const char *s;
    1163             :   iobuf_t a2;
    1164             :   int rc;
    1165             : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
    1166             :   char *remove_name = NULL;
    1167             : #endif
    1168             : 
    1169           0 :   if (a && a->use == IOBUF_OUTPUT)
    1170             :     {
    1171           0 :       s = iobuf_get_real_fname (a);
    1172           0 :       if (s && *s)
    1173             :         {
    1174             : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
    1175             :           remove_name = xstrdup (s);
    1176             : #else
    1177           0 :           remove (s);
    1178             : #endif
    1179             :         }
    1180             :     }
    1181             : 
    1182             :   /* send a cancel message to all filters */
    1183           0 :   for (a2 = a; a2; a2 = a2->chain)
    1184             :     {
    1185             :       size_t dummy;
    1186           0 :       if (a2->filter)
    1187           0 :         a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
    1188             :     }
    1189             : 
    1190           0 :   rc = iobuf_close (a);
    1191             : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
    1192             :   if (remove_name)
    1193             :     {
    1194             :       /* Argg, MSDOS does not allow to remove open files.  So
    1195             :        * we have to do it here */
    1196             : #ifdef HAVE_W32CE_SYSTEM
    1197             :       wchar_t *wtmp = utf8_to_wchar (remove_name);
    1198             :       if (wtmp)
    1199             :         DeleteFile (wtmp);
    1200             :       xfree (wtmp);
    1201             : #else
    1202             :       remove (remove_name);
    1203             : #endif
    1204             :       xfree (remove_name);
    1205             :     }
    1206             : #endif
    1207           0 :   return rc;
    1208             : }
    1209             : 
    1210             : 
    1211             : iobuf_t
    1212        1141 : iobuf_temp (void)
    1213             : {
    1214        1141 :   return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE);
    1215             : }
    1216             : 
    1217             : iobuf_t
    1218        2464 : iobuf_temp_with_content (const char *buffer, size_t length)
    1219             : {
    1220             :   iobuf_t a;
    1221             :   int i;
    1222             : 
    1223        2464 :   a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
    1224        2464 :   assert (length == a->d.size);
    1225             :   /* memcpy (a->d.buf, buffer, length); */
    1226     2083466 :   for (i=0; i < length; i++)
    1227     2081002 :     a->d.buf[i] = buffer[i];
    1228        2464 :   a->d.len = length;
    1229             : 
    1230        2464 :   return a;
    1231             : }
    1232             : 
    1233             : void
    1234           0 : iobuf_enable_special_filenames (int yes)
    1235             : {
    1236           0 :   special_names_enabled = yes;
    1237           0 : }
    1238             : 
    1239             : 
    1240             : /* See whether the filename has the form "-&nnnn", where n is a
    1241             :    non-zero number.  Returns this number or -1 if it is not the
    1242             :    case.  */
    1243             : static int
    1244        5485 : check_special_filename (const char *fname)
    1245             : {
    1246        5485 :   if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
    1247             :     {
    1248             :       int i;
    1249             : 
    1250           0 :       fname += 2;
    1251           0 :       for (i = 0; digitp (fname+i); i++)
    1252             :         ;
    1253           0 :       if (!fname[i])
    1254           0 :         return atoi (fname);
    1255             :     }
    1256        5485 :   return -1;
    1257             : }
    1258             : 
    1259             : 
    1260             : int
    1261        3668 : iobuf_is_pipe_filename (const char *fname)
    1262             : {
    1263        3668 :   if (!fname || (*fname=='-' && !fname[1]) )
    1264         186 :     return 1;
    1265        3482 :   return check_special_filename (fname) != -1;
    1266             : }
    1267             : 
    1268             : static iobuf_t
    1269        2117 : do_open (const char *fname, int special_filenames,
    1270             :          int use, const char *opentype, int mode700)
    1271             : {
    1272             :   iobuf_t a;
    1273             :   gnupg_fd_t fp;
    1274             :   file_filter_ctx_t *fcx;
    1275        2117 :   size_t len = 0;
    1276        2117 :   int print_only = 0;
    1277             :   int fd;
    1278             : 
    1279        2117 :   assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
    1280             : 
    1281        2117 :   if (special_filenames
    1282             :       /* NULL or '-'.  */
    1283        2117 :       && (!fname || (*fname == '-' && !fname[1])))
    1284             :     {
    1285         114 :       if (use == IOBUF_INPUT)
    1286             :         {
    1287          80 :           fp = FD_FOR_STDIN;
    1288          80 :           fname = "[stdin]";
    1289             :         }
    1290             :       else
    1291             :         {
    1292          34 :           fp = FD_FOR_STDOUT;
    1293          34 :           fname = "[stdout]";
    1294             :         }
    1295         114 :       print_only = 1;
    1296             :     }
    1297        2003 :   else if (!fname)
    1298           0 :     return NULL;
    1299        2003 :   else if (special_filenames && (fd = check_special_filename (fname)) != -1)
    1300           0 :     return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1),
    1301             :                          opentype);
    1302             :   else
    1303             :     {
    1304        2003 :       if (use == IOBUF_INPUT)
    1305        1478 :         fp = fd_cache_open (fname, opentype);
    1306             :       else
    1307         525 :         fp = direct_open (fname, opentype, mode700);
    1308        2003 :       if (fp == GNUPG_INVALID_FD)
    1309           0 :         return NULL;
    1310             :     }
    1311             : 
    1312        2117 :   a = iobuf_alloc (use, IOBUF_BUFFER_SIZE);
    1313        2117 :   fcx = xmalloc (sizeof *fcx + strlen (fname));
    1314        2117 :   fcx->fp = fp;
    1315        2117 :   fcx->print_only_name = print_only;
    1316        2117 :   strcpy (fcx->fname, fname);
    1317        2117 :   if (!print_only)
    1318        2003 :     a->real_fname = xstrdup (fname);
    1319        2117 :   a->filter = file_filter;
    1320        2117 :   a->filter_ov = fcx;
    1321        2117 :   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
    1322        2117 :   if (DBG_IOBUF)
    1323           0 :     log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
    1324             :                a->no, a->subno, fname, iobuf_desc (a), FD2INT (fcx->fp));
    1325             : 
    1326        2117 :   return a;
    1327             : }
    1328             : 
    1329             : iobuf_t
    1330        1558 : iobuf_open (const char *fname)
    1331             : {
    1332        1558 :   return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
    1333             : }
    1334             : 
    1335             : iobuf_t
    1336         559 : iobuf_create (const char *fname, int mode700)
    1337             : {
    1338         559 :   return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
    1339             : }
    1340             : 
    1341             : iobuf_t
    1342           0 : iobuf_openrw (const char *fname)
    1343             : {
    1344           0 :   return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
    1345             : }
    1346             : 
    1347             : 
    1348             : static iobuf_t
    1349           0 : do_iobuf_fdopen (int fd, const char *mode, int keep_open)
    1350             : {
    1351             :   iobuf_t a;
    1352             :   gnupg_fd_t fp;
    1353             :   file_filter_ctx_t *fcx;
    1354             :   size_t len;
    1355             : 
    1356           0 :   fp = INT2FD (fd);
    1357             : 
    1358           0 :   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
    1359             :                    IOBUF_BUFFER_SIZE);
    1360           0 :   fcx = xmalloc (sizeof *fcx + 20);
    1361           0 :   fcx->fp = fp;
    1362           0 :   fcx->print_only_name = 1;
    1363           0 :   fcx->keep_open = keep_open;
    1364           0 :   sprintf (fcx->fname, "[fd %d]", fd);
    1365           0 :   a->filter = file_filter;
    1366           0 :   a->filter_ov = fcx;
    1367           0 :   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
    1368           0 :   if (DBG_IOBUF)
    1369           0 :     log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
    1370           0 :                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
    1371           0 :   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
    1372           0 :   return a;
    1373             : }
    1374             : 
    1375             : 
    1376             : iobuf_t
    1377           0 : iobuf_fdopen (int fd, const char *mode)
    1378             : {
    1379           0 :   return do_iobuf_fdopen (fd, mode, 0);
    1380             : }
    1381             : 
    1382             : iobuf_t
    1383           0 : iobuf_fdopen_nc (int fd, const char *mode)
    1384             : {
    1385           0 :   return do_iobuf_fdopen (fd, mode, 1);
    1386             : }
    1387             : 
    1388             : 
    1389             : iobuf_t
    1390           0 : iobuf_esopen (estream_t estream, const char *mode, int keep_open)
    1391             : {
    1392             :   iobuf_t a;
    1393             :   file_es_filter_ctx_t *fcx;
    1394             :   size_t len;
    1395             : 
    1396           0 :   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
    1397             :                    IOBUF_BUFFER_SIZE);
    1398           0 :   fcx = xtrymalloc (sizeof *fcx + 30);
    1399           0 :   fcx->fp = estream;
    1400           0 :   fcx->print_only_name = 1;
    1401           0 :   fcx->keep_open = keep_open;
    1402           0 :   sprintf (fcx->fname, "[fd %p]", estream);
    1403           0 :   a->filter = file_es_filter;
    1404           0 :   a->filter_ov = fcx;
    1405           0 :   file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
    1406           0 :   if (DBG_IOBUF)
    1407           0 :     log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
    1408           0 :                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
    1409           0 :   return a;
    1410             : }
    1411             : 
    1412             : 
    1413             : iobuf_t
    1414           0 : iobuf_sockopen (int fd, const char *mode)
    1415             : {
    1416             :   iobuf_t a;
    1417             : #ifdef HAVE_W32_SYSTEM
    1418             :   sock_filter_ctx_t *scx;
    1419             :   size_t len;
    1420             : 
    1421             :   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
    1422             :                    IOBUF_BUFFER_SIZE);
    1423             :   scx = xmalloc (sizeof *scx + 25);
    1424             :   scx->sock = fd;
    1425             :   scx->print_only_name = 1;
    1426             :   sprintf (scx->fname, "[sock %d]", fd);
    1427             :   a->filter = sock_filter;
    1428             :   a->filter_ov = scx;
    1429             :   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
    1430             :   if (DBG_IOBUF)
    1431             :     log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
    1432             :   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
    1433             : #else
    1434           0 :   a = iobuf_fdopen (fd, mode);
    1435             : #endif
    1436           0 :   return a;
    1437             : }
    1438             : 
    1439             : int
    1440        1002 : iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
    1441             : {
    1442        1002 :   if (cmd == IOBUF_IOCTL_KEEP_OPEN)
    1443             :     {
    1444             :       /* Keep system filepointer/descriptor open.  This was used in
    1445             :          the past by http.c; this ioctl is not directly used
    1446             :          anymore.  */
    1447           0 :       if (DBG_IOBUF)
    1448           0 :         log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
    1449             :                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
    1450             :                    intval);
    1451           0 :       for (; a; a = a->chain)
    1452           0 :         if (!a->chain && a->filter == file_filter)
    1453             :           {
    1454           0 :             file_filter_ctx_t *b = a->filter_ov;
    1455           0 :             b->keep_open = intval;
    1456           0 :             return 0;
    1457             :           }
    1458             : #ifdef HAVE_W32_SYSTEM
    1459             :         else if (!a->chain && a->filter == sock_filter)
    1460             :           {
    1461             :             sock_filter_ctx_t *b = a->filter_ov;
    1462             :             b->keep_open = intval;
    1463             :             return 0;
    1464             :           }
    1465             : #endif
    1466             :     }
    1467        1002 :   else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
    1468             :     {
    1469          21 :       if (DBG_IOBUF)
    1470           0 :         log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
    1471             :                    ptrval ? (char *) ptrval : "?");
    1472          21 :       if (!a && !intval && ptrval)
    1473             :         {
    1474          21 :           if (fd_cache_invalidate (ptrval))
    1475           0 :             return -1;
    1476          21 :           return 0;
    1477             :         }
    1478             :     }
    1479         981 :   else if (cmd == IOBUF_IOCTL_NO_CACHE)
    1480             :     {
    1481         981 :       if (DBG_IOBUF)
    1482           0 :         log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
    1483             :                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
    1484             :                    intval);
    1485         981 :       for (; a; a = a->chain)
    1486         981 :         if (!a->chain && a->filter == file_filter)
    1487             :           {
    1488         981 :             file_filter_ctx_t *b = a->filter_ov;
    1489         981 :             b->no_cache = intval;
    1490         981 :             return 0;
    1491             :           }
    1492             : #ifdef HAVE_W32_SYSTEM
    1493             :         else if (!a->chain && a->filter == sock_filter)
    1494             :           {
    1495             :             sock_filter_ctx_t *b = a->filter_ov;
    1496             :             b->no_cache = intval;
    1497             :             return 0;
    1498             :           }
    1499             : #endif
    1500             :     }
    1501           0 :   else if (cmd == IOBUF_IOCTL_FSYNC)
    1502             :     {
    1503             :       /* Do a fsync on the open fd and return any errors to the caller
    1504             :          of iobuf_ioctl.  Note that we work on a file name here. */
    1505           0 :       if (DBG_IOBUF)
    1506           0 :         log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
    1507             :                    ptrval? (const char*)ptrval:"<null>");
    1508             : 
    1509           0 :         if (!a && !intval && ptrval)
    1510             :           {
    1511           0 :             return fd_cache_synchronize (ptrval);
    1512             :           }
    1513             :       }
    1514             : 
    1515             : 
    1516           0 :   return -1;
    1517             : }
    1518             : 
    1519             : 
    1520             : /****************
    1521             :  * Register an i/o filter.
    1522             :  */
    1523             : int
    1524        2038 : iobuf_push_filter (iobuf_t a,
    1525             :                    int (*f) (void *opaque, int control,
    1526             :                              iobuf_t chain, byte * buf, size_t * len),
    1527             :                    void *ov)
    1528             : {
    1529        2038 :   return iobuf_push_filter2 (a, f, ov, 0);
    1530             : }
    1531             : 
    1532             : int
    1533        3088 : iobuf_push_filter2 (iobuf_t a,
    1534             :                     int (*f) (void *opaque, int control,
    1535             :                               iobuf_t chain, byte * buf, size_t * len),
    1536             :                     void *ov, int rel_ov)
    1537             : {
    1538             :   iobuf_t b;
    1539        3088 :   size_t dummy_len = 0;
    1540        3088 :   int rc = 0;
    1541             : 
    1542        3088 :   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
    1543           0 :     return rc;
    1544             : 
    1545        3088 :   if (a->subno >= MAX_NESTING_FILTER)
    1546             :     {
    1547           0 :       log_error ("i/o filter too deeply nested - corrupted data?\n");
    1548           0 :       return GPG_ERR_BAD_DATA;
    1549             :     }
    1550             : 
    1551             :   /* We want to create a new filter and put it in front of A.  A
    1552             :      simple implementation would do:
    1553             : 
    1554             :        b = iobuf_alloc (...);
    1555             :        b->chain = a;
    1556             :        return a;
    1557             : 
    1558             :      This is a bit problematic: A is the head of the pipeline and
    1559             :      there are potentially many pointers to it.  Requiring the caller
    1560             :      to update all of these pointers is a burden.
    1561             : 
    1562             :      An alternative implementation would add a level of indirection.
    1563             :      For instance, we could use a pipeline object, which contains a
    1564             :      pointer to the first filter in the pipeline.  This is not what we
    1565             :      do either.
    1566             : 
    1567             :      Instead, we allocate a new buffer (B) and copy the first filter's
    1568             :      state into that and use the initial buffer (A) for the new
    1569             :      filter.  One limitation of this approach is that it is not
    1570             :      practical to maintain a pointer to a specific filter's state.
    1571             : 
    1572             :      Before:
    1573             : 
    1574             :            A
    1575             :            |
    1576             :            v 0x100               0x200
    1577             :            +----------+          +----------+
    1578             :            | filter x |--------->| filter y |---->....
    1579             :            +----------+          +----------+
    1580             : 
    1581             :      After:           B
    1582             :                       |
    1583             :                       v 0x300
    1584             :                       +----------+
    1585             :            A          | filter x |
    1586             :            |          +----------+
    1587             :            v 0x100    ^          v 0x200
    1588             :            +----------+          +----------+
    1589             :            | filter w |          | filter y |---->....
    1590             :            +----------+          +----------+
    1591             : 
    1592             :      Note: filter x's address changed from 0x100 to 0x300, but A still
    1593             :      points to the head of the pipeline.
    1594             :   */
    1595             : 
    1596        3088 :   b = xmalloc (sizeof *b);
    1597        3088 :   memcpy (b, a, sizeof *b);
    1598             :   /* fixme: it is stupid to keep a copy of the name at every level
    1599             :    * but we need the name somewhere because the name known by file_filter
    1600             :    * may have been released when we need the name of the file */
    1601        3088 :   b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
    1602             :   /* remove the filter stuff from the new stream */
    1603        3088 :   a->filter = NULL;
    1604        3088 :   a->filter_ov = NULL;
    1605        3088 :   a->filter_ov_owner = 0;
    1606        3088 :   a->filter_eof = 0;
    1607        3088 :   if (a->use == IOBUF_OUTPUT_TEMP)
    1608             :     /* A TEMP filter buffers any data sent to it; it does not forward
    1609             :        any data down the pipeline.  If we add a new filter to the
    1610             :        pipeline, it shouldn't also buffer data.  It should send it
    1611             :        downstream to be buffered.  Thus, the correct type for a filter
    1612             :        added in front of an IOBUF_OUTPUT_TEMP filter is IOBUF_OUPUT, not
    1613             :        IOBUF_OUTPUT_TEMP.  */
    1614             :     {
    1615           1 :       a->use = IOBUF_OUTPUT;
    1616             : 
    1617             :       /* When pipeline is written to, the temp buffer's size is
    1618             :          increased accordingly.  We don't need to allocate a 10 MB
    1619             :          buffer for a non-terminal filter.  Just use the default
    1620             :          size.  */
    1621           1 :       a->d.size = IOBUF_BUFFER_SIZE;
    1622             :     }
    1623        3087 :   else if (a->use == IOBUF_INPUT_TEMP)
    1624             :     /* Same idea as above.  */
    1625             :     {
    1626           4 :       a->use = IOBUF_INPUT;
    1627           4 :       a->d.size = IOBUF_BUFFER_SIZE;
    1628             :     }
    1629             : 
    1630             :   /* The new filter (A) gets a new buffer.
    1631             : 
    1632             :      If the pipeline is an output or temp pipeline, then giving the
    1633             :      buffer to the new filter means that data that was written before
    1634             :      the filter was pushed gets sent to the filter.  That's clearly
    1635             :      wrong.
    1636             : 
    1637             :      If the pipeline is an input pipeline, then giving the buffer to
    1638             :      the new filter (A) means that data that has read from (B), but
    1639             :      not yet read from the pipeline won't be processed by the new
    1640             :      filter (A)!  That's certainly not what we want.  */
    1641        3088 :   a->d.buf = xmalloc (a->d.size);
    1642        3088 :   a->d.len = 0;
    1643        3088 :   a->d.start = 0;
    1644             : 
    1645             :   /* disable nlimit for the new stream */
    1646        3088 :   a->ntotal = b->ntotal + b->nbytes;
    1647        3088 :   a->nlimit = a->nbytes = 0;
    1648        3088 :   a->nofast = 0;
    1649             :   /* make a link from the new stream to the original stream */
    1650        3088 :   a->chain = b;
    1651             : 
    1652             :   /* setup the function on the new stream */
    1653        3088 :   a->filter = f;
    1654        3088 :   a->filter_ov = ov;
    1655        3088 :   a->filter_ov_owner = rel_ov;
    1656             : 
    1657        3088 :   a->subno = b->subno + 1;
    1658             : 
    1659        3088 :   if (DBG_IOBUF)
    1660             :     {
    1661           0 :       log_debug ("iobuf-%d.%d: push '%s'\n",
    1662             :                  a->no, a->subno, iobuf_desc (a));
    1663           0 :       print_chain (a);
    1664             :     }
    1665             : 
    1666             :   /* now we can initialize the new function if we have one */
    1667        3088 :   if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
    1668             :                                     NULL, &dummy_len)))
    1669           0 :     log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
    1670        3088 :   return rc;
    1671             : }
    1672             : 
    1673             : /****************
    1674             :  * Remove an i/o filter.
    1675             :  */
    1676             : static int
    1677          28 : pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
    1678             :                                iobuf_t chain, byte * buf, size_t * len),
    1679             :             void *ov)
    1680             : {
    1681             :   iobuf_t b;
    1682          28 :   size_t dummy_len = 0;
    1683          28 :   int rc = 0;
    1684             : 
    1685          28 :   if (DBG_IOBUF)
    1686           0 :     log_debug ("iobuf-%d.%d: pop '%s'\n",
    1687             :                a->no, a->subno, iobuf_desc (a));
    1688          28 :   if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
    1689             :     {
    1690             :       /* This should be the last filter in the pipeline.  */
    1691           0 :       assert (! a->chain);
    1692           0 :       return 0;
    1693             :     }
    1694          28 :   if (!a->filter)
    1695             :     {                           /* this is simple */
    1696           0 :       b = a->chain;
    1697           0 :       assert (b);
    1698           0 :       xfree (a->d.buf);
    1699           0 :       xfree (a->real_fname);
    1700           0 :       memcpy (a, b, sizeof *a);
    1701           0 :       xfree (b);
    1702           0 :       return 0;
    1703             :     }
    1704          28 :   for (b = a; b; b = b->chain)
    1705          28 :     if (b->filter == f && (!ov || b->filter_ov == ov))
    1706             :       break;
    1707          28 :   if (!b)
    1708           0 :     log_bug ("pop_filter(): filter function not found\n");
    1709             : 
    1710             :   /* flush this stream if it is an output stream */
    1711          28 :   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
    1712             :     {
    1713           0 :       log_error ("filter_flush failed in pop_filter: %s\n", gpg_strerror (rc));
    1714           0 :       return rc;
    1715             :     }
    1716             :   /* and tell the filter to free it self */
    1717          28 :   if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
    1718             :                                     NULL, &dummy_len)))
    1719             :     {
    1720           0 :       log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
    1721           0 :       return rc;
    1722             :     }
    1723          28 :   if (b->filter_ov && b->filter_ov_owner)
    1724             :     {
    1725           0 :       xfree (b->filter_ov);
    1726           0 :       b->filter_ov = NULL;
    1727             :     }
    1728             : 
    1729             : 
    1730             :   /* and see how to remove it */
    1731          28 :   if (a == b && !b->chain)
    1732           0 :     log_bug ("can't remove the last filter from the chain\n");
    1733          28 :   else if (a == b)
    1734             :     {                           /* remove the first iobuf from the chain */
    1735             :       /* everything from b is copied to a. This is save because
    1736             :        * a flush has been done on the to be removed entry
    1737             :        */
    1738          28 :       b = a->chain;
    1739          28 :       xfree (a->d.buf);
    1740          28 :       xfree (a->real_fname);
    1741          28 :       memcpy (a, b, sizeof *a);
    1742          28 :       xfree (b);
    1743          28 :       if (DBG_IOBUF)
    1744           0 :         log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
    1745             :     }
    1746           0 :   else if (!b->chain)
    1747             :     {                           /* remove the last iobuf from the chain */
    1748           0 :       log_bug ("Ohh jeee, trying to remove a head filter\n");
    1749             :     }
    1750             :   else
    1751             :     {                           /* remove an intermediate iobuf from the chain */
    1752           0 :       log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
    1753             :     }
    1754             : 
    1755          28 :   return rc;
    1756             : }
    1757             : 
    1758             : 
    1759             : /****************
    1760             :  * read underflow: read more bytes into the buffer and return
    1761             :  * the first byte or -1 on EOF.
    1762             :  */
    1763             : static int
    1764      537669 : underflow (iobuf_t a, int clear_pending_eof)
    1765             : {
    1766             :   size_t len;
    1767             :   int rc;
    1768             : 
    1769      537669 :   if (DBG_IOBUF)
    1770           0 :     log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
    1771             :                a->no, a->subno,
    1772           0 :                (int) a->d.size, (int) (a->d.len - a->d.start),
    1773           0 :                (int) (a->d.size - (a->d.len - a->d.start)));
    1774             : 
    1775      537669 :   if (a->use == IOBUF_INPUT_TEMP)
    1776             :     /* By definition, there isn't more data to read into the
    1777             :        buffer.  */
    1778        2465 :     return -1;
    1779             : 
    1780      535204 :   assert (a->use == IOBUF_INPUT);
    1781             : 
    1782             :   /* If there is still some buffered data, then move it to the start
    1783             :      of the buffer and try to fill the end of the buffer.  (This is
    1784             :      useful if we are called from iobuf_peek().)  */
    1785      535204 :   assert (a->d.start <= a->d.len);
    1786      535204 :   a->d.len -= a->d.start;
    1787      535204 :   memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
    1788      535204 :   a->d.start = 0;
    1789             : 
    1790      535204 :   if (a->d.len == 0 && a->filter_eof)
    1791             :     /* The last time we tried to read from this filter, we got an EOF.
    1792             :        We couldn't return the EOF, because there was buffered data.
    1793             :        Since there is no longer any buffered data, return the
    1794             :        error.  */
    1795             :     {
    1796        1568 :       if (DBG_IOBUF)
    1797           0 :         log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
    1798             :                    a->no, a->subno);
    1799        1568 :       if (! clear_pending_eof)
    1800           0 :         return -1;
    1801             : 
    1802        1568 :       if (a->chain)
    1803             :         /* A filter follows this one.  Free this filter.  */
    1804             :         {
    1805         540 :           iobuf_t b = a->chain;
    1806         540 :           if (DBG_IOBUF)
    1807           0 :             log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
    1808             :                        a->no, a->subno);
    1809         540 :           xfree (a->d.buf);
    1810         540 :           xfree (a->real_fname);
    1811         540 :           memcpy (a, b, sizeof *a);
    1812         540 :           xfree (b);
    1813         540 :           print_chain (a);
    1814             :         }
    1815             :       else
    1816        1028 :         a->filter_eof = 0;   /* for the top level filter */
    1817        1568 :       return -1;                /* return one(!) EOF */
    1818             :     }
    1819             : 
    1820      533636 :   if (a->d.len == 0 && a->error)
    1821             :     /* The last time we tried to read from this filter, we got an
    1822             :        error.  We couldn't return the error, because there was
    1823             :        buffered data.  Since there is no longer any buffered data,
    1824             :        return the error.  */
    1825             :     {
    1826           0 :       if (DBG_IOBUF)
    1827           0 :         log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
    1828           0 :                    a->no, a->subno, gpg_strerror (a->error));
    1829           0 :       return -1;
    1830             :     }
    1831             : 
    1832      533636 :   if (a->filter && ! a->filter_eof && ! a->error)
    1833             :     /* We have a filter function and the last time we tried to read we
    1834             :        didn't get an EOF or an error.  Try to fill the buffer.  */
    1835             :     {
    1836             :       /* Be careful to account for any buffered data.  */
    1837      533494 :       len = a->d.size - a->d.len;
    1838      533494 :       if (DBG_IOBUF)
    1839           0 :         log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
    1840             :                    a->no, a->subno, (ulong) len);
    1841      533494 :       if (len == 0)
    1842             :         /* There is no space for more data.  Don't bother calling
    1843             :            A->FILTER.  */
    1844           0 :         rc = 0;
    1845             :       else
    1846     1066988 :         rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
    1847      533494 :                         &a->d.buf[a->d.len], &len);
    1848      533494 :       a->d.len += len;
    1849             : 
    1850      533494 :       if (DBG_IOBUF)
    1851           0 :         log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
    1852             :                    a->no, a->subno,
    1853           0 :                    rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
    1854             :                    (ulong) len);
    1855             : /*          if( a->no == 1 ) */
    1856             : /*                   log_hexdump ("     data:", a->d.buf, len); */
    1857             : 
    1858      533494 :       if (rc == -1)
    1859             :         /* EOF.  */
    1860             :         {
    1861        2758 :           size_t dummy_len = 0;
    1862             : 
    1863             :           /* Tell the filter to free itself */
    1864        2758 :           if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
    1865             :                                NULL, &dummy_len)))
    1866           0 :             log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
    1867             : 
    1868             :           /* Free everything except for the internal buffer.  */
    1869        2758 :           if (a->filter_ov && a->filter_ov_owner)
    1870           0 :             xfree (a->filter_ov);
    1871        2758 :           a->filter_ov = NULL;
    1872        2758 :           a->filter = NULL;
    1873        2758 :           a->filter_eof = 1;
    1874             : 
    1875        2758 :           if (clear_pending_eof && a->d.len == 0 && a->chain)
    1876             :             /* We don't need to keep this filter around at all:
    1877             : 
    1878             :                  - we got an EOF
    1879             :                  - we have no buffered data
    1880             :                  - a filter follows this one.
    1881             : 
    1882             :               Unlink this filter.  */
    1883             :             {
    1884        1024 :               iobuf_t b = a->chain;
    1885        1024 :               if (DBG_IOBUF)
    1886           0 :                 log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
    1887             :                            a->no, a->subno);
    1888        1024 :               xfree (a->d.buf);
    1889        1024 :               xfree (a->real_fname);
    1890        1024 :               memcpy (a, b, sizeof *a);
    1891        1024 :               xfree (b);
    1892             : 
    1893        1024 :               print_chain (a);
    1894             : 
    1895        3242 :               return -1;
    1896             :             }
    1897        1734 :           else if (a->d.len == 0)
    1898             :             /* We can't unlink this filter (it is the only one in the
    1899             :                pipeline), but we can immediately return EOF.  */
    1900        1194 :             return -1;
    1901             :         }
    1902      530736 :       else if (rc)
    1903             :         /* Record the error.  */
    1904             :         {
    1905           0 :           a->error = rc;
    1906             : 
    1907           0 :           if (a->d.len == 0)
    1908             :             /* There is no buffered data.  Immediately return EOF.  */
    1909           0 :             return -1;
    1910             :         }
    1911             :     }
    1912             : 
    1913      531418 :   assert (a->d.start <= a->d.len);
    1914      531418 :   if (a->d.start < a->d.len)
    1915      531274 :     return a->d.buf[a->d.start++];
    1916             : 
    1917             :   /* EOF.  */
    1918         144 :   return -1;
    1919             : }
    1920             : 
    1921             : 
    1922             : static int
    1923        6326 : filter_flush (iobuf_t a)
    1924             : {
    1925             :   size_t len;
    1926             :   int rc;
    1927             : 
    1928        6326 :   if (a->use == IOBUF_OUTPUT_TEMP)
    1929             :     {                           /* increase the temp buffer */
    1930          47 :       size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
    1931             : 
    1932          47 :       if (DBG_IOBUF)
    1933           0 :         log_debug ("increasing temp iobuf from %lu to %lu\n",
    1934             :                    (ulong) a->d.size, (ulong) newsize);
    1935             : 
    1936          47 :       a->d.buf = xrealloc (a->d.buf, newsize);
    1937          47 :       a->d.size = newsize;
    1938          47 :       return 0;
    1939             :     }
    1940        6279 :   else if (a->use != IOBUF_OUTPUT)
    1941           0 :     log_bug ("flush on non-output iobuf\n");
    1942        6279 :   else if (!a->filter)
    1943           0 :     log_bug ("filter_flush: no filter\n");
    1944        6279 :   len = a->d.len;
    1945        6279 :   rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
    1946        6279 :   if (!rc && len != a->d.len)
    1947             :     {
    1948           0 :       log_info ("filter_flush did not write all!\n");
    1949           0 :       rc = GPG_ERR_INTERNAL;
    1950             :     }
    1951        6279 :   else if (rc)
    1952           0 :     a->error = rc;
    1953        6279 :   a->d.len = 0;
    1954             : 
    1955        6279 :   return rc;
    1956             : }
    1957             : 
    1958             : 
    1959             : int
    1960        8133 : iobuf_readbyte (iobuf_t a)
    1961             : {
    1962             :   int c;
    1963             : 
    1964        8133 :   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
    1965             :     {
    1966           0 :       log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
    1967             :       return -1;
    1968             :     }
    1969             : 
    1970        8133 :   assert (a->d.start <= a->d.len);
    1971             : 
    1972        8133 :   if (a->nlimit && a->nbytes >= a->nlimit)
    1973           0 :     return -1;                  /* forced EOF */
    1974             : 
    1975        8133 :   if (a->d.start < a->d.len)
    1976             :     {
    1977         854 :       c = a->d.buf[a->d.start++];
    1978             :     }
    1979        7279 :   else if ((c = underflow (a, 1)) == -1)
    1980        4736 :     return -1;                  /* EOF */
    1981             : 
    1982        3397 :   assert (a->d.start <= a->d.len);
    1983             : 
    1984             :   /* Note: if underflow doesn't return EOF, then it returns the first
    1985             :      byte that was read and advances a->d.start appropriately.  */
    1986             : 
    1987        3397 :   a->nbytes++;
    1988        3397 :   return c;
    1989             : }
    1990             : 
    1991             : 
    1992             : int
    1993       25487 : iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
    1994             : {
    1995       25487 :   unsigned char *buf = (unsigned char *)buffer;
    1996             :   int c, n;
    1997             : 
    1998       25487 :   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
    1999             :     {
    2000           0 :       log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
    2001             :       return -1;
    2002             :     }
    2003             : 
    2004       25487 :   if (a->nlimit)
    2005             :     {
    2006             :       /* Handle special cases. */
    2007           0 :       for (n = 0; n < buflen; n++)
    2008             :         {
    2009           0 :           if ((c = iobuf_readbyte (a)) == -1)
    2010             :             {
    2011           0 :               if (!n)
    2012           0 :                 return -1;      /* eof */
    2013           0 :               break;
    2014             :             }
    2015             : 
    2016           0 :           if (buf)
    2017             :             {
    2018           0 :               *buf = c;
    2019           0 :               buf++;
    2020             :             }
    2021             :         }
    2022           0 :       return n;
    2023             :     }
    2024             : 
    2025       25487 :   n = 0;
    2026             :   do
    2027             :     {
    2028      553629 :       if (n < buflen && a->d.start < a->d.len)
    2029             :         /* Drain the buffer.  */
    2030             :         {
    2031      551870 :           unsigned size = a->d.len - a->d.start;
    2032      551870 :           if (size > buflen - n)
    2033       22750 :             size = buflen - n;
    2034      551870 :           if (buf)
    2035       27572 :             memcpy (buf, a->d.buf + a->d.start, size);
    2036      551870 :           n += size;
    2037      551870 :           a->d.start += size;
    2038      551870 :           if (buf)
    2039       27572 :             buf += size;
    2040             :         }
    2041      553629 :       if (n < buflen)
    2042             :         /* Draining the internal buffer didn't fill BUFFER.  Call
    2043             :            underflow to read more data into the filter's internal
    2044             :            buffer.  */
    2045             :         {
    2046      529802 :           if ((c = underflow (a, 1)) == -1)
    2047             :             /* EOF.  If we managed to read something, don't return EOF
    2048             :                now.  */
    2049             :             {
    2050        1659 :               a->nbytes += n;
    2051        1659 :               return n ? n : -1 /*EOF*/;
    2052             :             }
    2053      528143 :           if (buf)
    2054        3854 :             *buf++ = c;
    2055      528143 :           n++;
    2056             :         }
    2057             :     }
    2058      551970 :   while (n < buflen);
    2059       23828 :   a->nbytes += n;
    2060       23828 :   return n;
    2061             : }
    2062             : 
    2063             : 
    2064             : 
    2065             : int
    2066         588 : iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
    2067             : {
    2068         588 :   int n = 0;
    2069             : 
    2070         588 :   assert (buflen > 0);
    2071         588 :   assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
    2072             : 
    2073         588 :   if (buflen > a->d.size)
    2074             :     /* We can't peek more than we can buffer.  */
    2075           0 :     buflen = a->d.size;
    2076             : 
    2077             :   /* Try to fill the internal buffer with enough data to satisfy the
    2078             :      request.  */
    2079        1764 :   while (buflen > a->d.len - a->d.start)
    2080             :     {
    2081         588 :       if (underflow (a, 0) == -1)
    2082             :         /* EOF.  We can't read any more.  */
    2083           0 :         break;
    2084             : 
    2085             :       /* Underflow consumes the first character (it's the return
    2086             :          value).  unget() it by resetting the "file position".  */
    2087         588 :       assert (a->d.start == 1);
    2088         588 :       a->d.start = 0;
    2089             :     }
    2090             : 
    2091         588 :   n = a->d.len - a->d.start;
    2092         588 :   if (n > buflen)
    2093         588 :     n = buflen;
    2094             : 
    2095         588 :   if (n == 0)
    2096             :     /* EOF.  */
    2097           0 :     return -1;
    2098             : 
    2099         588 :   memcpy (buf, &a->d.buf[a->d.start], n);
    2100             : 
    2101         588 :   return n;
    2102             : }
    2103             : 
    2104             : 
    2105             : 
    2106             : 
    2107             : int
    2108      706769 : iobuf_writebyte (iobuf_t a, unsigned int c)
    2109             : {
    2110             :   int rc;
    2111             : 
    2112      706769 :   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
    2113             :     {
    2114           0 :       log_bug ("iobuf_writebyte called on an input pipeline!\n");
    2115             :       return -1;
    2116             :     }
    2117             : 
    2118      706769 :   if (a->d.len == a->d.size)
    2119          76 :     if ((rc=filter_flush (a)))
    2120           0 :       return rc;
    2121             : 
    2122      706769 :   assert (a->d.len < a->d.size);
    2123      706769 :   a->d.buf[a->d.len++] = c;
    2124      706769 :   return 0;
    2125             : }
    2126             : 
    2127             : 
    2128             : int
    2129       32936 : iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
    2130             : {
    2131       32936 :   const unsigned char *buf = (const unsigned char *)buffer;
    2132             :   int rc;
    2133             : 
    2134       32936 :   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
    2135             :     {
    2136           0 :       log_bug ("iobuf_write called on an input pipeline!\n");
    2137             :       return -1;
    2138             :     }
    2139             : 
    2140             :   do
    2141             :     {
    2142       35534 :       if (buflen && a->d.len < a->d.size)
    2143             :         {
    2144       34492 :           unsigned size = a->d.size - a->d.len;
    2145       34492 :           if (size > buflen)
    2146       31893 :             size = buflen;
    2147       34492 :           memcpy (a->d.buf + a->d.len, buf, size);
    2148       34492 :           buflen -= size;
    2149       34492 :           buf += size;
    2150       34492 :           a->d.len += size;
    2151             :         }
    2152       35534 :       if (buflen)
    2153             :         {
    2154        2598 :           rc = filter_flush (a);
    2155        2598 :           if (rc)
    2156           0 :             return rc;
    2157             :         }
    2158             :     }
    2159       35534 :   while (buflen);
    2160       32936 :   return 0;
    2161             : }
    2162             : 
    2163             : 
    2164             : int
    2165       11232 : iobuf_writestr (iobuf_t a, const char *buf)
    2166             : {
    2167       11232 :   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
    2168             :     {
    2169           0 :       log_bug ("iobuf_writestr called on an input pipeline!\n");
    2170             :       return -1;
    2171             :     }
    2172             : 
    2173       11232 :   return iobuf_write (a, buf, strlen (buf));
    2174             : }
    2175             : 
    2176             : 
    2177             : 
    2178             : int
    2179        1034 : iobuf_write_temp (iobuf_t dest, iobuf_t source)
    2180             : {
    2181        1034 :   assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
    2182        1034 :   assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
    2183             : 
    2184        1034 :   iobuf_flush_temp (source);
    2185        1034 :   return iobuf_write (dest, source->d.buf, source->d.len);
    2186             : }
    2187             : 
    2188             : size_t
    2189          47 : iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
    2190             : {
    2191             :   size_t n;
    2192             : 
    2193             :   while (1)
    2194             :     {
    2195          47 :       int rc = filter_flush (a);
    2196          47 :       if (rc)
    2197           0 :         log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed.  Ignoring.\n",
    2198             :                  a->no, a->subno, iobuf_desc (a));
    2199          47 :       if (! a->chain)
    2200          46 :         break;
    2201           1 :       a = a->chain;
    2202           1 :     }
    2203             : 
    2204          46 :   n = a->d.len;
    2205          46 :   if (n > buflen)
    2206           0 :     n = buflen;
    2207          46 :   memcpy (buffer, a->d.buf, n);
    2208          46 :   return n;
    2209             : }
    2210             : 
    2211             : /* Copies the data from the input iobuf SOURCE to the output iobuf
    2212             :    DEST until either an error is encountered or EOF is reached.
    2213             :    Returns the number of bytes copies.  */
    2214             : size_t
    2215           0 : iobuf_copy (iobuf_t dest, iobuf_t source)
    2216             : {
    2217             :   char *temp;
    2218             :   /* Use a 1 MB buffer.  */
    2219           0 :   const size_t temp_size = 1024 * 1024;
    2220             : 
    2221             :   size_t nread;
    2222           0 :   size_t nwrote = 0;
    2223             :   int err;
    2224             : 
    2225           0 :   assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
    2226           0 :   assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
    2227             : 
    2228           0 :   temp = xmalloc (temp_size);
    2229             :   while (1)
    2230             :     {
    2231           0 :       nread = iobuf_read (source, temp, temp_size);
    2232           0 :       if (nread == -1)
    2233             :         /* EOF.  */
    2234           0 :         break;
    2235             : 
    2236           0 :       err = iobuf_write (dest, temp, nread);
    2237           0 :       if (err)
    2238           0 :         break;
    2239           0 :       nwrote += nread;
    2240           0 :     }
    2241           0 :   xfree (temp);
    2242             : 
    2243           0 :   return nwrote;
    2244             : }
    2245             : 
    2246             : 
    2247             : void
    2248        1034 : iobuf_flush_temp (iobuf_t temp)
    2249             : {
    2250        1034 :   if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
    2251           0 :     log_bug ("iobuf_writestr called on an input pipeline!\n");
    2252        2068 :   while (temp->chain)
    2253           0 :     pop_filter (temp, temp->filter, NULL);
    2254        1034 : }
    2255             : 
    2256             : 
    2257             : void
    2258           0 : iobuf_set_limit (iobuf_t a, off_t nlimit)
    2259             : {
    2260           0 :   if (nlimit)
    2261           0 :     a->nofast = 1;
    2262             :   else
    2263           0 :     a->nofast = 0;
    2264           0 :   a->nlimit = nlimit;
    2265           0 :   a->ntotal += a->nbytes;
    2266           0 :   a->nbytes = 0;
    2267           0 : }
    2268             : 
    2269             : 
    2270             : 
    2271             : off_t
    2272         860 : iobuf_get_filelength (iobuf_t a, int *overflow)
    2273             : {
    2274             :   struct stat st;
    2275             : 
    2276         860 :   if (overflow)
    2277         860 :     *overflow = 0;
    2278             : 
    2279             :   /* Hmmm: file_filter may have already been removed */
    2280         860 :   for ( ; a->chain; a = a->chain )
    2281             :     ;
    2282             : 
    2283         860 :   if (a->filter != file_filter)
    2284           0 :     return 0;
    2285             : 
    2286             :   {
    2287         860 :     file_filter_ctx_t *b = a->filter_ov;
    2288         860 :     gnupg_fd_t fp = b->fp;
    2289             : 
    2290             : #if defined(HAVE_W32_SYSTEM)
    2291             :     ulong size;
    2292             :     static int (* __stdcall get_file_size_ex) (void *handle,
    2293             :                                                LARGE_INTEGER *r_size);
    2294             :     static int get_file_size_ex_initialized;
    2295             : 
    2296             :     if (!get_file_size_ex_initialized)
    2297             :       {
    2298             :         void *handle;
    2299             : 
    2300             :         handle = dlopen ("kernel32.dll", RTLD_LAZY);
    2301             :         if (handle)
    2302             :           {
    2303             :             get_file_size_ex = dlsym (handle, "GetFileSizeEx");
    2304             :             if (!get_file_size_ex)
    2305             :               dlclose (handle);
    2306             :           }
    2307             :         get_file_size_ex_initialized = 1;
    2308             :       }
    2309             : 
    2310             :     if (get_file_size_ex)
    2311             :       {
    2312             :         /* This is a newer system with GetFileSizeEx; we use this
    2313             :            then because it seem that GetFileSize won't return a
    2314             :            proper error in case a file is larger than 4GB. */
    2315             :         LARGE_INTEGER exsize;
    2316             : 
    2317             :         if (get_file_size_ex (fp, &exsize))
    2318             :           {
    2319             :             if (!exsize.u.HighPart)
    2320             :               return exsize.u.LowPart;
    2321             :             if (overflow)
    2322             :               *overflow = 1;
    2323             :             return 0;
    2324             :           }
    2325             :       }
    2326             :     else
    2327             :       {
    2328             :         if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
    2329             :           return size;
    2330             :       }
    2331             :     log_error ("GetFileSize for handle %p failed: %s\n",
    2332             :                fp, w32_strerror (0));
    2333             : #else
    2334         860 :     if ( !fstat (FD2INT (fp), &st) )
    2335         860 :       return st.st_size;
    2336           0 :     log_error("fstat() failed: %s\n", strerror(errno) );
    2337             : #endif
    2338             :   }
    2339             : 
    2340           0 :   return 0;
    2341             : }
    2342             : 
    2343             : 
    2344             : int
    2345        1178 : iobuf_get_fd (iobuf_t a)
    2346             : {
    2347        1178 :   for (; a->chain; a = a->chain)
    2348             :     ;
    2349             : 
    2350        1178 :   if (a->filter != file_filter)
    2351           0 :     return -1;
    2352             : 
    2353             :   {
    2354        1178 :     file_filter_ctx_t *b = a->filter_ov;
    2355        1178 :     gnupg_fd_t fp = b->fp;
    2356             : 
    2357        1178 :     return FD2INT (fp);
    2358             :   }
    2359             : }
    2360             : 
    2361             : 
    2362             : off_t
    2363           6 : iobuf_tell (iobuf_t a)
    2364             : {
    2365           6 :   return a->ntotal + a->nbytes;
    2366             : }
    2367             : 
    2368             : 
    2369             : #if !defined(HAVE_FSEEKO) && !defined(fseeko)
    2370             : 
    2371             : #ifdef HAVE_LIMITS_H
    2372             : # include <limits.h>
    2373             : #endif
    2374             : #ifndef LONG_MAX
    2375             : # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
    2376             : #endif
    2377             : #ifndef LONG_MIN
    2378             : # define LONG_MIN (-1 - LONG_MAX)
    2379             : #endif
    2380             : 
    2381             : /****************
    2382             :  * A substitute for fseeko, for hosts that don't have it.
    2383             :  */
    2384             : static int
    2385             : fseeko (FILE * stream, off_t newpos, int whence)
    2386             : {
    2387             :   while (newpos != (long) newpos)
    2388             :     {
    2389             :       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
    2390             :       if (fseek (stream, pos, whence) != 0)
    2391             :         return -1;
    2392             :       newpos -= pos;
    2393             :       whence = SEEK_CUR;
    2394             :     }
    2395             :   return fseek (stream, (long) newpos, whence);
    2396             : }
    2397             : #endif
    2398             : 
    2399             : int
    2400           0 : iobuf_seek (iobuf_t a, off_t newpos)
    2401             : {
    2402           0 :   file_filter_ctx_t *b = NULL;
    2403             : 
    2404           0 :   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
    2405             :     {
    2406             :       /* Find the last filter in the pipeline.  */
    2407           0 :       for (; a->chain; a = a->chain)
    2408             :         ;
    2409             : 
    2410           0 :       if (a->filter != file_filter)
    2411           0 :         return -1;
    2412             : 
    2413           0 :       b = a->filter_ov;
    2414             : 
    2415             : #ifdef HAVE_W32_SYSTEM
    2416             :       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
    2417             :         {
    2418             :           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
    2419             :                      b->fp, (int) GetLastError ());
    2420             :           return -1;
    2421             :         }
    2422             : #else
    2423           0 :       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
    2424             :         {
    2425           0 :           log_error ("can't lseek: %s\n", strerror (errno));
    2426           0 :           return -1;
    2427             :         }
    2428             : #endif
    2429             :       /* Discard the buffer it is not a temp stream.  */
    2430           0 :       a->d.len = 0;
    2431             :     }
    2432           0 :   a->d.start = 0;
    2433           0 :   a->nbytes = 0;
    2434           0 :   a->nlimit = 0;
    2435           0 :   a->nofast = 0;
    2436           0 :   a->ntotal = newpos;
    2437           0 :   a->error = 0;
    2438             : 
    2439             :   /* It is impossible for A->CHAIN to be non-NULL.  If A is an INPUT
    2440             :      or OUTPUT buffer, then we find the last filter, which is defined
    2441             :      as A->CHAIN being NULL.  If A is a TEMP filter, then A must be
    2442             :      the only filter in the pipe: when iobuf_push_filter adds a filter
    2443             :      to the front of a pipeline, it sets the new filter to be an
    2444             :      OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
    2445             :      to be an INPUT filter if the pipeline is an INPUT pipeline.
    2446             :      Thus, only the last filter in a TEMP pipeline can be a */
    2447             : 
    2448             :   /* remove filters, but the last */
    2449           0 :   if (a->chain)
    2450           0 :     log_debug ("pop_filter called in iobuf_seek - please report\n");
    2451           0 :   while (a->chain)
    2452           0 :     pop_filter (a, a->filter, NULL);
    2453             : 
    2454           0 :   return 0;
    2455             : }
    2456             : 
    2457             : 
    2458             : const char *
    2459         526 : iobuf_get_real_fname (iobuf_t a)
    2460             : {
    2461         526 :   if (a->real_fname)
    2462         512 :     return a->real_fname;
    2463             : 
    2464             :   /* the old solution */
    2465          53 :   for (; a; a = a->chain)
    2466          53 :     if (!a->chain && a->filter == file_filter)
    2467             :       {
    2468          14 :         file_filter_ctx_t *b = a->filter_ov;
    2469          14 :         return b->print_only_name ? NULL : b->fname;
    2470             :       }
    2471             : 
    2472           0 :   return NULL;
    2473             : }
    2474             : 
    2475             : const char *
    2476           0 : iobuf_get_fname (iobuf_t a)
    2477             : {
    2478           0 :   for (; a; a = a->chain)
    2479           0 :     if (!a->chain && a->filter == file_filter)
    2480             :       {
    2481           0 :         file_filter_ctx_t *b = a->filter_ov;
    2482           0 :         return b->fname;
    2483             :       }
    2484           0 :   return NULL;
    2485             : }
    2486             : 
    2487             : const char *
    2488           0 : iobuf_get_fname_nonnull (iobuf_t a)
    2489             : {
    2490             :   const char *fname;
    2491             : 
    2492           0 :   fname = iobuf_get_fname (a);
    2493           0 :   return fname? fname : "[?]";
    2494             : }
    2495             : 
    2496             : 
    2497             : /****************
    2498             :  * enable partial block mode as described in the OpenPGP draft.
    2499             :  * LEN is the first length byte on read, but ignored on writes.
    2500             :  */
    2501             : void
    2502         809 : iobuf_set_partial_block_mode (iobuf_t a, size_t len)
    2503             : {
    2504         809 :   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
    2505             : 
    2506         809 :   ctx->use = a->use;
    2507         809 :   if (!len)
    2508             :     {
    2509          28 :       if (a->use == IOBUF_INPUT)
    2510           0 :         log_debug ("pop_filter called in set_partial_block_mode"
    2511             :                    " - please report\n");
    2512             :       /* XXX: This pop_filter doesn't make sense.  Since we haven't
    2513             :          actually added the filter to the pipeline yet, why are we
    2514             :          popping anything?  Moreover, since we don't report an error,
    2515             :          the caller won't directly see an error.  I think that it
    2516             :          would be better to push the filter and set a->error to
    2517             :          GPG_ERR_BAD_DATA, but Werner thinks it's impossible for len
    2518             :          to be 0 (but he doesn't want to remove the check just in
    2519             :          case).  */
    2520          28 :       pop_filter (a, block_filter, NULL);
    2521             :     }
    2522             :   else
    2523             :     {
    2524         781 :       ctx->partial = 1;
    2525         781 :       ctx->size = 0;
    2526         781 :       ctx->first_c = len;
    2527         781 :       iobuf_push_filter (a, block_filter, ctx);
    2528             :     }
    2529         809 : }
    2530             : 
    2531             : 
    2532             : 
    2533             : unsigned int
    2534       28997 : iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
    2535             :                  unsigned *length_of_buffer, unsigned *max_length)
    2536             : {
    2537             :   int c;
    2538       28997 :   char *buffer = (char *)*addr_of_buffer;
    2539       28997 :   unsigned length = *length_of_buffer;
    2540       28997 :   unsigned nbytes = 0;
    2541       28997 :   unsigned maxlen = *max_length;
    2542             :   char *p;
    2543             : 
    2544             :   /* The code assumes that we have space for at least a newline and a
    2545             :      NUL character in the buffer.  This requires at least 2 bytes.  We
    2546             :      don't complicate the code by handling the stupid corner case, but
    2547             :      simply assert that it can't happen.  */
    2548       28997 :   assert (length >= 2 || maxlen >= 2);
    2549             : 
    2550       28997 :   if (!buffer || length <= 1)
    2551             :     /* must allocate a new buffer */
    2552             :     {
    2553         146 :       length = 256 <= maxlen ? 256 : maxlen;
    2554         146 :       buffer = xrealloc (buffer, length);
    2555         146 :       *addr_of_buffer = (unsigned char *)buffer;
    2556         146 :       *length_of_buffer = length;
    2557             :     }
    2558             : 
    2559       28997 :   p = buffer;
    2560     1579344 :   while ((c = iobuf_get (a)) != -1)
    2561             :     {
    2562     1550067 :       *p++ = c;
    2563     1550067 :       nbytes++;
    2564     1550067 :       if (c == '\n')
    2565       28715 :         break;
    2566             : 
    2567     1521352 :       if (nbytes == length - 1)
    2568             :         /* We don't have enough space to add a \n and a \0.  Increase
    2569             :            the buffer size.  */
    2570             :         {
    2571           4 :           if (length == maxlen)
    2572             :             /* We reached the buffer's size limit!  */
    2573             :             {
    2574             :               /* Skip the rest of the line.  */
    2575           2 :               while (c != '\n' && (c = iobuf_get (a)) != -1)
    2576             :                 ;
    2577             : 
    2578             :               /* p is pointing at the last byte in the buffer.  We
    2579             :                  always terminate the line with "\n\0" so overwrite
    2580             :                  the previous byte with a \n.  */
    2581           2 :               assert (p > buffer);
    2582           2 :               p[-1] = '\n';
    2583             : 
    2584             :               /* Indicate truncation.  */
    2585           2 :               *max_length = 0;
    2586           2 :               break;
    2587             :             }
    2588             : 
    2589           2 :           length += length < 1024 ? 256 : 1024;
    2590           2 :           if (length > maxlen)
    2591           1 :             length = maxlen;
    2592             : 
    2593           2 :           buffer = xrealloc (buffer, length);
    2594           2 :           *addr_of_buffer = (unsigned char *)buffer;
    2595           2 :           *length_of_buffer = length;
    2596           2 :           p = buffer + nbytes;
    2597             :         }
    2598             :     }
    2599             :   /* Add the terminating NUL.  */
    2600       28997 :   *p = 0;
    2601             : 
    2602             :   /* Return the number of characters written to the buffer including
    2603             :      the newline, but not including the terminating NUL.  */
    2604       28997 :   return nbytes;
    2605             : }
    2606             : 
    2607             : static int
    2608           0 : translate_file_handle (int fd, int for_write)
    2609             : {
    2610             : #if defined(HAVE_W32CE_SYSTEM)
    2611             :   /* This is called only with one of the special filenames.  Under
    2612             :      W32CE the FD here is not a file descriptor but a rendezvous id,
    2613             :      thus we need to finish the pipe first.  */
    2614             :   fd = _assuan_w32ce_finish_pipe (fd, for_write);
    2615             : #elif defined(HAVE_W32_SYSTEM)
    2616             :   {
    2617             :     int x;
    2618             : 
    2619             :     (void)for_write;
    2620             : 
    2621             :     if (fd == 0)
    2622             :       x = (int) GetStdHandle (STD_INPUT_HANDLE);
    2623             :     else if (fd == 1)
    2624             :       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
    2625             :     else if (fd == 2)
    2626             :       x = (int) GetStdHandle (STD_ERROR_HANDLE);
    2627             :     else
    2628             :       x = fd;
    2629             : 
    2630             :     if (x == -1)
    2631             :       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
    2632             :                  fd, (int) GetLastError ());
    2633             : 
    2634             :     fd = x;
    2635             :   }
    2636             : #else
    2637             :   (void)for_write;
    2638             : #endif
    2639           0 :   return fd;
    2640             : }
    2641             : 
    2642             : 
    2643             : void
    2644       12018 : iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
    2645             : {
    2646       12018 :   if ( partial )
    2647             :     {
    2648             :       for (;;)
    2649             :         {
    2650           0 :           if (a->nofast || a->d.start >= a->d.len)
    2651             :             {
    2652           0 :               if (iobuf_readbyte (a) == -1)
    2653             :                 {
    2654           0 :                   break;
    2655             :                 }
    2656             :             }
    2657             :           else
    2658             :             {
    2659           0 :               unsigned long count = a->d.len - a->d.start;
    2660           0 :               a->nbytes += count;
    2661           0 :               a->d.start = a->d.len;
    2662             :             }
    2663           0 :         }
    2664             :     }
    2665             :   else
    2666             :     {
    2667       12018 :       unsigned long remaining = n;
    2668       24037 :       while (remaining > 0)
    2669             :         {
    2670           2 :           if (a->nofast || a->d.start >= a->d.len)
    2671             :             {
    2672           1 :               if (iobuf_readbyte (a) == -1)
    2673             :                 {
    2674           1 :                   break;
    2675             :                 }
    2676           0 :               --remaining;
    2677             :             }
    2678             :           else
    2679             :             {
    2680           1 :               unsigned long count = a->d.len - a->d.start;
    2681           1 :               if (count > remaining)
    2682             :                 {
    2683           0 :                   count = remaining;
    2684             :                 }
    2685           1 :               a->nbytes += count;
    2686           1 :               a->d.start += count;
    2687           1 :               remaining -= count;
    2688             :             }
    2689             :         }
    2690             :     }
    2691       12018 : }

Generated by: LCOV version 1.11