朋友,你的代码里需要处理zip文件吗?你是不是也觉得直接调用unzip命令效率非常低吗?那还等什么?赶快拿起键盘,按下复制粘贴键搬运吧!!!
说明:代码只做示例之用,只能处理压缩包里只有一个文件的情况,直接读取第一个压缩文件的数据,调用解压算法进行解压,简单粗暴,如果想处理多个文件的压缩包,请自行查阅zip文件的中央目录的结构。解压算法直接从unzip源码里抠出来的,删除了所有条件编译,不同平台下可能会有不同的结果,目前只在centos6.5下测试通过,其他平台请参考unzip的源码,关于zip文件结构,请参考下面的连接
https://en.wikipedia.org/wiki/Zip_(file_format)
https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.2.0.txt
http://lib.yoekey.com/?p=236
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #ifndef O_BINARY # define O_BINARY 0 #endif typedef void zvoid; typedef unsigned char uch; /* code assumes unsigned bytes; these type- */ typedef unsigned short ush; /* defs replace byte/UWORD/ULONG (which are */ typedef unsigned long ulg; /* predefined on some systems) & match zip */ #define DUMPBITS(n) {b>>=(n);k-=(n);} #define MAXLITLENS 288 #define MAXDISTS 32 #define Trace(x) fprintf x #define ZCONST const #define UINT_D64 unsigned #define BMAX 16 /* maximum bit length of any code (16 for explode) */ #define N_MAX 288 /* maximum number of codes in any set */ #define INBUFSIZ 8192 #define WSIZE 65536L /* window size--must be a power of two, and */ #define wsize WSIZE /* wsize is a constant */ #define INVALID_CODE 99 #define IS_INVALID_CODE(c) ((c) == INVALID_CODE) # define memzero(dest,len) memset(dest,0,len) /* bits in base literal/length lookup table */ static ZCONST unsigned lbits = 9; /* bits in base distance lookup table */ static ZCONST unsigned dbits = 6; static ZCONST unsigned border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; /* - Copy lengths for literal codes 257..285 */ static ZCONST ush cplens64[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0 }; /* For Deflate64, the code 285 is defined differently. */ static ZCONST ush cplens32[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; /* note: see note #13 above about the 258 in this list. */ /* - Extra bits for literal codes 257..285 */ static ZCONST uch cplext64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, INVALID_CODE, INVALID_CODE }; static ZCONST uch cplext32[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, INVALID_CODE, INVALID_CODE }; /* - Extra bits for distance codes 0..29 (0..31 for Deflate64) */ static ZCONST uch cpdext64[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 }; static ZCONST uch cpdext32[] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, INVALID_CODE, INVALID_CODE }; static ZCONST ush cpdist[] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153 }; static ZCONST unsigned mask_bits[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; struct huft { uch e; /* number of extra bits or operation */ uch b; /* number of bits in this code or subcode */ union { ush n; /* literal, length base, or distance base */ struct huft *t; /* pointer to next level of table */ } v; }; static int bb = 0, bk = 0, wp = 0, incnt = 0; static ZCONST ush *cplens; static ZCONST uch *cplext; static ZCONST uch *cpdext; static struct huft *fixed_tl32; /* inflate static */ static struct huft *fixed_td32; /* inflate static */ static unsigned fixed_bl32, fixed_bd32; /* inflate static */ static struct huft *fixed_tl; static unsigned fixed_bl; static struct huft *fixed_td; static unsigned fixed_bd; static int blockno = 0; static unsigned char *inptr; static unsigned char *fileunbuff; static uch Slide[WSIZE]; #define NEXTBYTE (incnt-- > 0 ? (int)(*inptr++) : 0) #define NEEDBITS(n) {while((int)k<(int)(n)){int c=(incnt-- > 0 ? (int)(*inptr++) : 0);\ if(c==EOF){if((int)k>=0)break;retval=1;goto cleanup_and_exit;}\ b|=((ulg)c)<<k;k+=8;}} static int huft_free(struct huft *t)/* table to free */ { register struct huft *p, *q; /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != (struct huft *)NULL) { q = (--p)->v.t; free((zvoid *)p); p = q; } return 0; } static int huft_build( ZCONST unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ unsigned n, /* number of codes (assumed <= N_MAX) */ unsigned s, /* number of simple-valued codes (0..s-1) */ ZCONST ush *d, /* list of base values for non-simple codes */ ZCONST uch *e, /* list of extra bits for non-simple codes */ struct huft **t, /* result: starting table */ unsigned *m /* maximum lookup bits, returns actual */ ) { unsigned a; /* counter for codes of length k */ unsigned c[BMAX + 1]; /* bit length count table */ unsigned el; /* length of EOB code (value 256) */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register unsigned i; /* counter, current code */ register unsigned j; /* counter */ register int k; /* number of bits in current code */ int lx[BMAX + 1]; /* memory for l[-1..BMAX-1] */ int *l = lx + 1; /* stack of bits per table */ register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned x[BMAX + 1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ /* Generate counts for each bit length */ el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */ memzero((char *)c, sizeof(c)); p = (unsigned *)b; i = n; do { c[*p]++; p++; /* assume all entries <= BMAX */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (struct huft *)NULL; *m = 0; return 0; } /* Find minimum and maximum length, bound *m by those */ for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if (*m < j) *m = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if (*m > i) *m = i; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return 2; /* bad input: more codes than bits */ if ((y -= c[i]) < 0) return 2; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ memzero((char *)v, sizeof(v)); p = (unsigned *)b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); n = x[g]; /* set n to length of v */ /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = l[-1] = 0; /* no bits decoded yet */ u[0] = (struct huft *)NULL; /* just to keep compilers happy */ q = (struct huft *)NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l[h]) { w += l[h++]; /* add bits already decoded */ /* compute minimum size table less than or equal to *m bits */ z = (z = g - w) > *m ? *m : z; /* upper limit */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } if ((unsigned)w + j > el && (unsigned)w < el) j = el - w; /* make EOB code end at table */ z = 1 << j; /* table entries for j-bit table */ l[h] = j; /* set table size in stack */ /* allocate and link in new table */ if ((q = (struct huft *)malloc((z + 1) * sizeof(struct huft))) == (struct huft *)NULL) { if (h) huft_free(u[0]); return 3; /* not enough memory */ } *t = q + 1; /* link to list for huft_free() */ *(t = &(q->v.t)) = (struct huft *)NULL; u[h] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.b = (uch)l[h - 1]; /* bits to dump before this table */ r.e = (uch)(32 + j); /* bits in this table */ r.v.t = q; /* pointer to this table */ j = (i & ((1 << w) - 1)) >> (w - l[h - 1]); u[h - 1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.b = (uch)(k - w); if (p >= v + n) r.e = INVALID_CODE; /* out of values--invalid code */ else if (*p < s) { r.e = (uch)(*p < 256 ? 32 : 31); /* 256 is end-of-block code */ r.v.n = (ush)*p++; /* simple code is just the value */ } else { r.e = e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) w -= l[--h]; /* don't need to update q */ } } /* return actual size of base table */ *m = l[0]; /* Return true (1) if we were given an incomplete table */ return y != 0 && g != 1; } static int inflate_codes(struct huft *tl, struct huft *td, unsigned bl, unsigned bd) { register unsigned e; /* table entry flag/number of extra bits */ unsigned d; /* index for copy */ UINT_D64 n; /* length for copy (deflate64: might be 64k+2) */ UINT_D64 w; /* current window position (deflate64: up to 64k) */ struct huft *t; /* pointer to table entry */ unsigned ml, md; /* masks for bl and bd bits */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ int retval = 0; /* error code returned: initialized to "no error" */ /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd]; while (1) /* do until end of block */ { // NEEDBITS(bl) {while ((int)k < (int)(bl)) { int c = (incnt-- > 0 ? (int)(*inptr++) : 0); \ if (c == EOF) { if ((int)k >= 0)break; retval = 1; goto cleanup_and_exit; }\ b |= ((ulg)c) << k; k += 8; }} t = tl + ((unsigned)b & ml); while (1) { DUMPBITS(t->b) if ((e = t->e) == 32) /* then it's a literal */ { Slide[w++] = (uch)t->v.n; if (w == wsize) { memcpy(fileunbuff + blockno++ * sizeof(Slide), Slide, sizeof(Slide)); w = 0; } break; } if (e < 31) /* then it's a length */ { /* get length of block to copy */ NEEDBITS(e) n = t->v.n + ((unsigned)b & mask_bits[e]); DUMPBITS(e) /* decode distance of block to copy */ NEEDBITS(bd) t = td + ((unsigned)b & md); while (1) { DUMPBITS(t->b) if ((e = t->e) < 32) break; if (IS_INVALID_CODE(e)) return 1; e &= 31; NEEDBITS(e) t = t->v.t + ((unsigned)b & mask_bits[e]); } NEEDBITS(e) d = (unsigned)w - t->v.n - ((unsigned)b & mask_bits[e]); DUMPBITS(e) /* do the copy */ do { e = (unsigned)(wsize - ((d &= (unsigned)(wsize - 1)) > (unsigned)w ? (UINT_D64)d : w)); if ((UINT_D64)e > n) e = (unsigned)n; n -= e; if ((unsigned)w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(Slide + (unsigned)w, Slide + d, e); w += e; d += e; } else /* do it slowly to avoid memcpy() overlap */ do { Slide[w++] = Slide[d++];; if (e == 228) { int a = 0; a = 4; } } while (--e); if (w == wsize) { memcpy(fileunbuff + blockno++ * sizeof(Slide), Slide, sizeof(Slide)); w = 0; } } while (n); break; } if (e == 31) /* it's the EOB signal */ { /* sorry for this goto, but we have to exit two loops at once */ goto cleanup_decode; } if (IS_INVALID_CODE(e)) return 1; e &= 31; NEEDBITS(e) t = t->v.t + ((unsigned)b & mask_bits[e]); } } int aaa = 0; cleanup_decode: /* restore the globals from the locals */ wp = (unsigned)w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; cleanup_and_exit: /* done */ return retval; } static int inflate_dynamic() /* decompress an inflated type 2 (dynamic Huffman codes) block. */ { unsigned i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ unsigned bl; /* lookup bits for tl */ unsigned bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ unsigned ll[MAXLITLENS + MAXDISTS]; /* lit./length and distance code lengths */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ int retval = 0; /* error code returned: initialized to "no error" */ /* make local bit buffer */ b = bb; k = bk; /* read in table lengths */ NEEDBITS(5) nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ DUMPBITS(5) NEEDBITS(5) nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ DUMPBITS(5) NEEDBITS(4) nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ DUMPBITS(4) if (nl > MAXLITLENS || nd > MAXDISTS) return 1; /* bad lengths */ /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { NEEDBITS(3) ll[border[j]] = (unsigned)b & 7; DUMPBITS(3) } for (; j < 19; j++) ll[border[j]] = 0; /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; retval = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl); if (bl == 0) /* no bit lengths */ retval = 1; if (retval) { if (retval == 1) huft_free(tl); return retval; /* incomplete code set */ } /* read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while (i < n) { NEEDBITS(bl) j = (td = tl + ((unsigned)b & m))->b; DUMPBITS(j) j = td->v.n; if (j < 16) /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } } /* free decoding table for trees */ huft_free(tl); /* restore the global bit buffer */ bb = b; bk = k; /* build the decoding tables for literal/length and distance codes */ bl = lbits; retval = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl); if (bl == 0) /* no literals or lengths */ retval = 1; if (retval) { if (retval == 1) { huft_free(tl); } return retval; /* incomplete code set */ } bd = dbits; retval = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd); if (retval == 1) retval = 0; if (bd == 0 && nl > 257) /* lengths but no distances */ retval = 1; if (retval) { if (retval == 1) { huft_free(td); } huft_free(tl); return retval; } /* decompress until an end-of-block code */ retval = inflate_codes(tl, td, bl, bd); cleanup_and_exit: /* free the decoding tables, return */ huft_free(tl); huft_free(td); return retval; } static int inflate_stored() { UINT_D64 w; /* current window position (deflate64: up to 64k!) */ unsigned n; /* number of bytes in block */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ int retval = 0; /* error code returned: initialized to "no error" */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* go to byte boundary */ n = k & 7; DUMPBITS(n); /* get the length and its complement */ NEEDBITS(16) n = ((unsigned)b & 0xffff); DUMPBITS(16) NEEDBITS(16) if (n != (unsigned)((~b) & 0xffff)) return 1; /* error in compressed data */ DUMPBITS(16) /* read and output the compressed data */ while (n--) { NEEDBITS(8) Slide[w++] = (uch)b; if (w == wsize) { memcpy(fileunbuff + blockno++ * sizeof(Slide), Slide, sizeof(Slide)); w = 0; } DUMPBITS(8) } /* restore the globals from the locals */ wp = (unsigned)w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; cleanup_and_exit: return retval; } static int inflate_fixed() { if (fixed_tl == (struct huft *)NULL) { int i; /* temporary variable */ unsigned l[288]; /* length list for huft_build */ /* literal table */ for (i = 0; i < 144; i++) l[i] = 8; for (; i < 256; i++) l[i] = 9; for (; i < 280; i++) l[i] = 7; for (; i < 288; i++) /* make a complete, but wrong code set */ l[i] = 8; fixed_bl = 7; if ((i = huft_build(l, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl)) != 0) { fixed_tl = (struct huft *)NULL; return i; } /* distance table */ for (i = 0; i < MAXDISTS; i++) /* make an incomplete code set */ l[i] = 5; fixed_bd = 5; if ((i = huft_build(l, MAXDISTS, 0, cpdist, cpdext, &fixed_td, &fixed_bd)) > 1) { huft_free(fixed_tl); fixed_td = fixed_tl = (struct huft *)NULL; return i; } } /* decompress until an end-of-block code */ return inflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd); } static int inflate_block(int *e) { unsigned t; /* block type */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ int retval = 0; /* error code returned: initialized to "no error" */ /* make local bit buffer */ b = bb; k = bk; /* read in last block bit */ NEEDBITS(1) *e = (int)b & 1; DUMPBITS(1) /* read in block type */ NEEDBITS(2) t = (unsigned)b & 3; DUMPBITS(2) /* restore the global bit buffer */ bb = b; bk = k; /* inflate that block type */ if (t == 2) return inflate_dynamic(); if (t == 0) return inflate_stored(); if (t == 1) return inflate_fixed(); /* bad block type */ retval = 2; cleanup_and_exit: return retval; } int main(int argc, char **argv) { char *zipfilename; int zipfilefd; int zipfilelen; unsigned char *zipfilebuff; struct stat stat_zipfile; ssize_t readret, writeret; int filezipsize = 0; int fileunzipsize = 0; int filenamelen = 0; int fileextralen = 0; char *filename; char *filebuff; memset(&stat_zipfile, 0, sizeof(stat_zipfile)); zipfilename = "/home/zhangn/work/myunzip/bin/x64/Debug/1.zip"; stat(zipfilename, &(stat_zipfile)); zipfilelen = stat_zipfile.st_size; zipfilebuff = malloc(zipfilelen); if (!zipfilebuff) return 1; memset(zipfilebuff, 0, zipfilelen); zipfilefd = open(zipfilename, O_RDONLY | O_BINARY); while (readret = read(zipfilefd, zipfilebuff, zipfilelen)) { if (readret < 0) break; } close(zipfilefd); memcpy(&filezipsize, zipfilebuff + 18, 4); memcpy(&fileunzipsize, zipfilebuff + 22, 4); memcpy(&filenamelen, zipfilebuff + 26, 2); memcpy(&fileextralen, zipfilebuff + 28, 2); filename = malloc(filenamelen); filebuff = malloc(filezipsize); fileunbuff = malloc(fileunzipsize); if (!filename || !filebuff || !fileunzipsize) return -1; incnt = filezipsize; inptr = filebuff; memset(filename, 0, filenamelen); memset(filebuff, 0, filezipsize); memset(fileunbuff, 0, fileunzipsize); memcpy(filename, zipfilebuff + 30, filenamelen); memcpy(filebuff, zipfilebuff + 30 + filenamelen + fileextralen, filezipsize); free(zipfilebuff); zipfilebuff = NULL; cplens = cplens32; cplext = cplext32; cpdext = cpdext32; fixed_tl = fixed_tl32; fixed_bl = fixed_bl32; fixed_td = fixed_td32; fixed_bd = fixed_bd32; int r = 0, e = 0; int blockcount = fileunzipsize / wsize + 1; do { if ((r = inflate_block(&e)) != 0) return r; } while (!e); fixed_tl32 = fixed_tl; fixed_bl32 = fixed_bl; fixed_td32 = fixed_td; fixed_bd32 = fixed_bd; memcpy(fileunbuff + blockno * sizeof(Slide), Slide, wp); int outfile = open("/home/zhangn/work/myunzip/bin/x64/Debug/1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (outfile < 0) { r = -1; goto END; } int pos = 0; writeret = 0; while (1) { writeret = write(outfile, fileunbuff + pos, (fileunzipsize - pos > 1024 ? 1024 : fileunzipsize - pos)); pos += writeret; if (writeret < 0) break; if (pos == fileunzipsize) break; } close(outfile); END: free(filename); free(filebuff); free(fileunbuff); inptr = NULL; filename = NULL; filebuff = NULL; fileunbuff = NULL; return r; }