This is the mail archive of the
cygwin-patches@cygwin.com
mailing list for the Cygwin project.
compiler fixup patch for cinstall && mingw && w32api. (whew) (pt1)
- To: cygwin-patches at cygwin dot com
- Subject: compiler fixup patch for cinstall && mingw && w32api. (whew) (pt1)
- From: Robert Collins <robert dot collins at itdomain dot com dot au>
- Date: 06 Nov 2001 01:42:06 +1100
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_ */