~ubuntu-branches/ubuntu/vivid/gnupg2/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/CVE-2013-4402.patch/common/iobuf.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-11-01 22:15:05 UTC
  • mfrom: (14.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20131101221505-i1zpbl1qd1a3gsvx
Tags: 2.0.22-1ubuntu1
* Merge from Debian, remaining changes:
  - Drop sh prefix from openpgp test environment as it leads to exec
  invocations of sh /bin/bash leading to syntax errors from sh.  Fixes
  FTBFS detected in Ubuntu saucy archive rebuild.
  - Add udev rules to give gpg access to some smartcard readers;
    Debian #543217.
  - debian/gnupg2.udev: udev rules to set ACLs on SCM smartcard readers.
  - Add upstart user job for gpg-agent.

Show diffs side-by-side

added added

removed removed

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