⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unzip.c

📁 Windows上的精简Linux系统
💻 C
字号:
/* * unzip.c *  * This is a collection of several routines from gzip-1.0.3  * adapted for Linux. * * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 * puts by Nick Holloway 1993, better puts by Martin Mares 1995 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 * * Adapted for MEMDISK by H. Peter Anvin, April 2003 */#include <stdint.h>#include "memdisk.h"#include "conio.h"/* * gzip declarations */#define OF(args)  args#define STATIC static#define memzero(s, n)     memset ((s), 0, (n))typedef uint8_t  uch;typedef uint16_t ush;typedef uint32_t ulg;#define WSIZE 0x8000	        /* Window size must be at least 32k, */				/* and a power of two */static uch *inbuf;		/* input pointer */static uch window[WSIZE];	/* sliding output window buffer */static unsigned insize;		/* total input bytes read */static unsigned inbytes;	/* valid bytes in inbuf */static unsigned outcnt;		/* bytes in output buffer *//* gzip flag byte */#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */#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 ENCRYPTED    0x20 /* bit 5 set: file is encrypted */#define RESERVED     0xC0 /* bit 6,7:   reserved *//* Diagnostic functions */#ifdef DEBUG#  define Assert(cond,msg) {if(!(cond)) error(msg);}#  define Trace(x) fprintf x#  define Tracev(x) {if (verbose) fprintf x ;}#  define Tracevv(x) {if (verbose>1) fprintf x ;}#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}#else#  define Assert(cond,msg)#  define Trace(x)#  define Tracev(x)#  define Tracevv(x)#  define Tracec(c,x)#  define Tracecv(c,x)#endifstatic int  fill_inbuf(void);static void flush_window(void);static void error(char *m);static void gzip_mark(void **);static void gzip_release(void **);extern ulg crc_32_tab[256];/* Get byte from input buffer */static inline uch get_byte(void){  if ( inbytes ) {    uch b = *inbuf++;    inbytes--;    return b;  } else {    return fill_inbuf();	/* Input buffer underrun */  }}/* Unget byte from input buffer */static inline void unget_byte(void){  inbytes++;  inbuf--;}static ulg bytes_out = 0;	/* Number of bytes output */static uch *output_data;	/* Output data pointer */static ulg output_size;		/* Number of output bytes expected */static void *malloc(int size);static void free(void *where);static ulg free_mem_ptr, free_mem_end_ptr;#include "inflate.c"static void *malloc(int size){  void *p;    if (size < 0) error("malloc error");    free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */    p = (void *)free_mem_ptr;  free_mem_ptr += size;    if (free_mem_ptr >= free_mem_end_ptr)    error("out of memory");    return p;}static void free(void *where){  /* Don't care */}static void gzip_mark(void **ptr){  *ptr = (void *) free_mem_ptr;}static void gzip_release(void **ptr){  free_mem_ptr = (long) *ptr;} /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty * and at least one byte is really needed. */static int fill_inbuf(void){  /* This should never happen.  We have already pointed the algorithm     to all the data we have. */  printf("failed\nDecompression error: ran out of input data\n");  die();}/* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */static void flush_window(void){    ulg c = crc;         /* temporary variable */    unsigned n;    uch *in, *out, ch;    if ( bytes_out+outcnt > output_size )      error("output buffer overrun");        in = window;    out = output_data;    for (n = 0; n < outcnt; n++) {	    ch = *out++ = *in++;	    c = crc_32_tab[(c ^ ch) & 0xff] ^ (c >> 8);    }    crc = c;    output_data = out;    bytes_out += (ulg)outcnt;    outcnt = 0;}static void error(char *x){  printf("failed\nDecompression error: %s\n", x);  die();}/* GZIP header */struct gzip_header {  uint16_t magic;  uint8_t method;  uint8_t flags;  uint32_t timestamp;  uint8_t extra_flags;  uint8_t os_type;} __attribute__ ((packed));/* (followed by optional and variable length "extra", "original name",   and "comment" fields) */struct gzip_trailer {  uint32_t crc;  uint32_t dbytes;} __attribute__ ((packed));/* PKZIP header.  See * <http://www.pkware.com/products/enterprise/white_papers/appnote.html>. */struct pkzip_header {  uint32_t magic;  uint16_t version;  uint16_t flags;  uint16_t method;  uint16_t modified_time;  uint16_t modified_date;  uint32_t crc;  uint32_t zbytes;  uint32_t dbytes;  uint16_t filename_len;  uint16_t extra_len;} __attribute__ ((packed));/* (followed by optional and variable length "filename" and "extra"   fields) *//* gzip flag byte */#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */#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 ENCRYPTED    0x20 /* bit 5 set: file is encrypted */#define RESERVED     0xC0 /* bit 6,7:   reserved *//* pkzip flag byte */#define PK_ENCRYPTED     0x01  /* bit 0 set: file is encrypted */#define PK_DATADESC       0x08  /* bit 3 set: file has trailing "data                                   descriptor" */#define PK_UNSUPPORTED    0xFFF0 /* All other bits must be zero *//* Return 0 if (indata, size) points to a ZIP file, and fill in   compressed data size, uncompressed data size, CRC, and offset of   data.   If indata is not a ZIP file, return -1. */int check_zip(void *indata, uint32_t size, uint32_t *zbytes_p,              uint32_t *dbytes_p, uint32_t *orig_crc, uint32_t *offset_p) {  struct gzip_header *gzh = (struct gzip_header *)indata;  struct pkzip_header *pkzh = (struct pkzip_header *)indata;  uint32_t offset;  if (gzh->magic == 0x8b1f) {    struct gzip_trailer *gzt = indata + size - sizeof (struct gzip_trailer);    /* We only support method #8, DEFLATED */    if (gzh->method != 8)  {      error("gzip file uses invalid method");      return -1;    }    if (gzh->flags & ENCRYPTED) {      error("gzip file is encrypted; not supported");      return -1;    }    if (gzh->flags & CONTINUATION) {      error("gzip file is a continuation file; not supported");      return -1;    }    if (gzh->flags & RESERVED) {      error("gzip file has unsupported flags");      return -1;    }    offset = sizeof (*gzh);    if (gzh->flags & EXTRA_FIELD) {      /* Skip extra field */      unsigned len = *(unsigned *)(indata + offset);      offset += 2 + len;    }    if (gzh->flags & ORIG_NAME) {      /* Discard the old name */      uint8_t *p = indata;      while (p[offset] != 0 && offset < size) {        offset++;      }      offset++;    }        if (gzh->flags & COMMENT) {      /* Discard the comment */      uint8_t *p = indata;      while (p[offset] != 0 && offset < size) {        offset++;      }      offset++;    }    if (offset > size) {      error ("gzip file corrupt");      return -1;    }    *zbytes_p = size - offset - sizeof (struct gzip_trailer);    *dbytes_p = gzt->dbytes;    *orig_crc = gzt->crc;    *offset_p = offset;    return 0;  }  else if (pkzh->magic == 0x04034b50UL) {    /* Magic number matches pkzip file. */        offset = sizeof (*pkzh);    if (pkzh->flags & PK_ENCRYPTED) {      error("pkzip file is encrypted; not supported");      return -1;    }    if (pkzh->flags & PK_DATADESC) {      error("pkzip file uses data_descriptor field; not supported");      return -1;    }    if (pkzh->flags & PK_UNSUPPORTED) {      error("pkzip file has unsupported flags");      return -1;    }    /* We only support method #8, DEFLATED */    if (pkzh->method != 8) {      error("pkzip file uses invalid method");      return -1;    }    /* skip header */    offset = sizeof (*pkzh);    /* skip filename */    offset += pkzh->filename_len;    /* skip extra field */    offset += pkzh->extra_len;    if (offset + pkzh->zbytes > size) {      error ("pkzip file corrupt");      return -1;    }    *zbytes_p = pkzh->zbytes;    *dbytes_p = pkzh->dbytes;    *orig_crc = pkzh->crc;    *offset_p = offset;    return 0;  }  else {    /* Magic number does not match. */    return -1;  }  error ("Internal error in check_zip");  return -1;}/* * Decompress the image, trying to flush the end of it as close * to end_mem as possible.  Return a pointer to the data block, * and change datalen. */extern void _end;void *unzip(void *indata, uint32_t zbytes, uint32_t dbytes,            uint32_t orig_crc, void *target){  /* Set up the heap; it's the 64K after the bounce buffer */  free_mem_ptr = (ulg)sys_bounce + 0x10000;  free_mem_end_ptr = free_mem_ptr + 0x10000;  /* Set up input buffer */  inbuf  = indata;  /* Sometimes inflate() looks beyond the end of the compressed data,     but it always backs up before it is done.  So we give it 4 bytes     of slack. */  insize = inbytes = zbytes + 4;  /* Set up output buffer */  outcnt = 0;  output_data = target;  output_size = dbytes;  bytes_out = 0;  makecrc();  gunzip();  /* Verify that gunzip() consumed the entire input. */  if (inbytes != 4)    error("compressed data length error");  /* Check the uncompressed data length and CRC. */  if ( bytes_out != dbytes )    error("uncompressed data length error");  if (orig_crc != CRC_VALUE)    error("crc error");  puts("ok\n");  return target;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -