aboutsummaryrefslogtreecommitdiff
path: root/sys/boot/libsa/bzipfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/libsa/bzipfs.c')
-rw-r--r--sys/boot/libsa/bzipfs.c388
1 files changed, 0 insertions, 388 deletions
diff --git a/sys/boot/libsa/bzipfs.c b/sys/boot/libsa/bzipfs.c
deleted file mode 100644
index ff1514efeed3..000000000000
--- a/sys/boot/libsa/bzipfs.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (c) 1998 Michael Smith.
- * Copyright (c) 2000 Maxim Sobolev
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifndef REGRESSION
-#include "stand.h"
-#else
-#include <stdlib.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-struct open_file {
- int f_flags; /* see F_* below */
- void *f_fsdata; /* file system specific data */
-};
-#define F_READ 0x0001 /* file opened for reading */
-#define EOFFSET (ELAST+8) /* relative seek not supported */
-static inline u_int min(u_int a, u_int b) { return(a < b ? a : b); }
-#define panic(x, y) abort()
-#endif
-
-#include <sys/stat.h>
-#include <string.h>
-#include <bzlib.h>
-
-#define BZ_BUFSIZE 2048 /* XXX larger? */
-
-struct bz_file
-{
- int bzf_rawfd;
- bz_stream bzf_bzstream;
- char bzf_buf[BZ_BUFSIZE];
- int bzf_endseen;
-};
-
-static int bzf_fill(struct bz_file *z);
-static int bzf_open(const char *path, struct open_file *f);
-static int bzf_close(struct open_file *f);
-static int bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid);
-static off_t bzf_seek(struct open_file *f, off_t offset, int where);
-static int bzf_stat(struct open_file *f, struct stat *sb);
-
-#ifndef REGRESSION
-struct fs_ops bzipfs_fsops = {
- "bzip",
- bzf_open,
- bzf_close,
- bzf_read,
- null_write,
- bzf_seek,
- bzf_stat,
- null_readdir
-};
-#endif
-
-static int
-bzf_fill(struct bz_file *bzf)
-{
- int result;
- int req;
-
- req = BZ_BUFSIZE - bzf->bzf_bzstream.avail_in;
- result = 0;
-
- /* If we need more */
- if (req > 0) {
- /* move old data to bottom of buffer */
- if (req < BZ_BUFSIZE)
- bcopy(bzf->bzf_buf + req, bzf->bzf_buf, BZ_BUFSIZE - req);
-
- /* read to fill buffer and update availibility data */
- result = read(bzf->bzf_rawfd, bzf->bzf_buf + bzf->bzf_bzstream.avail_in, req);
- bzf->bzf_bzstream.next_in = bzf->bzf_buf;
- if (result >= 0)
- bzf->bzf_bzstream.avail_in += result;
- }
- return(result);
-}
-
-/*
- * Adapted from get_byte/check_header in libz
- *
- * Returns 0 if the header is OK, nonzero if not.
- */
-static int
-get_byte(struct bz_file *bzf)
-{
- if ((bzf->bzf_bzstream.avail_in == 0) && (bzf_fill(bzf) == -1))
- return(-1);
- bzf->bzf_bzstream.avail_in--;
- return(*(bzf->bzf_bzstream.next_in)++);
-}
-
-static int bz_magic[3] = {'B', 'Z', 'h'}; /* bzip2 magic header */
-
-static int
-check_header(struct bz_file *bzf)
-{
- unsigned int len;
- int c;
-
- /* Check the bzip2 magic header */
- for (len = 0; len < 3; len++) {
- c = get_byte(bzf);
- if (c != bz_magic[len]) {
- return(1);
- }
- }
- /* Check that the block size is valid */
- c = get_byte(bzf);
- if (c < '1' || c > '9')
- return(1);
-
- /* Put back bytes that we've took from the input stream */
- bzf->bzf_bzstream.next_in -= 4;
- bzf->bzf_bzstream.avail_in += 4;
-
- return(0);
-}
-
-static int
-bzf_open(const char *fname, struct open_file *f)
-{
- static char *bzfname;
- int rawfd;
- struct bz_file *bzf;
- char *cp;
- int error;
- struct stat sb;
-
- /* Have to be in "just read it" mode */
- if (f->f_flags != F_READ)
- return(EPERM);
-
- /* If the name already ends in .gz or .bz2, ignore it */
- if ((cp = strrchr(fname, '.')) && (!strcmp(cp, ".gz")
- || !strcmp(cp, ".bz2") || !strcmp(cp, ".split")))
- return(ENOENT);
-
- /* Construct new name */
- bzfname = malloc(strlen(fname) + 5);
- if (bzfname == NULL)
- return(ENOMEM);
- sprintf(bzfname, "%s.bz2", fname);
-
- /* Try to open the compressed datafile */
- rawfd = open(bzfname, O_RDONLY);
- free(bzfname);
- if (rawfd == -1)
- return(ENOENT);
-
- if (fstat(rawfd, &sb) < 0) {
- printf("bzf_open: stat failed\n");
- close(rawfd);
- return(ENOENT);
- }
- if (!S_ISREG(sb.st_mode)) {
- printf("bzf_open: not a file\n");
- close(rawfd);
- return(EISDIR); /* best guess */
- }
-
- /* Allocate a bz_file structure, populate it */
- bzf = malloc(sizeof(struct bz_file));
- if (bzf == NULL)
- return(ENOMEM);
- bzero(bzf, sizeof(struct bz_file));
- bzf->bzf_rawfd = rawfd;
-
- /* Verify that the file is bzipped */
- if (check_header(bzf)) {
- close(bzf->bzf_rawfd);
- free(bzf);
- return(EFTYPE);
- }
-
- /* Initialise the inflation engine */
- if ((error = BZ2_bzDecompressInit(&(bzf->bzf_bzstream), 0, 1)) != BZ_OK) {
- printf("bzf_open: BZ2_bzDecompressInit returned %d\n", error);
- close(bzf->bzf_rawfd);
- free(bzf);
- return(EIO);
- }
-
- /* Looks OK, we'll take it */
- f->f_fsdata = bzf;
- return(0);
-}
-
-static int
-bzf_close(struct open_file *f)
-{
- struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
-
- BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
- close(bzf->bzf_rawfd);
- free(bzf);
- return(0);
-}
-
-static int
-bzf_read(struct open_file *f, void *buf, size_t size, size_t *resid)
-{
- struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
- int error;
-
- bzf->bzf_bzstream.next_out = buf; /* where and how much */
- bzf->bzf_bzstream.avail_out = size;
-
- while (bzf->bzf_bzstream.avail_out && bzf->bzf_endseen == 0) {
- if ((bzf->bzf_bzstream.avail_in == 0) && (bzf_fill(bzf) == -1)) {
- printf("bzf_read: fill error\n");
- return(EIO);
- }
- if (bzf->bzf_bzstream.avail_in == 0) { /* oops, unexpected EOF */
- printf("bzf_read: unexpected EOF\n");
- if (bzf->bzf_bzstream.avail_out == size)
- return(EIO);
- break;
- }
-
- error = BZ2_bzDecompress(&bzf->bzf_bzstream); /* decompression pass */
- if (error == BZ_STREAM_END) { /* EOF, all done */
- bzf->bzf_endseen = 1;
- break;
- }
- if (error != BZ_OK) { /* argh, decompression error */
- printf("bzf_read: BZ2_bzDecompress returned %d\n", error);
- return(EIO);
- }
- }
- if (resid != NULL)
- *resid = bzf->bzf_bzstream.avail_out;
- return(0);
-}
-
-static int
-bzf_rewind(struct open_file *f)
-{
- struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
- struct bz_file *bzf_tmp;
-
- /*
- * Since bzip2 does not have an equivalent inflateReset function a crude
- * one needs to be provided. The functions all called in such a way that
- * at any time an error occurs a roll back can be done (effectively making
- * this rewind 'atomic', either the reset occurs successfully or not at all,
- * with no 'undefined' state happening).
- */
-
- /* Allocate a bz_file structure, populate it */
- bzf_tmp = malloc(sizeof(struct bz_file));
- if (bzf_tmp == NULL)
- return(-1);
- bzero(bzf_tmp, sizeof(struct bz_file));
- bzf_tmp->bzf_rawfd = bzf->bzf_rawfd;
-
- /* Initialise the inflation engine */
- if (BZ2_bzDecompressInit(&(bzf_tmp->bzf_bzstream), 0, 1) != BZ_OK) {
- free(bzf_tmp);
- return(-1);
- }
-
- /* Seek back to the beginning of the file */
- if (lseek(bzf->bzf_rawfd, 0, SEEK_SET) == -1) {
- BZ2_bzDecompressEnd(&(bzf_tmp->bzf_bzstream));
- free(bzf_tmp);
- return(-1);
- }
-
- /* Free old bz_file data */
- BZ2_bzDecompressEnd(&(bzf->bzf_bzstream));
- free(bzf);
-
- /* Use the new bz_file data */
- f->f_fsdata = bzf_tmp;
-
- return(0);
-}
-
-static off_t
-bzf_seek(struct open_file *f, off_t offset, int where)
-{
- struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
- off_t target;
- char discard[16];
-
- switch (where) {
- case SEEK_SET:
- target = offset;
- break;
- case SEEK_CUR:
- target = offset + bzf->bzf_bzstream.total_out_lo32;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
-
- /* Can we get there from here? */
- if (target < bzf->bzf_bzstream.total_out_lo32 && bzf_rewind(f) != 0) {
- errno = EOFFSET;
- return -1;
- }
-
- /* if bzf_rewind was called then bzf has changed */
- bzf = (struct bz_file *)f->f_fsdata;
-
- /* skip forwards if required */
- while (target > bzf->bzf_bzstream.total_out_lo32) {
- errno = bzf_read(f, discard, min(sizeof(discard),
- target - bzf->bzf_bzstream.total_out_lo32), NULL);
- if (errno)
- return(-1);
- }
- /* This is where we are (be honest if we overshot) */
- return(bzf->bzf_bzstream.total_out_lo32);
-}
-
-static int
-bzf_stat(struct open_file *f, struct stat *sb)
-{
- struct bz_file *bzf = (struct bz_file *)f->f_fsdata;
- int result;
-
- /* stat as normal, but indicate that size is unknown */
- if ((result = fstat(bzf->bzf_rawfd, sb)) == 0)
- sb->st_size = -1;
- return(result);
-}
-
-void
-bz_internal_error(int errorcode)
-{
- panic("bzipfs: critical error %d in bzip2 library occured\n", errorcode);
-}
-
-#ifdef REGRESSION
-/* Small test case, open and decompress test.bz2 */
-int main()
-{
- struct open_file f;
- char buf[1024];
- size_t resid;
- int err;
-
- memset(&f, '\0', sizeof(f));
- f.f_flags = F_READ;
- err = bzf_open("test", &f);
- if (err != 0)
- exit(1);
- do {
- err = bzf_read(&f, buf, sizeof(buf), &resid);
- } while (err == 0 && resid != sizeof(buf));
-
- if (err != 0)
- exit(2);
- exit(0);
-}
-#endif