~noskcaj/ubuntu/trusty/gpgme1.0/1.4.3

« back to all changes in this revision

Viewing changes to assuan/assuan-buffer.c

  • Committer: Bazaar Package Importer
  • Author(s): Jose Carlos Garcia Sogo
  • Date: 2008-03-08 14:06:34 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080308140634-dom8okim5mdkz22o
Tags: 1.1.6-2
* Bump shlibs info, as this version added some new symbols (Closes: #469534)
* Urgency set to medium, as this package has yet transitioned to lenny.
* debian/control: add Vcs-Browser info 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* assuan-buffer.c - read and send data
2
 
 *      Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of Assuan.
5
5
 *
15
15
 *
16
16
 * You should have received a copy of the GNU Lesser General Public
17
17
 * License along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
19
 * USA. 
19
20
 */
20
21
 
21
22
#include <config.h>
30
31
#endif
31
32
#include "assuan-defs.h"
32
33
 
 
34
 
 
35
/* Extended version of write(2) to guarantee that all bytes are
 
36
   written.  Returns 0 on success or -1 and ERRNO on failure. */
33
37
static int
34
 
writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
 
38
writen (assuan_context_t ctx, const char *buffer, size_t length)
35
39
{
36
40
  while (length)
37
41
    {
49
53
  return 0;  /* okay */
50
54
}
51
55
 
52
 
/* Read an entire line.  */
 
56
/* Read an entire line. Returns 0 on success or -1 and ERRNo on
 
57
   failure.  EOF is indictated by setting the integer at address
 
58
   R_EOF.  */
53
59
static int
54
 
readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
 
60
readline (assuan_context_t ctx, char *buf, size_t buflen,
55
61
          int *r_nread, int *r_eof)
56
62
{
57
63
  size_t nleft = buflen;
88
94
}
89
95
 
90
96
 
91
 
int
92
 
_assuan_read_line (ASSUAN_CONTEXT ctx)
 
97
/* Function returns an Assuan error. */
 
98
assuan_error_t
 
99
_assuan_read_line (assuan_context_t ctx)
93
100
{
94
101
  char *line = ctx->inbound.line;
95
102
  int nread, atticlen;
97
104
  char *endp = 0;
98
105
 
99
106
  if (ctx->inbound.eof)
100
 
    return -1;
 
107
    return _assuan_error (-1);
101
108
 
102
109
  atticlen = ctx->inbound.attic.linelen;
103
110
  if (atticlen)
128
135
  if (rc)
129
136
    {
130
137
      if (ctx->log_fp)
131
 
        fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
 
138
        fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s (%d)]\n",
132
139
                 assuan_get_assuan_log_prefix (),
133
 
                 (unsigned int)getpid (), ctx, strerror (errno));
134
 
      return ASSUAN_Read_Error;
 
140
                 (unsigned int)getpid (), ctx->inbound.fd,
 
141
                 strerror (errno), errno);
 
142
      return _assuan_error (ASSUAN_Read_Error);
135
143
    }
136
144
  if (!nread)
137
145
    {
138
146
      assert (ctx->inbound.eof);
139
147
      if (ctx->log_fp)
140
 
        fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
 
148
        fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [EOF]\n",
141
149
                 assuan_get_assuan_log_prefix (),
142
 
                 (unsigned int)getpid (), ctx);
143
 
      return -1;
 
150
                 (unsigned int)getpid (), ctx->inbound.fd);
 
151
      return _assuan_error (-1);
144
152
    }
145
153
 
146
154
  ctx->inbound.attic.pending = 0;
151
159
 
152
160
  if (endp)
153
161
    {
 
162
      unsigned monitor_result;
154
163
      int n = endp - line + 1;
 
164
 
155
165
      if (n < nread)
156
166
        /* LINE contains more than one line.  We copy it to the attic
157
167
           now as handlers are allowed to modify the passed
168
178
      *endp = 0;
169
179
 
170
180
      ctx->inbound.linelen = endp - line;
171
 
      if (ctx->log_fp)
 
181
 
 
182
      monitor_result = (ctx->io_monitor
 
183
                        ? ctx->io_monitor (ctx, 0,
 
184
                                           ctx->inbound.line,
 
185
                                           ctx->inbound.linelen)
 
186
                        : 0);
 
187
      if ( (monitor_result & 2) )
 
188
        ctx->inbound.linelen = 0;
 
189
      
 
190
      if (ctx->log_fp && !(monitor_result & 1))
172
191
        {
173
 
          fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
 
192
          fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ",
174
193
                   assuan_get_assuan_log_prefix (),
175
 
                   (unsigned int)getpid (), ctx);
 
194
                   (unsigned int)getpid (), ctx->inbound.fd);
176
195
          if (ctx->confidential)
177
196
            fputs ("[Confidential data not shown]", ctx->log_fp);
178
197
          else
186
205
  else
187
206
    {
188
207
      if (ctx->log_fp)
189
 
        fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
 
208
        fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Invalid line]\n",
190
209
                 assuan_get_assuan_log_prefix (),
191
 
                 (unsigned int)getpid (), ctx);
 
210
                 (unsigned int)getpid (), ctx->inbound.fd);
192
211
      *line = 0;
193
212
      ctx->inbound.linelen = 0;
194
 
      return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
195
 
        : ASSUAN_Line_Too_Long;
 
213
      return _assuan_error (ctx->inbound.eof 
 
214
                            ? ASSUAN_Line_Not_Terminated
 
215
                            : ASSUAN_Line_Too_Long);
196
216
    }
197
217
}
198
218
 
207
227
   See also: assuan_pending_line().
208
228
*/
209
229
assuan_error_t
210
 
assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
 
230
assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen)
211
231
{
212
232
  assuan_error_t err;
213
233
 
214
234
  if (!ctx)
215
 
    return ASSUAN_Invalid_Value;
 
235
    return _assuan_error (ASSUAN_Invalid_Value);
216
236
 
217
237
  err = _assuan_read_line (ctx);
218
238
  *line = ctx->inbound.line;
224
244
/* Return true if a full line is buffered (i.e. an entire line may be
225
245
   read without any I/O).  */
226
246
int
227
 
assuan_pending_line (ASSUAN_CONTEXT ctx)
 
247
assuan_pending_line (assuan_context_t ctx)
228
248
{
229
249
  return ctx && ctx->inbound.attic.pending;
230
250
}
234
254
_assuan_write_line (assuan_context_t ctx, const char *prefix,
235
255
                    const char *line, size_t len)
236
256
{
237
 
  int rc = 0;
 
257
  assuan_error_t rc = 0;
238
258
  size_t prefixlen = prefix? strlen (prefix):0;
 
259
  unsigned int monitor_result;
239
260
 
240
261
  /* Make sure that the line is short enough. */
241
262
  if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
242
263
    {
243
264
      if (ctx->log_fp)
244
 
        fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
 
265
        fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
245
266
                 "[supplied line too long -truncated]\n",
246
267
                 assuan_get_assuan_log_prefix (),
247
 
                 (unsigned int)getpid (), ctx);
 
268
                 (unsigned int)getpid (), ctx->inbound.fd);
248
269
      if (prefixlen > 5)
249
270
        prefixlen = 5;
250
271
      if (len > ASSUAN_LINELENGTH - prefixlen - 2)
251
272
        len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
252
273
    }
253
274
 
 
275
  monitor_result = (ctx->io_monitor
 
276
                    ? ctx->io_monitor (ctx, 1, line, len)
 
277
                    : 0);
 
278
 
254
279
  /* Fixme: we should do some kind of line buffering.  */
255
 
  if (ctx->log_fp)
 
280
  if (ctx->log_fp && !(monitor_result & 1))
256
281
    {
257
 
      fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
 
282
      fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
258
283
               assuan_get_assuan_log_prefix (),
259
 
               (unsigned int)getpid (), ctx);
 
284
               (unsigned int)getpid (), ctx->inbound.fd);
260
285
      if (ctx->confidential)
261
286
        fputs ("[Confidential data not shown]", ctx->log_fp);
262
287
      else
263
 
        _assuan_log_print_buffer (ctx->log_fp, line, len);
 
288
        {
 
289
          if (prefixlen)
 
290
            _assuan_log_print_buffer (ctx->log_fp, prefix, prefixlen);
 
291
          _assuan_log_print_buffer (ctx->log_fp, line, len);
 
292
        }
264
293
      putc ('\n', ctx->log_fp);
265
294
    }
266
295
 
267
 
  if (prefixlen)
 
296
  if (prefixlen && !(monitor_result & 2))
268
297
    {
269
298
      rc = writen (ctx, prefix, prefixlen);
270
299
      if (rc)
271
 
        rc = ASSUAN_Write_Error;
 
300
        rc = _assuan_error (ASSUAN_Write_Error);
272
301
    }
273
 
  if (!rc)
 
302
  if (!rc && !(monitor_result & 2))
274
303
    {
275
304
      rc = writen (ctx, line, len);
276
305
      if (rc)
277
 
        rc = ASSUAN_Write_Error;
 
306
        rc = _assuan_error (ASSUAN_Write_Error);
278
307
      if (!rc)
279
308
        {
280
309
          rc = writen (ctx, "\n", 1);
281
310
          if (rc)
282
 
            rc = ASSUAN_Write_Error;
 
311
            rc = _assuan_error (ASSUAN_Write_Error);
283
312
        }
284
313
    }
285
314
  return rc;
287
316
 
288
317
 
289
318
assuan_error_t 
290
 
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line)
 
319
assuan_write_line (assuan_context_t ctx, const char *line)
291
320
{
292
321
  size_t len;
293
322
  const char *s;
294
323
 
295
324
  if (!ctx)
296
 
    return ASSUAN_Invalid_Value;
 
325
    return _assuan_error (ASSUAN_Invalid_Value);
297
326
 
298
327
  /* Make sure that we never take a LF from the user - this might
299
328
     violate the protocol. */
301
330
  len = s? (s-line) : strlen (line);
302
331
 
303
332
  if (ctx->log_fp && s)
304
 
    fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
305
 
             "[supplied line contained a LF -truncated]\n",
 
333
    fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
 
334
             "[supplied line contained a LF - truncated]\n",
306
335
             assuan_get_assuan_log_prefix (),
307
 
             (unsigned int)getpid (), ctx);
 
336
             (unsigned int)getpid (), ctx->inbound.fd);
308
337
 
309
338
  return _assuan_write_line (ctx, NULL, line, len);
310
339
}
312
341
 
313
342
 
314
343
/* Write out the data in buffer as datalines with line wrapping and
315
 
   percent escaping.  This function is used for GNU's custom streams */
 
344
   percent escaping.  This function is used for GNU's custom streams. */
316
345
int
317
346
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
318
347
{
319
 
  ASSUAN_CONTEXT ctx = cookie;
 
348
  assuan_context_t ctx = cookie;
320
349
  size_t size = orig_size;
321
350
  char *line;
322
351
  size_t linelen;
329
358
  line += linelen;
330
359
  while (size)
331
360
    {
332
 
      /* insert data line header */
 
361
      unsigned int monitor_result;
 
362
 
 
363
      /* Insert data line header. */
333
364
      if (!linelen)
334
365
        {
335
366
          *line++ = 'D';
337
368
          linelen += 2;
338
369
        }
339
370
      
340
 
      /* copy data, keep some space for the CRLF and to escape one character */
 
371
      /* Copy data, keep space for the CRLF and to escape one character. */
341
372
      while (size && linelen < LINELENGTH-2-2)
342
373
        {
343
374
          if (*buffer == '%' || *buffer == '\r' || *buffer == '\n')
355
386
          size--;
356
387
        }
357
388
      
 
389
      
 
390
      monitor_result = (ctx->io_monitor
 
391
                        ? ctx->io_monitor (ctx, 1,
 
392
                                           ctx->outbound.data.line, linelen)
 
393
                        : 0);
 
394
 
358
395
      if (linelen >= LINELENGTH-2-2)
359
396
        {
360
 
          if (ctx->log_fp)
 
397
          if (ctx->log_fp && !(monitor_result & 1))
361
398
            {
362
 
              fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
 
399
              fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
363
400
                       assuan_get_assuan_log_prefix (),
364
 
                       (unsigned int)getpid (), ctx);
 
401
                       (unsigned int)getpid (), ctx->inbound.fd);
365
402
 
366
403
              if (ctx->confidential)
367
404
                fputs ("[Confidential data not shown]", ctx->log_fp);
373
410
            }
374
411
          *line++ = '\n';
375
412
          linelen++;
376
 
          if (writen (ctx, ctx->outbound.data.line, linelen))
 
413
          if ( !(monitor_result & 2)
 
414
               && writen (ctx, ctx->outbound.data.line, linelen))
377
415
            {
378
 
              ctx->outbound.data.error = ASSUAN_Write_Error;
 
416
              ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
379
417
              return 0;
380
418
            }
381
419
          line = ctx->outbound.data.line;
393
431
int
394
432
_assuan_cookie_write_flush (void *cookie)
395
433
{
396
 
  ASSUAN_CONTEXT ctx = cookie;
 
434
  assuan_context_t ctx = cookie;
397
435
  char *line;
398
436
  size_t linelen;
 
437
  unsigned int monitor_result;
399
438
 
400
439
  if (ctx->outbound.data.error)
401
440
    return 0;
403
442
  line = ctx->outbound.data.line;
404
443
  linelen = ctx->outbound.data.linelen;
405
444
  line += linelen;
 
445
 
 
446
  monitor_result = (ctx->io_monitor
 
447
                    ? ctx->io_monitor (ctx, 1,
 
448
                                       ctx->outbound.data.line, linelen)
 
449
                    : 0);
 
450
  
406
451
  if (linelen)
407
452
    {
408
 
      if (ctx->log_fp)
 
453
      if (ctx->log_fp && !(monitor_result & 1))
409
454
        {
410
 
          fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
 
455
          fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
411
456
                   assuan_get_assuan_log_prefix (),
412
 
                   (unsigned int)getpid (), ctx);
 
457
                   (unsigned int)getpid (), ctx->inbound.fd);
413
458
          if (ctx->confidential)
414
459
            fputs ("[Confidential data not shown]", ctx->log_fp);
415
460
          else
419
464
        }
420
465
      *line++ = '\n';
421
466
      linelen++;
422
 
      if (writen (ctx, ctx->outbound.data.line, linelen))
 
467
      if ( !(monitor_result & 2)
 
468
           && writen (ctx, ctx->outbound.data.line, linelen))
423
469
        {
424
 
          ctx->outbound.data.error = ASSUAN_Write_Error;
 
470
          ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
425
471
          return 0;
426
472
        }
427
473
      ctx->outbound.data.linelen = 0;
449
495
 **/
450
496
 
451
497
assuan_error_t
452
 
assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
 
498
assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
453
499
{
454
500
  if (!ctx)
455
 
    return ASSUAN_Invalid_Value;
 
501
    return _assuan_error (ASSUAN_Invalid_Value);
456
502
  if (!buffer && length)
457
 
    return ASSUAN_Invalid_Value;
 
503
    return _assuan_error (ASSUAN_Invalid_Value);
458
504
 
459
505
  if (!buffer)
460
506
    { /* flush what we have */
475
521
}
476
522
 
477
523
assuan_error_t
478
 
assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
 
524
assuan_sendfd (assuan_context_t ctx, int fd)
479
525
{
 
526
  /* It is explicitly allowed to use (NULL, -1) as a runtime test to
 
527
     check whether descriptor passing is available. */
 
528
  if (!ctx && fd == -1)
 
529
#ifdef USE_DESCRIPTOR_PASSING
 
530
    return 0;
 
531
#else
 
532
    return _assuan_error (ASSUAN_Not_Implemented);
 
533
#endif
 
534
 
480
535
  if (! ctx->io->sendfd)
481
536
    return set_error (ctx, Not_Implemented,
482
537
                      "server does not support sending and receiving "
485
540
}
486
541
 
487
542
assuan_error_t
488
 
assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
 
543
assuan_receivefd (assuan_context_t ctx, int *fd)
489
544
{
490
545
  if (! ctx->io->receivefd)
491
546
    return set_error (ctx, Not_Implemented,