This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

compiler fixup patch for cinstall && mingw && w32api. (whew) (pt1)


This is not final yet, which is why there is no changelog and it's not split up for the various different lists yet.

Firstly: the mingw stuff. The following function returned the error
"Is not a prototype"

Index: include/errno.h
===================================================================
RCS file: /cvs/src/src/winsup/mingw/include/errno.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 errno.h
--- errno.h 2000/02/17 19:38:31 1.1.1.1
+++ errno.h 2001/11/05 14:30:07
@@ -104,7 +104,7 @@ extern "C" {
#undef errno
extern int errno;
#else
-int* _errno();
+int* _errno(void);
#define errno (*_errno())
#endif

Now, w32api. This fixes two functions defined w/o prototype errors, and a "partially bracketed initializer" for the _AUTHORITITY constants.

Index: include/winnt.h
===================================================================
RCS file: /cvs/src/src/winsup/w32api/include/winnt.h,v
retrieving revision 1.31
diff -u -p -r1.31 winnt.h
--- winnt.h 2001/11/01 19:42:56 1.31
+++ winnt.h 2001/11/05 14:31:29
@@ -267,12 +267,12 @@ typedef BYTE BOOLEAN,*PBOOLEAN;
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF)
#define EXCEPTION_NONCONTINUABLE 1
#define EXCEPTION_MAXIMUM_PARAMETERS 15
-#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0}
-#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1}
-#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2}
-#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3}
-#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4}
-#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5}
+#define SECURITY_NULL_SID_AUTHORITY {{0,0,0,0,0,0}}
+#define SECURITY_WORLD_SID_AUTHORITY {{0,0,0,0,0,1}}
+#define SECURITY_LOCAL_SID_AUTHORITY {{0,0,0,0,0,2}}
+#define SECURITY_CREATOR_SID_AUTHORITY {{0,0,0,0,0,3}}
+#define SECURITY_NON_UNIQUE_AUTHORITY {{0,0,0,0,0,4}}
+#define SECURITY_NT_AUTHORITY {{0,0,0,0,0,5}}
#define SECURITY_NULL_RID 0
#define SECURITY_WORLD_RID 0
#define SECURITY_LOCAL_RID 0
@@ -2524,6 +2524,7 @@ typedef struct _REPARSE_POINT_INFORMATIO
WORD   ReparseDataLength;
WORD   UnparsedNameLength;
} REPARSE_POINT_INFORMATION, *PREPARSE_POINT_INFORMATION;
+PVOID GetCurrentFiber(void);
extern __inline__ PVOID GetCurrentFiber(void)
{
     void* ret;
@@ -2534,7 +2535,7 @@ extern __inline__ PVOID GetCurrentFiber(
);
     return ret;
}
-
+PVOID GetFiberData(void);
extern __inline__ PVOID GetFiberData(void)
{
     void* ret;


and now for... cinstall ... evolution isn't letting me add all the files... so heres pt1
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

/* Archive IO operations
 */

#if 0
static const char *cvsid =
  "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif
  
#include "win32.h"
#include <stdio.h>
#include "log.h"
#include "port.h"

#include "io_stream.h"
#include "archive.h"
#include "zlib/zlib.h"
#include "archive_gz.h"
#include "archive_bz.h"

/* In case you are wondering why the file magic is not in one place:
 * It could be. But there is little (any?) benefit.
 * What is important is that the file magic required for any _task_ is centralised.
 * One such task is identifying archives
 *
 * to federate into each class one might add a magic parameter to the constructor, which
 * the class could test itself. 
 */

#define longest_magic 3

io_stream *
archive::decompress (io_stream * original)
{
  if (!original)
    return NULL;
  char magic[longest_magic];
  if (original->peek (magic, longest_magic) > 0)
    {
      if (memcmp (magic, "\037\213", 2) == 0)
	{
	  /* tar */
	  archive_gz *rv = new archive_gz (original);
	  if (!rv->error ())
	    return rv;
	  return NULL;
	}
      else if (memcmp (magic, "BZh", 3) == 0)
	{
	  archive_bz *rv = new archive_bz (original);
	  if (!rv->error ())
	    return rv;
	  return NULL;
	}
    }
  return NULL;
}

ssize_t archive::read (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive::read called");
  return 0;
}

ssize_t archive::write (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive::write called");
  return 0;
}

ssize_t archive::peek (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive::peek called");
  return 0;
}

long
archive::tell ()
{
  log (LOG_TIMESTAMP, "bz::tell called");
  return 0;
}

int
archive::error ()
{
  log (LOG_TIMESTAMP, "archive::error called");
  return 0;
}

const char *
archive::next_file_name ()
{
  log (LOG_TIMESTAMP, "archive::next_file_name called");
  return NULL;
}

archive::~archive ()
{
  log (LOG_TIMESTAMP, "archive::~archive called");
  return;
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _ARCHIVE_H_
#define _ARCHIVE_H_

/* this is the parent class for all archive IO operations. 
 * It 
 */

class archive: public io_stream {
public:
  /* Get a decompressed stream from a normal stream. If this function returns non-null
   * a valid compress header was found. The io_stream pointer passed to decompress
   * should be discarded. The old io_stream will be automatically closed when the 
   * decompression stream is closed
   */
  static io_stream * decompress (io_stream *);
  /* 
   * To create a stream that will be compressed, you should open the url, and then get a new stream
   * from archive::compress. 
   */
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len);
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len);
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len);
  virtual long tell ();
  /* try guessing this one */
  virtual int error ();
  /* Find out the next stream name -
   * ie for foo.tar.gz, at offset 0, next_file_name = foo.tar
   * for foobar that is an archive, next_file_name is the next
   * extractable filename.
   */
  virtual const char* next_file_name() = NULL;
  /* if you are still needing these hints... give up now! */
  virtual ~archive ();
};

#endif /* _ARCHIVE_H_ */
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

/* Archive IO operations
 */

#if 0
static const char *cvsid = "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif

#include "win32.h"
#include <stdio.h>
#include <errno.h>
#include "log.h"
#include "port.h"

#include "io_stream.h"
#include "archive.h"
#include "archive_bz.h"

archive_bz::archive_bz (io_stream *original)
{
  original = NULL;
  lasterr = 0;
  if (!original)
    lasterr = EBADF;
}

ssize_t
archive_bz::read (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive_bz::read called");
  return 0;
}

ssize_t
archive_bz::write (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive_bz::write called");
  return 0;
}

ssize_t
archive_bz::peek (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive_bz::peek called");
  return 0;
}

long
archive_bz::tell ()
{
  log (LOG_TIMESTAMP, "archive_bz::tell called");
  return 0;
}

int
archive_bz::error ()
{
  log (LOG_TIMESTAMP, "archive_bz::error called");
  return 0;
}

archive_bz::~archive_bz ()
{
  log (LOG_TIMESTAMP, "archive_bz::~bz called");
  return;
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _BZ_H_
#define _BZ_H_

/* this is the parent class for all archive IO operations. 
 * It 
 */

class archive_bz: public archive {
public:
  archive_bz (io_stream *);
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len);
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len);
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len);
  virtual long tell ();
  /* try guessing this one */
  virtual int error ();
  /* Find out the next stream name -
   * ie for foo.tar.bz, at offset 0, next_file_name = foo.tar
   * for foobar that is an archive, next_file_name is the next
   * extractable filename.
   */
  virtual const char* next_file_name() {return NULL;};
  /* if you are still needing these hints... give up now! */
  virtual ~archive_bz ();
private:
  archive_bz () {};
  io_stream *original;
  int lasterr;
};

#endif /* _BZ_H_ */
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

/* Archive IO operations for gz files
 * Portions copyright under the zlib licence - this class was derived from gzio.c in that
 * library.
 */

#if 0
static const char *cvsid =
  "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif
  
#include "win32.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "log.h"
#include "port.h"

#include "io_stream.h"
#include "archive.h"
#include "zlib/zlib.h"
#include "archive_gz.h"

#define HEAD_CRC     0x02	/* bit 1 set: header CRC present */
#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
#define COMMENT      0x10	/* bit 4 set: file comment present */
#define RESERVED     0xE0	/* bits 5..7: reserved */


/* TODO make this a static member and federate the magic logic */
static int gz_magic[2] = { 0x1f, 0x8b };	/* gzip magic header */

/*
 * Predicate: the stream is open for read. For writing the class constructor variant with
 * mode must be called directly
 */
archive_gz::archive_gz (io_stream * parent)
{
  construct (parent, "r");
}

archive_gz::archive_gz (io_stream * parent, const char *openmode)
{
  construct (parent, openmode);
}

void
archive_gz::construct (io_stream * parent, const char *openmode)
{
  if (!parent)
    {
      z_err = Z_STREAM_ERROR;
      return;
    }

  original = parent;
  int err;
  int level = Z_DEFAULT_COMPRESSION;	/* compression level */
  int strategy = Z_DEFAULT_STRATEGY;	/* compression strategy */
  char *p = (char *) openmode;
  char fmode[80];		/* copy of openmode, without the compression level */
  char *m = fmode;

  stream.zalloc = (alloc_func) NULL;
  stream.zfree = (free_func) NULL;
  stream.opaque = (voidpf) NULL;
  stream.next_in = inbuf = NULL;
  stream.next_out = outbuf = NULL;
  stream.avail_in = stream.avail_out = 0;
  z_err = Z_OK;
  z_eof = 0;
  crc = crc32 (0L, Z_NULL, 0);
  msg = NULL;
  transparent = 0;

  mode = '\0';
  do
    {
      if (*p == 'r')
	mode = 'r';
      if (*p == 'w' || *p == 'a')
	mode = 'w';
      if (*p >= '0' && *p <= '9')
	{
	  level = *p - '0';
	}
      else if (*p == 'f')
	{
	  strategy = Z_FILTERED;
	}
      else if (*p == 'h')
	{
	  strategy = Z_HUFFMAN_ONLY;
	}
      else
	{
	  *m++ = *p;		/* copy the mode */
	}
    }
  while (*p++ && m != fmode + sizeof (fmode));
  if (mode == '\0')
    {
      destroy ();
      z_err = Z_STREAM_ERROR;
      return;
    }


  if (mode == 'w')
    {
      err = deflateInit2 (&(stream), level,
			  Z_DEFLATED, -MAX_WBITS, 8, strategy);
      /* windowBits is passed < 0 to suppress zlib header */

      stream.next_out = outbuf = (Byte *) malloc (16384);
      if (err != Z_OK || outbuf == Z_NULL)
	{
	  destroy ();
	  z_err = Z_STREAM_ERROR;
	  return;
	}
    }
  else
    {

      stream.next_in = inbuf = (unsigned char *) malloc (16384);
      err = inflateInit2 (&stream, -MAX_WBITS);
      /* windowBits is passed < 0 to tell that there is no zlib header.
       * Note that in this case inflate *requires* an extra "dummy" byte
       * after the compressed stream in order to complete decompression and
       * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
       * present after the compressed stream.
       */
      if (err != Z_OK || inbuf == Z_NULL)
	{
	  destroy ();
	  z_err = Z_STREAM_ERROR;
	  return;
	}
    }
  stream.avail_out = 16384;

  errno = 0;
  if (mode == 'w')
    {
      /* Write a very simple .gz header:
       */
      char temp[20];
      sprintf (temp, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
	       Z_DEFLATED, 0 /*flags */ , 0, 0, 0, 0 /*time */ ,
	       0 /*xflags */ , 0x0b);
      original->write (temp, 10);
      startpos = 10L;
      /* We use 10L instead of ftell(s->file) to because ftell causes an
       * fflush on some systems. This version of the library doesn't use
       * startpos anyway in write mode, so this initialization is not
       * necessary. 
       */
    }
  else
    {

      check_header ();		/* skip the .gz header */
      startpos = (original->tell () - stream.avail_in);
    }

  return;
}

/* ===========================================================================
   Outputs a long in LSB order to the given file
*/
void
archive_gz::putLong (unsigned long x)
{
  int n;
  for (n = 0; n < 4; n++)
    {
      unsigned char c = (unsigned char) (x & 0xff);
      original->write (&c, 1);
      x = x >> 8;
    }
}


uLong archive_gz::getLong ()
{
  uLong
    x = (uLong)
    get_byte ();
  int
    c;

  x += ((uLong) get_byte ()) << 8;
  x += ((uLong) get_byte ()) << 16;
  c = get_byte ();
  if (c == EOF)
    z_err = Z_DATA_ERROR;
  x += ((uLong) c) << 24;
  return x;
}


ssize_t archive_gz::read (void *buffer, size_t len)
{
  Bytef *
    start = (Bytef *)
    buffer;			/* starting point for crc computation */
  Byte *
    next_out;			/* == stream.next_out but not forced far (for MSDOS) */

  if (mode != 'r')
    return Z_STREAM_ERROR;

  if (z_err == Z_DATA_ERROR || z_err == Z_ERRNO)
    return -1;
  if (z_err == Z_STREAM_END)
    return 0;			/* EOF */

  next_out = (Byte *) buffer;
  stream.next_out = (Bytef *) buffer;
  stream.avail_out = len;

  while (stream.avail_out != 0)
    {

      if (transparent)
	{
	  /* Copy first the lookahead bytes: */
	  uInt
	    n =
	    stream.
	    avail_in;
	  if (n > stream.avail_out)
	    n = stream.avail_out;
	  if (n > 0)
	    {
	      memcpy (stream.next_out, stream.next_in, n);
	      next_out += n;
	      stream.next_out = next_out;
	      stream.next_in += n;
	      stream.avail_out -= n;
	      stream.avail_in -= n;
	    }
	  if (stream.avail_out > 0)
	    {
	      stream.avail_out -= original->read (next_out, stream.avail_out);
	    }
	  len -= stream.avail_out;
	  stream.total_in += (uLong) len;
	  stream.total_out += (uLong) len;
	  if (len == 0)
	    z_eof = 1;
	  return (int) len;
	}
      if (stream.avail_in == 0 && !z_eof)
	{

	  errno = 0;
	  stream.avail_in = original->read (inbuf, 16384);
	  if (stream.avail_in == 0)
	    {
	      z_eof = 1;
	      if (original->error ())
		{
		  z_err = Z_ERRNO;
		  break;
		}
	    }
	  stream.next_in = inbuf;
	}
      z_err = inflate (&(stream), Z_NO_FLUSH);

      if (z_err == Z_STREAM_END)
	{
	  /* Check CRC and original size */
	  crc = crc32 (crc, start, (uInt) (stream.next_out - start));
	  start = stream.next_out;

	  if (getLong () != crc)
	    {
	      z_err = Z_DATA_ERROR;
	    }
	  else
	    {
	      (void) getLong ();
	      /* The uncompressed length returned by above getlong() may
	       * be different from stream.total_out) in case of
	       * concatenated .gz files. Check for such files:
	       */
	      check_header ();
	      if (z_err == Z_OK)
		{
		  uLong
		    total_in =
		    stream.
		    total_in;
		  uLong
		    total_out =
		    stream.
		    total_out;

		  inflateReset (&(stream));
		  stream.total_in = total_in;
		  stream.total_out = total_out;
		  crc = crc32 (0L, Z_NULL, 0);
		}
	    }
	}
      if (z_err != Z_OK || z_eof)
	break;
    }
  crc = crc32 (crc, start, (uInt) (stream.next_out - start));

  return (int) (len - stream.avail_out);
}


/* ===========================================================================
   Writes the given number of uncompressed bytes into the compressed file.
   gzwrite returns the number of bytes actually written (0 in case of error).
*/
ssize_t archive_gz::write (void *buffer, size_t len)
{
  if (mode != 'w')
    return Z_STREAM_ERROR;

  stream.next_in = (Bytef *) buffer;
  stream.avail_in = len;

  while (stream.avail_in != 0)
    {

      if (stream.avail_out == 0)
	{

	  stream.next_out = outbuf;
	  if (original->write (outbuf, 16384) != 16384)
	    {
	      z_err = Z_ERRNO;
	      break;
	    }
	  stream.avail_out = 16384;
	}
      z_err = deflate (&(stream), Z_NO_FLUSH);
      if (z_err != Z_OK)
	break;
    }
  crc = crc32 (crc, (const Bytef *) buffer, len);

  return (int) (len - stream.avail_in);
}

ssize_t archive_gz::peek (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "archive_gz::peek called");
  if (mode != 'r')
    return Z_STREAM_ERROR;
  /* TODO: read up to len into the output buffer */
  return 0;
}

long
archive_gz::tell ()
{
  log (LOG_TIMESTAMP, "archive_gz::tell called");
  return 0;
}

int
archive_gz::error ()
{
  log (LOG_TIMESTAMP, "archive_gz::error called");
  return z_err;
}

void
archive_gz::destroy ()
{
  if (msg)
    free (msg);

  if (stream.state != NULL)
    {
      if (mode == 'w')
	{
	  z_err = deflateEnd (&(stream));
	}
      else if (mode == 'r')
	{
	  z_err = inflateEnd (&(stream));
	}
    }

  if (inbuf)
    free (inbuf);
  if (outbuf)
    free (outbuf);
  if (original)
    delete original;
}

archive_gz::~archive_gz ()
{
  log (LOG_TIMESTAMP, "archive_gz::~gz called");
  if (mode == 'w')
    {
      z_err = do_flush (Z_FINISH);
      if (z_err != Z_OK)
	{
	  destroy ();
	  return;
	}

      putLong (crc);
      putLong (stream.total_in);
    }
  destroy ();
 
  return;
}

int
archive_gz::do_flush (int flush)
{
  uInt len;
  int done = 0;

  if (mode != 'w')
    return Z_STREAM_ERROR;

  stream.avail_in = 0;		/* should be zero already anyway */

  for (;;)
    {
      len = 16384 - stream.avail_out;

      if (len != 0)
	{
	  if ((uInt) original->write (outbuf, len) != len)
	    {
	      z_err = Z_ERRNO;
	      return Z_ERRNO;
	    }
	  stream.next_out = outbuf;
	  stream.avail_out = 16384;
	}
      if (done)
	break;
      z_err = deflate (&(stream), flush);

      /* Ignore the second of two consecutive flushes: */
      if (len == 0 && z_err == Z_BUF_ERROR)
	z_err = Z_OK;

      /* deflate has finished flushing only when it hasn't used up
       * all the available space in the output buffer:
       */
      done = (stream.avail_out != 0 || z_err == Z_STREAM_END);

      if (z_err != Z_OK && z_err != Z_STREAM_END)
	break;
    }
  return z_err == Z_STREAM_END ? Z_OK : z_err;
}


#if 0

gzclose (lst);

#endif

/* ===========================================================================
 *  Read a byte from a gz_stream; update next_in and avail_in. Return EOF
 *  for end of file.
 *  IN assertion: the stream s has been sucessfully opened for reading.
 */
int
archive_gz::get_byte ()
{
  if (z_eof)
    return EOF;
  if (stream.avail_in == 0)
    {
      errno = 0;
      stream.avail_in = original->read (inbuf, 16384);
      if (stream.avail_in == 0)
	{
	  z_eof = 1;
	  if (original->error ())
	    z_err = Z_ERRNO;
	  return EOF;
	}
      stream.next_in = inbuf;
    }
  stream.avail_in--;
  return *(stream.next_in)++;
}


/* ===========================================================================
      Check the gzip header of a gz_stream opened for reading. Set the stream
    mode to transparent if the gzip magic header is not present; set s->err
    to Z_DATA_ERROR if the magic header is present but the rest of the header
    is incorrect.
    IN assertion: the stream s has already been created sucessfully;
       s->stream.avail_in is zero for the first time, but may be non-zero
       for concatenated .gz files.
*/
void
archive_gz::check_header ()
{
  int method;			/* method byte */
  int flags;			/* flags byte */
  uInt len;
  int c;

  /* Check the gzip magic header */
  for (len = 0; len < 2; len++)
    {
      c = get_byte ();
      if (c != gz_magic[len])
	{
	  if (len != 0)
	    stream.avail_in++, stream.next_in--;
	  if (c != EOF)
	    {
	      stream.avail_in++, stream.next_in--;
	      transparent = 1;
	    }
	  z_err = stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
	  return;
	}
    }
  method = get_byte ();
  flags = get_byte ();
  if (method != Z_DEFLATED || (flags & RESERVED) != 0)
    {
      z_err = Z_DATA_ERROR;
      return;
    }

  /* Discard time, xflags and OS code: */
  for (len = 0; len < 6; len++)
    (void) get_byte ();

  if ((flags & EXTRA_FIELD) != 0)
    {				/* skip the extra field */
      len = (uInt) get_byte ();
      len += ((uInt) get_byte ()) << 8;
      /* len is garbage if EOF but the loop below will quit anyway */
      while (len-- != 0 && get_byte () != EOF);
    }
  if ((flags & ORIG_NAME) != 0)
    {				/* skip the original file name */
      while ((c = get_byte ()) != 0 && c != EOF);
    }
  if ((flags & COMMENT) != 0)
    {				/* skip the .gz file comment */
      while ((c = get_byte ()) != 0 && c != EOF);
    }
  if ((flags & HEAD_CRC) != 0)
    {				/* skip the header crc */
      for (len = 0; len < 2; len++)
	(void) get_byte ();
    }
  z_err = z_eof ? Z_DATA_ERROR : Z_OK;
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _ARCHIVE_GZ_H_
#define _ARCHIVE_GZ_H_

/* this is the parent class for all archive IO operations. 
 * It 
 */

class archive_gz: public archive {
public:
  archive_gz (io_stream *);
  archive_gz (io_stream *, const char *);
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len);
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len);
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len);
  virtual long tell ();
  /* try guessing this one */
  virtual int error ();
  /* Find out the next stream name -
   * ie for foo.tar.gz, at offset 0, next_file_name = foo.tar
   * for foobar that is an archive, next_file_name is the next
   * extractable filename.
   */
  virtual const char* next_file_name() {return NULL;};
  /* if you are still needing these hints... give up now! */
  virtual ~archive_gz ();
private:
  archive_gz () {};
  void construct (io_stream *, const char *);
  void check_header ();
  int get_byte ();
  unsigned long getLong ();
  void putLong (unsigned long);
  void destroy ();
  int do_flush (int);
  io_stream *original;
  /* from zlib */
  z_stream stream;
  int      z_err;   /* error code for last stream operation */
  int      z_eof;   /* set if end of input file */
  unsigned char  *inbuf;  /* input buffer */
  unsigned char  *outbuf; /* output buffer */
  uLong    crc;     /* crc32 of uncompressed data */
  char     *msg;    /* error message */
  int      transparent; /* 1 if input file is not a .gz file */
  char     mode;    /* 'w' or 'r' */
  long     startpos; /* start of compressed data in file (header skipped) */
};

#endif /* _ARCHIVE_GZ_H_ */
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

/* this is the parent class for all IO operations. It's flexable enough to be cover for
 * HTTP access, local file access, and files being extracted from archives.
 * It also encapsulates the idea of an archive, and all non-archives become the special 
 * case.
 */

#if 0
static const char *cvsid = "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif

#include "win32.h"
#include <stdio.h>
#include "log.h"
#include "port.h"

#include "io_stream.h"
#include "io_stream_file.h"
#include "io_stream_cygfile.h"
#include "mkdir.h"

io_stream *
io_stream::factory (io_stream *parent)
{
  /* something like,  
   * if !next_file_name 
   *   return NULL
   * switch (magic_id(peek (parent), max_magic_length))
   * case io_stream * foo = new tar
   * case io_stream * foo = new bz2
   * return foo
   */
  log (LOG_TIMESTAMP, "io_stream::factory has been called");
  return NULL;
}

io_stream *
io_stream::open (const char *name, const char *mode)
{
  if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0] ||
      !mode || IsBadStringPtr (mode, 5) || !mode[0])
    return NULL;
  /* iterate through the known url prefix's */
  if (!strncasecmp("file://", name, 7))
    {
      io_stream_file *rv = new io_stream_file (&name[7], mode);
      if (!rv->error ())
	return rv;
      delete rv;
      return NULL;
    }
  if (!strncasecmp("cygfile://", name, 10))
    {
      io_stream_cygfile *rv = new io_stream_cygfile (&name[10], mode);
      if (!rv->error ())
	  return rv;
      delete rv;
      return NULL;
    }
  return NULL;
}

int
io_stream::mkpath_p (path_type_t isadir, const char *name)
{
  if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0])
    return 1;
  /* iterate through the known url prefix's */
  if (!strncasecmp("file://", name, 7))
    {
      return mkdir_p (isadir == PATH_TO_DIR ? 1:0, &name[7]);
    }
  if (!strncasecmp("cygfile://", name, 10))
    {
      return cygmkdir_p (isadir == PATH_TO_DIR ? 1:0, &name[10]);
    }
  return 1;
}

char *
io_stream::gets (char *buffer, size_t length)
{
  char *pos = buffer;
  size_t count = 0;
  while (count +1 < length && read (pos, 1) == 1)
    {
      count++;
      pos++;
      if (*(pos - 1) == '\n')
	{
	  /* end of line */
	  /* TODO: remove the \r if it is present depending on the 
	   * file's mode 
	   */
	  break;
	}
    }
  if (count == 0 || error ())
  /* EOF when no chars found, or an error */
    return NULL;
  *pos = '\0';
  return buffer;
}

io_stream::~io_stream ()
{
  log (LOG_TIMESTAMP, "io_stream::~io_stream called");
  return;
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _IO_STREAM_H_
#define _IO_STREAM_H_

/* this is the parent class for all IO operations. It's flexable enough to be cover for
 * HTTP access, local file access, and files being extracted from archives.
 * It also encapsulates the idea of an archive, and all non-archives become the special 
 * case.
 */

/* Some things don't fit cleanly just - TODO
 * make mkdir_p fit in the hierarchy
 */

//Where is this defined?
typedef signed long ssize_t;

#if __GNUC__
#define _ATTR_(foo) __attribute__ foo
#else
#define _ATTR_(foo)
#endif

typedef enum {
    PATH_TO_DIR,
    PATH_TO_FILE
} path_type_t;

class io_stream {
public:
  /* create a new stream from an existing one - used to get
   * decompressed data
   * or open archives.
   * will return NULL if there is no sub-stream available (ie (peek()
   * didn't match any known magic number) && nextfilename () = NULL
   */
  static io_stream * factory (io_stream *);
  /* open a stream by url. The particular stream type returned
   * will depend on the url passed.
   * ie for file:// it will be a disk file.
   * for ftp:// it will perform an upload to a ftp site.
   * the second parameter - mode can specify r|w && t|b. Other flags are not currently
   * supported.
   * Automatic decompression does not occur. Compressed files will return a io_stream
   * from archive::decompress. This behaviour is by design - to allow deliberate access
   * to the compressed data.
   * To create a stream that will be compressed, you should open the url, and then get a new stream
   * from archive::compress. 
   * If a stream is opened for reading, and it's an archive, the next_file_name method
   * will return non-NULL. To access the files within the archive use io_stream::factory
   * to create a new stream that will read from the archive.
   */
  static io_stream * open (const char *, const char *);
  /* ensure that we have access to the entire path */
  /* Create a directory, and any needed parent directories.
   * returns 1 on failure.
   */
  static int mkpath_p (path_type_t, const char *);
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len) = 0;
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len) = 0;
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len) = 0;
  /* ever read the f* functions from libc ? */
  virtual long tell () = 0;
  /* try guessing this one */
  virtual int error () = 0;
  /* hmm, yet another for the guessing books */
  virtual char *gets (char *, size_t len);
  /* Find out the next stream name -
   * ie for foo.tar.gz, at offset 0, next_file_name = foo.tar
   * for foobar that is an archive, next_file_name is the next
   * extractable filename.
   */
  virtual const char* next_file_name() = NULL;
  /* if you are still needing these hints... give up now! */
  virtual ~io_stream ();
};

#endif /* _IO_STREAM_H_ */
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#if 0
static const char *cvsid = "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif

#include "win32.h"
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
#include "port.h"
#include "mount.h"
#include "mkdir.h"

#include "io_stream.h"
#include "io_stream_cygfile.h"

static void
get_root_dir_now ()
{
  if (get_root_dir ())
    return;
  read_mounts ();
}

io_stream_cygfile::io_stream_cygfile (const char *name, const char *mode)
{
  fp = NULL;
  errno = 0;
  if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0] ||
      !mode || IsBadStringPtr (mode, 5) || !mode[0])
    return;

  /* do this every time because the mount points may change due to fwd/back button use...
   * TODO: make this less...manual
   */
  get_root_dir_now ();
  if (!get_root_dir ())
    /* TODO: assign a errno for "no mount table :} " */
    return;
  
  fp = fopen (cygpath (name, 0), mode);
  if (!fp)
    lasterr = errno;
}

io_stream_cygfile::~io_stream_cygfile ()
{
  if (fp)
    fclose (fp);
}

ssize_t
io_stream_cygfile::read (void *buffer, size_t len)
{
  if (fp)
    return fread (buffer, 1, len, fp);
  return 0;
}

ssize_t
io_stream_cygfile::write (void *buffer, size_t len)
{
  if (fp)
    return fwrite (buffer, 1, len, fp);
  return 0;
}

ssize_t
io_stream_cygfile::peek (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "io_stream_cygfile::peek called");
  if (fp)
    {
      int pos = ftell (fp);
      ssize_t rv = fread (buffer, 1, len, fp);
      fseek (fp, pos, SEEK_SET);
      return rv;
    }
  return 0;
}

long
io_stream_cygfile::tell ()
{ 
  if (fp)
    {
      return ftell (fp);
    }
  return 0;
}

int
io_stream_cygfile::error ()
{
  if (fp)
    return ferror (fp);
  return lasterr;
}

int
cygmkdir_p (int isadir, const char *name)
{
  if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0])
    return 1;
  get_root_dir_now ();
  if (!get_root_dir ())
    /* TODO: assign a errno for "no mount table :} " */
    return 1;
  return mkdir_p (isadir, cygpath (name, 0));
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _IO_STREAM_CYGFILE_H_
#define _IO_STREAM_CYGFILE_H_


/* io_stream on disk files using cygwin paths
 * and potentially understanding links in the future
 */

extern int cygmkdir_p (int isadir, const char *path);

class io_stream_cygfile : public io_stream {
public:
  io_stream_cygfile (const char *, const char *);
  ~io_stream_cygfile ();
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len);
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len);
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len);
  virtual long tell ();
  /* can't guess, oh well */
  virtual int error ();
  /* dummy for io_stream_file */
  virtual const char *next_file_name () {return NULL;};
private:
  /* always require parameters */
  io_stream_cygfile () {};
  FILE *fp;
  int lasterr;
};

#endif /* _IO_STREAM_CYGFILE_H_ */
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#if 0
static const char *cvsid = "\n%%% $Id: source.cc,v 2.5 2001/11/01 13:22:46 rbcollins Exp $\n";
#endif

#include "win32.h"
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
#include "port.h"

#include "io_stream.h"
#include "io_stream_file.h"

io_stream_file::io_stream_file (const char *name, const char *mode)
{
  fp = NULL;
  errno = 0;
  if (!name || IsBadStringPtr (name, MAX_PATH) || !name[0] ||
      !mode || IsBadStringPtr (mode, 5) || !mode[0])
    return;
  fp = fopen (name, mode);
  if (!fp)
    lasterr = errno;
}

io_stream_file::~io_stream_file ()
{
  if (fp)
      fclose (fp);
}

ssize_t
io_stream_file::read (void *buffer, size_t len)
{
  if (fp)
    return fread (buffer, 1, len, fp);
  return 0;
}

ssize_t
io_stream_file::write (void *buffer, size_t len)
{
  if (fp)
    return fwrite (buffer, 1, len, fp);
  return 0;
}

ssize_t
io_stream_file::peek (void *buffer, size_t len)
{
  log (LOG_TIMESTAMP, "io_stream_file::peek called");
  if (fp)
    {
      int pos = ftell (fp);
      ssize_t rv = fread (buffer, 1, len, fp);
      fseek (fp, pos, SEEK_SET);
      return rv;
    }
  return 0;
}

long
io_stream_file::tell ()
{
  if (fp)
    {
      return ftell (fp);
    }
  return 0;
}

int
io_stream_file::error ()
{
  if (fp)
    return ferror (fp);
  return lasterr;
}
/*
 * Copyright (c) 2001, Robert Collins.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Robert Collins  <rbtcollins@hotmail.com>
 *
 */

#ifndef _IO_STREAM_FILE_H_
#define _IO_STREAM_FILE_H_


/* io_stream on disk files
 */

class io_stream_file : public io_stream {
public:
  io_stream_file (const char *, const char *);
  ~io_stream_file ();
  /* read data (duh!) */
  virtual ssize_t read(void *buffer, size_t len);
  /* provide data to (double duh!) */
  virtual ssize_t write(void *buffer, size_t len);
  /* read data without removing it from the class's internal buffer */
  virtual ssize_t peek(void *buffer, size_t len);
  virtual long tell ();
  /* can't guess, oh well */
  virtual int error ();
  /* dummy for io_stream_file */
  virtual const char *next_file_name () {return NULL;};
private:
  /* always require parameters */
  io_stream_file () {};
  FILE *fp;
  int lasterr;
};

#endif /* _IO_STREAM_FILE_H_ */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]