diff options
author | 1997-02-06 02:56:44 +0000 | |
---|---|---|
committer | 1997-02-06 02:56:44 +0000 | |
commit | 35534e268462f799e199bb8580400b32bcbe70bd (patch) | |
tree | c6323386ff861415568d15888407ad945bb9c0e9 /sys/lib/libsa | |
parent | Enable support for gzip'd kernels. (diff) | |
download | wireguard-openbsd-35534e268462f799e199bb8580400b32bcbe70bd.tar.xz wireguard-openbsd-35534e268462f799e199bb8580400b32bcbe70bd.zip |
Add libz and make libsa aware of it. From NetBSD.
Diffstat (limited to 'sys/lib/libsa')
-rw-r--r-- | sys/lib/libsa/Makefile | 9 | ||||
-rw-r--r-- | sys/lib/libsa/close.c | 6 | ||||
-rw-r--r-- | sys/lib/libsa/cread.c | 409 | ||||
-rw-r--r-- | sys/lib/libsa/lseek.c | 6 | ||||
-rw-r--r-- | sys/lib/libsa/open.c | 6 | ||||
-rw-r--r-- | sys/lib/libsa/read.c | 6 | ||||
-rw-r--r-- | sys/lib/libsa/stand.h | 9 |
7 files changed, 445 insertions, 6 deletions
diff --git a/sys/lib/libsa/Makefile b/sys/lib/libsa/Makefile index 4165ff0a6c2..5ff86f98344 100644 --- a/sys/lib/libsa/Makefile +++ b/sys/lib/libsa/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.9 1996/12/08 15:15:44 niklas Exp $ +# $OpenBSD: Makefile,v 1.10 1997/02/06 02:56:44 downsj Exp $ # $NetBSD: Makefile,v 1.13 1996/10/02 16:19:51 ws Exp $ LIB= sa @@ -16,6 +16,10 @@ CFLAGS+=${XCFLAGS} -D_STANDALONE -DCOMPAT_UFS $(DEBUGFLAGS) -I${DIR} -I${DIR}/.. CFLAGS+=$(EXTRACFLAGS) CPPFLAGS+=${XCPPFLAGS} +.if defined(SA_ZLIB) +CPPFLAGS+= -D__INTERNAL_LIBSA_CREAD +.endif + .if ${MACHINE_ARCH}=="i386" .PATH: ${DIR}/../../arch/${MACHINE_ARCH}/stand .include "${DIR}/../../arch/${MACHINE_ARCH}/stand/Makefile.inc" @@ -28,6 +32,9 @@ SRCS+= alloc.c memcpy.c exit.c exec.c getfile.c gets.c globals.c \ # io routines SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c ioctl.c \ lseek.c open.c nullfs.c read.c stat.c fstat.c write.c +.if defined(SA_ZLIB) +SRCS+= cread.c +.endif .if !defined(NO_NET) # network routines diff --git a/sys/lib/libsa/close.c b/sys/lib/libsa/close.c index cf947d3333a..cc9876fa9c1 100644 --- a/sys/lib/libsa/close.c +++ b/sys/lib/libsa/close.c @@ -1,4 +1,4 @@ -/* $OpenBSD: close.c,v 1.4 1996/09/23 14:18:49 mickey Exp $ */ +/* $OpenBSD: close.c,v 1.5 1997/02/06 02:56:44 downsj Exp $ */ /* $NetBSD: close.c,v 1.5 1995/09/06 19:53:29 pk Exp $ */ /*- @@ -69,7 +69,11 @@ #include "saerrno.h" int +#ifndef __INTERNAL_LIBSA_CREAD close(fd) +#else +oclose(fd) +#endif int fd; { register struct open_file *f = &files[fd]; diff --git a/sys/lib/libsa/cread.c b/sys/lib/libsa/cread.c new file mode 100644 index 00000000000..3ec595014c0 --- /dev/null +++ b/sys/lib/libsa/cread.c @@ -0,0 +1,409 @@ +/* $OpenBSD: cread.c,v 1.1 1997/02/06 02:56:45 downsj Exp $ */ +/* $NetBSD: cread.c,v 1.2 1997/02/04 18:38:20 thorpej Exp $ */ + +/* + * Copyright (c) 1996 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project + * by Matthias Drochner. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* support for compressed bootfiles + (only read) + replaces open(), close(), read(), lseek(). + original libsa open(), close(), read(), lseek() are called + as oopen(), oclose(), oread() resp. olseek(). + compression parts stripped from zlib:gzio.c + */ + +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "stand.h" +#include "../libz/zlib.h" + +#define EOF (-1) /* needed by compression code */ + +#ifdef SAVE_MEMORY +#define Z_BUFSIZE 1024 +#else +#define Z_BUFSIZE 4096 +#endif + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#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 */ + +static struct sd { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + int fd; + unsigned char *inbuf; /* input buffer */ + unsigned long crc; /* crc32 of uncompressed data */ + int transparent; /* 1 if input file is not a .gz file */ +} *ss[SOPEN_MAX]; + +/* + * compression utilities + */ + +void *zcalloc (opaque, items, size) +void *opaque; +unsigned items; +unsigned size; +{ + return(alloc(items * size)); +} + +void zcfree (opaque, ptr) +void *opaque; +void *ptr; +{ + free(ptr, 0); /* XXX works only with modified allocator */ +} + +void zmemcpy(dest, source, len) +unsigned char *dest; +unsigned char *source; +unsigned int len; +{ + bcopy(source, dest, len); +} + +static int get_byte(s) + struct sd *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = oread(s->fd, s->inbuf, Z_BUFSIZE); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (errno) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +static unsigned long getLong (s) + struct sd *s; +{ + unsigned long x = (unsigned long)get_byte(s); + int c; + + x += ((unsigned long)get_byte(s))<<8; + x += ((unsigned long)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((unsigned long)c)<<24; + return x; +} + +static void check_header(s) + struct sd *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + unsigned int len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + s->transparent = 1; + if (c != EOF) s->stream.avail_in++, s->stream.next_in--; + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (unsigned int)get_byte(s); + len += ((unsigned int)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + +/* + * new open(), close(), read(), lseek() + */ + +int +open(fname, mode) + const char *fname; + int mode; +{ + int fd; + struct sd *s = 0; + + if(((fd = oopen(fname, mode)) == -1) + || (mode != 0)) /* compression only for read */ + return(fd); + + ss[fd] = s = alloc(sizeof(struct sd)); + if(!s) goto errout; + bzero(s, sizeof(struct sd)); + + if(inflateInit2(&(s->stream), -15) != Z_OK) + goto errout; + + s->stream.next_in = s->inbuf = (unsigned char*)alloc(Z_BUFSIZE); + if(!s->inbuf) { + inflateEnd(&(s->stream)); + goto errout; + } + + s->fd = fd; + check_header(s); /* skip the .gz header */ + return(fd); + +errout: + if(s) free(s, sizeof(struct sd)); + oclose(fd); + return(-1); +} + +int +close(fd) + int fd; +{ + struct open_file *f; + struct sd *s; + + if ((unsigned)fd >= SOPEN_MAX) { + errno = EBADF; + return (-1); + } + f = &files[fd]; + + if(!(f->f_flags & F_READ)) + return(oclose(fd)); + + s = ss[fd]; + + inflateEnd(&(s->stream)); + + free(s->inbuf, Z_BUFSIZE); + free(s, sizeof(struct sd)); + + return(oclose(fd)); +} + +ssize_t +read(fd, buf, len) + int fd; + void *buf; + size_t len; +{ + struct sd *s; + unsigned char *start = buf; /* starting point for crc computation */ + + s = ss[fd]; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + s->stream.next_out = buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + unsigned int n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + s->stream.next_out += n; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= oread(s->fd, s->stream.next_out, s->stream.avail_out); + } + return (int)(len - s->stream.avail_out); + } + + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = oread(fd, s->inbuf, Z_BUFSIZE); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (errno) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (unsigned int)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) { + s->z_err = Z_DATA_ERROR; + } else { + /* Check for concatenated .gz files: */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (unsigned int)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + +off_t +lseek(fd, offset, where) + int fd; + off_t offset; + int where; +{ + register struct open_file *f; + struct sd *s; + + if ((unsigned)fd >= SOPEN_MAX) { + errno = EBADF; + return (-1); + } + f = &files[fd];; + + if(!(f->f_flags & F_READ)) + return(olseek(fd, offset, where)); + + s = ss[fd]; + + if(s->transparent) { + off_t res = olseek(fd, offset, where); + if(res != (off_t)-1) { + /* make sure the lookahead buffer is invalid */ + s->stream.avail_in = 0; + } + return(res); + } + + switch(where) { + case SEEK_CUR: + offset += s->stream.total_out; + case SEEK_SET: + + /* if seek backwards, simply start from + the beginning */ + if(offset < s->stream.total_out) { + off_t res; + void *sav_inbuf; + + res = olseek(fd, 0, SEEK_SET); + if(res == (off_t)-1) + return(res); + /* ??? perhaps fallback to close / open */ + + inflateEnd(&(s->stream)); + + sav_inbuf = s->inbuf; /* don't allocate again */ + bzero(s, sizeof(struct sd)); /* this resets total_out to 0! */ + + inflateInit2(&(s->stream), -15); + s->stream.next_in = s->inbuf = sav_inbuf; + + s->fd = fd; + check_header(s); /* skip the .gz header */ + } + + /* to seek forwards, throw away data */ + if(offset > s->stream.total_out) { + off_t toskip = offset - s->stream.total_out; + + while(toskip > 0) { +#define DUMMYBUFSIZE 256 + char dummybuf[DUMMYBUFSIZE]; + off_t len = toskip; + if(len > DUMMYBUFSIZE) len = DUMMYBUFSIZE; + if(read(fd, dummybuf, len) != len) { + errno = EOFFSET; + return((off_t)-1); + } + toskip -= len; + } + } +#ifdef DEBUG + if(offset != s->stream.total_out) + panic("lseek compressed"); +#endif + return(offset); + case SEEK_END: + errno = EOFFSET; + break; + default: + errno = EINVAL; + } + return((off_t)-1); +} diff --git a/sys/lib/libsa/lseek.c b/sys/lib/libsa/lseek.c index 02f6443fd39..e15f1a534a7 100644 --- a/sys/lib/libsa/lseek.c +++ b/sys/lib/libsa/lseek.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lseek.c,v 1.3 1996/12/08 15:15:51 niklas Exp $ */ +/* $OpenBSD: lseek.c,v 1.4 1997/02/06 02:56:45 downsj Exp $ */ /* $NetBSD: lseek.c,v 1.3 1996/06/21 20:09:03 pk Exp $ */ /*- @@ -68,7 +68,11 @@ #include "stand.h" off_t +#ifndef __INTERNAL_LIBSA_CREAD lseek(fd, offset, where) +#else +olseek(fd, offset, where) +#endif int fd; off_t offset; int where; diff --git a/sys/lib/libsa/open.c b/sys/lib/libsa/open.c index 99cc9100ea6..f98f2a5f5ae 100644 --- a/sys/lib/libsa/open.c +++ b/sys/lib/libsa/open.c @@ -1,4 +1,4 @@ -/* $OpenBSD: open.c,v 1.5 1996/12/08 15:15:54 niklas Exp $ */ +/* $OpenBSD: open.c,v 1.6 1997/02/06 02:56:46 downsj Exp $ */ /* $NetBSD: open.c,v 1.12 1996/09/30 16:01:21 ws Exp $ */ /*- @@ -74,7 +74,11 @@ struct open_file files[SOPEN_MAX]; */ int +#ifndef __INTERNAL_LIBSA_CREAD open(fname, mode) +#else +oopen(fname, mode) +#endif const char *fname; int mode; { diff --git a/sys/lib/libsa/read.c b/sys/lib/libsa/read.c index c1612521101..3e85865d0a3 100644 --- a/sys/lib/libsa/read.c +++ b/sys/lib/libsa/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.3 1996/12/08 15:15:55 niklas Exp $ */ +/* $OpenBSD: read.c,v 1.4 1997/02/06 02:56:46 downsj Exp $ */ /* $NetBSD: read.c,v 1.7 1996/06/21 20:29:28 pk Exp $ */ /*- @@ -69,7 +69,11 @@ #include "stand.h" ssize_t +#ifndef __INTERNAL_LIBSA_CREAD read(fd, dest, bcount) +#else +oread(fd, dest, bcount) +#endif int fd; void *dest; size_t bcount; diff --git a/sys/lib/libsa/stand.h b/sys/lib/libsa/stand.h index 9952ef83bc2..d0e23609070 100644 --- a/sys/lib/libsa/stand.h +++ b/sys/lib/libsa/stand.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stand.h,v 1.17 1997/01/17 07:28:15 downsj Exp $ */ +/* $OpenBSD: stand.h,v 1.18 1997/02/06 02:56:47 downsj Exp $ */ /* $NetBSD: stand.h,v 1.18 1996/11/30 04:35:51 gwr Exp $ */ /*- @@ -188,6 +188,13 @@ int null_readdir __P((struct open_file *f, char *name)); void putchar __P((int)); int getchar __P((void)); +#ifdef __INTERNAL_LIBSA_CREAD +int oopen __P((const char *, int)); +int oclose __P((int)); +ssize_t oread __P((int, void *, size_t)); +off_t olseek __P((int, off_t, int)); +#endif + /* Machine dependent functions */ int devopen __P((struct open_file *, const char *, char **)); void machdep_exec __P((char *, int, char *, char *, char *)); |