* README: Mentioned --enable-selinux-support.
[gnupg.git] / util / iobuf.c
index 3d55349..3a8f461 100644 (file)
@@ -1,5 +1,6 @@
 /* iobuf.c  -  file handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003,
+ *               2004 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -666,28 +667,20 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
                        }
                        a->size |= c;
                        a->partial = 2;
+                       if( !a->size ) {
+                           a->eof = 1;
+                           if( !n )
+                               rc = -1;
+                           break;
+                       }
                    }
                    else { /* next partial body length */
                        a->size = 1 << (c & 0x1f);
                    }
            /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size);*/
                }
-               else { /* the gnupg partial length scheme - much better :-) */
-                   c = iobuf_get(chain);
-                   a->size = c << 8;
-                   c = iobuf_get(chain);
-                   a->size |= c;
-                   if( c == -1 ) {
-                       log_error("block_filter: error reading length info\n");
-                       rc = G10ERR_READ_FILE;
-                   }
-                   if( !a->size ) {
-                       a->eof = 1;
-                       if( !n )
-                           rc = -1;
-                       break;
-                   }
-               }
+               else
+                 BUG();
            }
 
            while( !rc && size && a->size ) {
@@ -761,35 +754,8 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
                }
            }
        }
-       else { /* the gnupg scheme (which is not openpgp compliant) */
-           size_t avail, n;
-
-           for(p=buf; !rc && size; ) {
-               n = size;
-               avail = a->size - a->count;
-               if( !avail ) {
-                   if( n > a->size ) {
-                       iobuf_put( chain, (a->size >> 8) & 0xff );
-                       iobuf_put( chain, a->size & 0xff );
-                       avail = a->size;
-                       a->count = 0;
-                   }
-                   else {
-                       iobuf_put( chain, (n >> 8) & 0xff );
-                       iobuf_put( chain, n & 0xff );
-                       avail = n;
-                       a->count = a->size - n;
-                   }
-               }
-               if( n > avail )
-                   n = avail;
-               if( iobuf_write(chain, p, n ) )
-                   rc = G10ERR_WRITE_FILE;
-               a->count += n;
-               p += n;
-               size -= n;
-           }
-       }
+       else
+         BUG();
     }
     else if( control == IOBUFCTRL_INIT ) {
        if( DBG_IOBUF )
@@ -845,10 +811,8 @@ block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
                }
                m_free( a->buffer ); a->buffer = NULL; a->buflen = 0;
            }
-           else {
-               iobuf_writebyte(chain, 0);
-               iobuf_writebyte(chain, 0);
-           }
+           else
+             BUG();
        }
        else if( a->size ) {
            log_error("block_filter: pending bytes!\n");
@@ -1041,6 +1005,16 @@ check_special_filename ( const char *fname )
     return -1;
 }
 
+/* This fucntion returns true if FNAME indicates a PIPE (stdout or
+   stderr) or a special file name if those are enabled. */
+int
+iobuf_is_pipe_filename (const char *fname)
+{
+  if (!fname || (*fname=='-' && !fname[1]) )
+    return 1;
+  return check_special_filename (fname) != -1;
+}
+
 /****************
  * Create a head iobuf for reading from a file
  * returns: NULL if an error occures and sets errno
@@ -1390,7 +1364,7 @@ iobuf_push_filter2( IOBUF a,
 /****************
  * Remove an i/o filter.
  */
-int
+static int
 pop_filter( IOBUF a, int (*f)(void *opaque, int control,
                      IOBUF chain, byte *buf, size_t *len), void *ov )
 {
@@ -1876,6 +1850,28 @@ iobuf_get_filelength( IOBUF a )
     return 0;
 }
 
+
+/* Return the file descriptor of the underlying file or -1 if it is
+   not available.  */
+int 
+iobuf_get_fd (IOBUF a)
+{
+  if (a->directfp)
+    return fileno ( (FILE*)a->directfp );
+
+  for ( ; a; a = a->chain )
+    if (!a->chain && a->filter == file_filter)
+      {
+        file_filter_ctx_t *b = a->filter_ov;
+        FILEP_OR_FD fp = b->fp;
+
+        return my_fileno (fp);
+      }
+
+  return -1;
+}
+
+
 /****************
  * Tell the file position, where the next read will take place
  */
@@ -2017,28 +2013,6 @@ iobuf_get_fname( IOBUF a )
     return NULL;
 }
 
-/****************
- * Start the block write mode, see rfc1991.new for details.
- * A value of 0 for N stops this mode (flushes and writes
- * the end marker)
- */
-void
-iobuf_set_block_mode( IOBUF a, size_t n )
-{
-    block_filter_ctx_t *ctx = m_alloc_clear( sizeof *ctx );
-
-    assert( a->use == 1 || a->use == 2 );
-    ctx->use = a->use;
-    if( !n ) {
-       if( a->use == 1 )
-           log_debug("pop_filter called in set_block_mode - please report\n");
-       pop_filter(a, block_filter, NULL );
-    }
-    else {
-       ctx->size = n; /* only needed for use 2 */
-       iobuf_push_filter(a, block_filter, ctx );
-    }
-}
 
 /****************
  * enable partial block mode as described in the OpenPGP draft.
@@ -2067,19 +2041,6 @@ iobuf_set_partial_block_mode( IOBUF a, size_t len )
 
 
 /****************
- * Checks whether the stream is in block mode
- * Note: This does not work if other filters are pushed on the stream.
- */
-int
-iobuf_in_block_mode( IOBUF a )
-{
-    if( a && a->filter == block_filter )
-       return 1; /* yes */
-    return 0; /* no */
-}
-
-
-/****************
  * Same as fgets() but if the buffer is too short a larger one will
  * be allocated up to some limit *max_length.
  * A line is considered a byte stream ending in a LF.
@@ -2191,3 +2152,40 @@ translate_file_handle ( int fd, int for_write )
 #endif
     return fd;
 }
+
+
+void
+iobuf_skip_rest(IOBUF a, unsigned long n, int partial)
+{
+    if ( partial ) {
+       for (;;) {
+           if (a->nofast || a->d.start >= a->d.len) {
+               if (iobuf_readbyte (a) == -1) {
+                   break;
+               }
+           } else {
+               unsigned long count = a->d.len - a->d.start;
+               a->nbytes += count;
+               a->d.start = a->d.len;
+           }
+       }
+    } else {
+       unsigned long remaining = n;
+       while (remaining > 0) {
+           if (a->nofast || a->d.start >= a->d.len) {
+               if (iobuf_readbyte (a) == -1) {
+                   break;
+               }
+               --remaining;
+           } else {
+               unsigned long count = a->d.len - a->d.start;
+               if (count > remaining) {
+                   count = remaining;
+               }
+               a->nbytes += count;
+               a->d.start += count;
+               remaining -= count;
+           }
+       }
+    }
+}