~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to common/iobuf.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

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