Coverage Report

Created: 2022-12-08 06:10

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