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

📄 sshzlib.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return 0;    tab = *ztab;    for (code = 0; code <= tab->mask; code++)	if (tab->table[code].nexttable != NULL)	    zlib_freetable(&tab->table[code].nexttable);    sfree(tab->table);    tab->table = NULL;    sfree(tab);    *ztab = NULL;    return (0);}struct zlib_decompress_ctx {    struct zlib_table *staticlentable, *staticdisttable;    struct zlib_table *currlentable, *currdisttable, *lenlentable;    enum {	START, OUTSIDEBLK,	TREES_HDR, TREES_LENLEN, TREES_LEN, TREES_LENREP,	INBLK, GOTLENSYM, GOTLEN, GOTDISTSYM,	UNCOMP_LEN, UNCOMP_NLEN, UNCOMP_DATA    } state;    int sym, hlit, hdist, hclen, lenptr, lenextrabits, lenaddon, len,	lenrep;    int uncomplen;    unsigned char lenlen[19];    unsigned char lengths[286 + 32];    unsigned long bits;    int nbits;    unsigned char window[WINSIZE];    int winpos;    unsigned char *outblk;    int outlen, outsize;};void *zlib_decompress_init(void){    struct zlib_decompress_ctx *dctx = snew(struct zlib_decompress_ctx);    unsigned char lengths[288];    memset(lengths, 8, 144);    memset(lengths + 144, 9, 256 - 144);    memset(lengths + 256, 7, 280 - 256);    memset(lengths + 280, 8, 288 - 280);    dctx->staticlentable = zlib_mktable(lengths, 288);    memset(lengths, 5, 32);    dctx->staticdisttable = zlib_mktable(lengths, 32);    dctx->state = START;		       /* even before header */    dctx->currlentable = dctx->currdisttable = dctx->lenlentable = NULL;    dctx->bits = 0;    dctx->nbits = 0;    dctx->winpos = 0;    return dctx;}void zlib_decompress_cleanup(void *handle){    struct zlib_decompress_ctx *dctx = (struct zlib_decompress_ctx *)handle;    if (dctx->currlentable && dctx->currlentable != dctx->staticlentable)	zlib_freetable(&dctx->currlentable);    if (dctx->currdisttable && dctx->currdisttable != dctx->staticdisttable)	zlib_freetable(&dctx->currdisttable);    if (dctx->lenlentable)	zlib_freetable(&dctx->lenlentable);    zlib_freetable(&dctx->staticlentable);    zlib_freetable(&dctx->staticdisttable);    sfree(dctx);}static int zlib_huflookup(unsigned long *bitsp, int *nbitsp,		   struct zlib_table *tab){    unsigned long bits = *bitsp;    int nbits = *nbitsp;    while (1) {	struct zlib_tableentry *ent;	ent = &tab->table[bits & tab->mask];	if (ent->nbits > nbits)	    return -1;		       /* not enough data */	bits >>= ent->nbits;	nbits -= ent->nbits;	if (ent->code == -1)	    tab = ent->nexttable;	else {	    *bitsp = bits;	    *nbitsp = nbits;	    return ent->code;	}	if (!tab) {	    /*	     * There was a missing entry in the table, presumably	     * due to an invalid Huffman table description, and the	     * subsequent data has attempted to use the missing	     * entry. Return a decoding failure.	     */	    return -2;	}    }}static void zlib_emit_char(struct zlib_decompress_ctx *dctx, int c){    dctx->window[dctx->winpos] = c;    dctx->winpos = (dctx->winpos + 1) & (WINSIZE - 1);    if (dctx->outlen >= dctx->outsize) {	dctx->outsize = dctx->outlen + 512;	dctx->outblk = sresize(dctx->outblk, dctx->outsize, unsigned char);    }    dctx->outblk[dctx->outlen++] = c;}#define EATBITS(n) ( dctx->nbits -= (n), dctx->bits >>= (n) )int zlib_decompress_block(void *handle, unsigned char *block, int len,			  unsigned char **outblock, int *outlen){    struct zlib_decompress_ctx *dctx = (struct zlib_decompress_ctx *)handle;    const coderecord *rec;    int code, blktype, rep, dist, nlen, header;    static const unsigned char lenlenmap[] = {	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15    };    dctx->outblk = snewn(256, unsigned char);    dctx->outsize = 256;    dctx->outlen = 0;    while (len > 0 || dctx->nbits > 0) {	while (dctx->nbits < 24 && len > 0) {	    dctx->bits |= (*block++) << dctx->nbits;	    dctx->nbits += 8;	    len--;	}	switch (dctx->state) {	  case START:	    /* Expect 16-bit zlib header. */	    if (dctx->nbits < 16)		goto finished;	       /* done all we can */            /*             * The header is stored as a big-endian 16-bit integer,             * in contrast to the general little-endian policy in             * the rest of the format :-(             */            header = (((dctx->bits & 0xFF00) >> 8) |                      ((dctx->bits & 0x00FF) << 8));            EATBITS(16);            /*             * Check the header:             *             *  - bits 8-11 should be 1000 (Deflate/RFC1951)             *  - bits 12-15 should be at most 0111 (window size)             *  - bit 5 should be zero (no dictionary present)             *  - we don't care about bits 6-7 (compression rate)             *  - bits 0-4 should be set up to make the whole thing             *    a multiple of 31 (checksum).             */            if ((header & 0x0F00) != 0x0800 ||                (header & 0xF000) >  0x7000 ||                (header & 0x0020) != 0x0000 ||                (header % 31) != 0)                goto decode_error;	    dctx->state = OUTSIDEBLK;	    break;	  case OUTSIDEBLK:	    /* Expect 3-bit block header. */	    if (dctx->nbits < 3)		goto finished;	       /* done all we can */	    EATBITS(1);	    blktype = dctx->bits & 3;	    EATBITS(2);	    if (blktype == 0) {		int to_eat = dctx->nbits & 7;		dctx->state = UNCOMP_LEN;		EATBITS(to_eat);       /* align to byte boundary */	    } else if (blktype == 1) {		dctx->currlentable = dctx->staticlentable;		dctx->currdisttable = dctx->staticdisttable;		dctx->state = INBLK;	    } else if (blktype == 2) {		dctx->state = TREES_HDR;	    }	    break;	  case TREES_HDR:	    /*	     * Dynamic block header. Five bits of HLIT, five of	     * HDIST, four of HCLEN.	     */	    if (dctx->nbits < 5 + 5 + 4)		goto finished;	       /* done all we can */	    dctx->hlit = 257 + (dctx->bits & 31);	    EATBITS(5);	    dctx->hdist = 1 + (dctx->bits & 31);	    EATBITS(5);	    dctx->hclen = 4 + (dctx->bits & 15);	    EATBITS(4);	    dctx->lenptr = 0;	    dctx->state = TREES_LENLEN;	    memset(dctx->lenlen, 0, sizeof(dctx->lenlen));	    break;	  case TREES_LENLEN:	    if (dctx->nbits < 3)		goto finished;	    while (dctx->lenptr < dctx->hclen && dctx->nbits >= 3) {		dctx->lenlen[lenlenmap[dctx->lenptr++]] =		    (unsigned char) (dctx->bits & 7);		EATBITS(3);	    }	    if (dctx->lenptr == dctx->hclen) {		dctx->lenlentable = zlib_mktable(dctx->lenlen, 19);		dctx->state = TREES_LEN;		dctx->lenptr = 0;	    }	    break;	  case TREES_LEN:	    if (dctx->lenptr >= dctx->hlit + dctx->hdist) {		dctx->currlentable = zlib_mktable(dctx->lengths, dctx->hlit);		dctx->currdisttable = zlib_mktable(dctx->lengths + dctx->hlit,						  dctx->hdist);		zlib_freetable(&dctx->lenlentable);		dctx->lenlentable = NULL;		dctx->state = INBLK;		break;	    }	    code =		zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->lenlentable);	    if (code == -1)		goto finished;	    if (code == -2)		goto decode_error;	    if (code < 16)		dctx->lengths[dctx->lenptr++] = code;	    else {		dctx->lenextrabits = (code == 16 ? 2 : code == 17 ? 3 : 7);		dctx->lenaddon = (code == 18 ? 11 : 3);		dctx->lenrep = (code == 16 && dctx->lenptr > 0 ?			       dctx->lengths[dctx->lenptr - 1] : 0);		dctx->state = TREES_LENREP;	    }	    break;	  case TREES_LENREP:	    if (dctx->nbits < dctx->lenextrabits)		goto finished;	    rep =		dctx->lenaddon +		(dctx->bits & ((1 << dctx->lenextrabits) - 1));	    EATBITS(dctx->lenextrabits);	    while (rep > 0 && dctx->lenptr < dctx->hlit + dctx->hdist) {		dctx->lengths[dctx->lenptr] = dctx->lenrep;		dctx->lenptr++;		rep--;	    }	    dctx->state = TREES_LEN;	    break;	  case INBLK:	    code =		zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->currlentable);	    if (code == -1)		goto finished;	    if (code == -2)		goto decode_error;	    if (code < 256)		zlib_emit_char(dctx, code);	    else if (code == 256) {		dctx->state = OUTSIDEBLK;		if (dctx->currlentable != dctx->staticlentable) {		    zlib_freetable(&dctx->currlentable);		    dctx->currlentable = NULL;		}		if (dctx->currdisttable != dctx->staticdisttable) {		    zlib_freetable(&dctx->currdisttable);		    dctx->currdisttable = NULL;		}	    } else if (code < 286) {   /* static tree can give >285; ignore */		dctx->state = GOTLENSYM;		dctx->sym = code;	    }	    break;	  case GOTLENSYM:	    rec = &lencodes[dctx->sym - 257];	    if (dctx->nbits < rec->extrabits)		goto finished;	    dctx->len =		rec->min + (dctx->bits & ((1 << rec->extrabits) - 1));	    EATBITS(rec->extrabits);	    dctx->state = GOTLEN;	    break;	  case GOTLEN:	    code =		zlib_huflookup(&dctx->bits, &dctx->nbits,			       dctx->currdisttable);	    if (code == -1)		goto finished;	    if (code == -2)		goto decode_error;	    dctx->state = GOTDISTSYM;	    dctx->sym = code;	    break;	  case GOTDISTSYM:	    rec = &distcodes[dctx->sym];	    if (dctx->nbits < rec->extrabits)		goto finished;	    dist = rec->min + (dctx->bits & ((1 << rec->extrabits) - 1));	    EATBITS(rec->extrabits);	    dctx->state = INBLK;	    while (dctx->len--)		zlib_emit_char(dctx, dctx->window[(dctx->winpos - dist) &						  (WINSIZE - 1)]);	    break;	  case UNCOMP_LEN:	    /*	     * Uncompressed block. We expect to see a 16-bit LEN.	     */	    if (dctx->nbits < 16)		goto finished;	    dctx->uncomplen = dctx->bits & 0xFFFF;	    EATBITS(16);	    dctx->state = UNCOMP_NLEN;	    break;	  case UNCOMP_NLEN:	    /*	     * Uncompressed block. We expect to see a 16-bit NLEN,	     * which should be the one's complement of the previous	     * LEN.	     */	    if (dctx->nbits < 16)		goto finished;	    nlen = dctx->bits & 0xFFFF;	    EATBITS(16);	    if (dctx->uncomplen == 0)		dctx->state = OUTSIDEBLK;	/* block is empty */	    else		dctx->state = UNCOMP_DATA;	    break;	  case UNCOMP_DATA:	    if (dctx->nbits < 8)		goto finished;	    zlib_emit_char(dctx, dctx->bits & 0xFF);	    EATBITS(8);	    if (--dctx->uncomplen == 0)		dctx->state = OUTSIDEBLK;	/* end of uncompressed block */	    break;	}    }  finished:    *outblock = dctx->outblk;    *outlen = dctx->outlen;    return 1;  decode_error:    sfree(dctx->outblk);    *outblock = dctx->outblk = NULL;    *outlen = 0;    return 0;}#ifdef ZLIB_STANDALONE#include <stdio.h>#include <string.h>int main(int argc, char **argv){    unsigned char buf[16], *outbuf;    int ret, outlen;    void *handle;    int noheader = FALSE, opts = TRUE;    char *filename = NULL;    FILE *fp;    while (--argc) {        char *p = *++argv;        if (p[0] == '-' && opts) {            if (!strcmp(p, "-d"))                noheader = TRUE;            else if (!strcmp(p, "--"))                opts = FALSE;          /* next thing is filename */            else {                fprintf(stderr, "unknown command line option '%s'\n", p);                return 1;            }        } else if (!filename) {            filename = p;        } else {            fprintf(stderr, "can only handle one filename\n");            return 1;        }    }    handle = zlib_decompress_init();    if (noheader) {        /*         * Provide missing zlib header if -d was specified.         */        zlib_decompress_block(handle, "\x78\x9C", 2, &outbuf, &outlen);        assert(outlen == 0);    }    if (filename)        fp = fopen(filename, "rb");    else        fp = stdin;    if (!fp) {        assert(filename);        fprintf(stderr, "unable to open '%s'\n", filename);        return 1;    }    while (1) {	ret = fread(buf, 1, sizeof(buf), fp);	if (ret <= 0)	    break;	zlib_decompress_block(handle, buf, ret, &outbuf, &outlen);        if (outbuf) {            if (outlen)                fwrite(outbuf, 1, outlen, stdout);            sfree(outbuf);        } else {            fprintf(stderr, "decoding error\n");            return 1;        }    }    zlib_decompress_cleanup(handle);    if (filename)        fclose(fp);    return 0;}#elseconst struct ssh_compress ssh_zlib = {    "zlib",    zlib_compress_init,    zlib_compress_cleanup,    zlib_compress_block,    zlib_decompress_init,    zlib_decompress_cleanup,    zlib_decompress_block,    zlib_disable_compression,    "zlib (RFC1950)"};#endif

⌨️ 快捷键说明

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