diff -urN xar/lib/archive.c xar.context/lib/archive.c --- xar/lib/archive.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/archive.c 2006-03-17 11:24:36.000000000 -0800 @@ -64,6 +64,13 @@ #define O_SHLOCK 0 #endif +#ifndef LONG_MAX +#define LONG_MAX INT32_MAX +#endif +#ifndef LONG_MIN +#define LONG_MIN INT32_MIN +#endif + static int32_t xar_unserialize(xar_t x); void xar_serialize(xar_t x, const char *file); diff -urN xar/lib/bzxar.c xar.context/lib/bzxar.c --- xar/lib/bzxar.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/bzxar.c 2006-03-17 10:57:14.000000000 -0800 @@ -47,13 +47,12 @@ #include "io.h" #ifdef HAVE_LIBBZ2 -static int initted = 0; -static bz_stream zs; +#define BZIP2_CONTEXT(x) ((bz_stream *)(*x)) #endif -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr); +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context); -int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { #ifdef HAVE_LIBBZ2 const char *opt; void *out = NULL; @@ -67,31 +66,27 @@ if( !opt ) return 0; if( strcmp(opt, "application/x-bzip2") != 0 ) return 0; - if( !initted ) { - zs.bzalloc = NULL; - zs.bzfree = NULL; - zs.opaque = NULL; - - BZ2_bzDecompressInit(&zs, 0, 0); - initted = 1; + if( !BZIP2_CONTEXT(context) ) { + *context = calloc(1,sizeof(bz_stream)); + BZ2_bzDecompressInit(BZIP2_CONTEXT(context), 0, 0); } outlen = *inlen; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + BZIP2_CONTEXT(context)->next_in = *in; + BZIP2_CONTEXT(context)->avail_in = *inlen; + BZIP2_CONTEXT(context)->next_out = out; + BZIP2_CONTEXT(context)->avail_out = 0; - while( zs.avail_in != 0 ) { + while( BZIP2_CONTEXT(context)->avail_in != 0 ) { outlen = outlen * 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + BZIP2_CONTEXT(context)->next_out = out + offset; + BZIP2_CONTEXT(context)->avail_out = outlen - offset; - r = BZ2_bzDecompress(&zs); + r = BZ2_bzDecompress(BZIP2_CONTEXT(context)); if( (r != BZ_OK) && (r != BZ_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); @@ -99,10 +94,10 @@ xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } - offset += outlen - offset - zs.avail_out; + offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out; if( (r == BZ_STREAM_END) && (offset == 0) ) { - xar_bzip_fromheap_done(x, f, attr); - offset += outlen - offset - zs.avail_out; + xar_bzip_fromheap_done(x, f, attr, context); + offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out; break; } } @@ -114,14 +109,19 @@ return 0; } -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { #ifdef HAVE_LIBBZ2 - initted = 0; - BZ2_bzDecompressEnd(&zs); + BZ2_bzDecompressEnd(BZIP2_CONTEXT(context)); + + if(BZIP2_CONTEXT(context)){ + free(BZIP2_CONTEXT(context)); + *context = NULL; + } + #endif /* HAVE_LIBBZ2 */ return 0; } -int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { #ifdef HAVE_LIBBZ2 const char *opt; char *tmpstr; @@ -133,9 +133,13 @@ if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; - initted = 0; - BZ2_bzCompressEnd(&zs); + BZ2_bzCompressEnd(BZIP2_CONTEXT(context)); + if(BZIP2_CONTEXT(context)){ + free(BZIP2_CONTEXT(context)); + *context = NULL; + } + asprintf(&tmpstr, "%s/encoding", attr); if( f ) { xar_prop_set(f, tmpstr, NULL); @@ -147,7 +151,7 @@ return 0; } -int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { #ifdef HAVE_LIBBZ2 void *out = NULL; size_t outlen, offset = 0; @@ -161,33 +165,32 @@ if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; - if( !initted ) { - memset(&zs, 0, sizeof(zs)); - BZ2_bzCompressInit(&zs, 9, 0, 30); - initted = 1; + if( !BZIP2_CONTEXT(context) ) { + *context = calloc(1,sizeof(bz_stream)); + BZ2_bzCompressInit(BZIP2_CONTEXT(context), 9, 0, 30); } outlen = *inlen/2; if(outlen == 0) outlen = 1024; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + BZIP2_CONTEXT(context)->next_in = *in; + BZIP2_CONTEXT(context)->avail_in = *inlen; + BZIP2_CONTEXT(context)->next_out = out; + BZIP2_CONTEXT(context)->avail_out = 0; do { outlen *= 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + BZIP2_CONTEXT(context)->next_out = out + offset; + BZIP2_CONTEXT(context)->avail_out = outlen - offset; - if( *inlen == 0 ) - r = BZ2_bzCompress(&zs, BZ_FINISH); + if( (*inlen == 0) ) + r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_FINISH); else - r = BZ2_bzCompress(&zs, BZ_RUN); - offset = outlen - zs.avail_out; - } while( zs.avail_in != 0 ); + r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_RUN); + offset = outlen - BZIP2_CONTEXT(context)->avail_out; + } while( BZIP2_CONTEXT(context)->avail_in != 0 ); free(*in); *in = out; diff -urN xar/lib/bzxar.h xar.context/lib/bzxar.h --- xar/lib/bzxar.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/bzxar.h 2006-03-17 10:57:20.000000000 -0800 @@ -34,10 +34,10 @@ #ifndef _XAR_BZLIB_H_ #define _XAR_BZLIB_H_ -int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *); +int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context); -int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *); +int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_BZLIB_H_ */ diff -urN xar/lib/darwinattr.c xar.context/lib/darwinattr.c --- xar/lib/darwinattr.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/darwinattr.c 2006-03-17 11:26:37.000000000 -0800 @@ -54,8 +54,15 @@ #include #endif -static int Fd; +struct _darwinattr_context{ + int fd; + char *finfo; + char *buf; + int len; + int off; +}; +#define DARWINATTR_CONTEXT(x) ((struct _darwinattr_context *)(x)) #if defined(__APPLE__) #ifdef HAVE_GETATTRLIST #include @@ -66,21 +73,19 @@ char finderinfo[32]; }; -static char *Gfinfo = NULL; - /* finfo_read * This is for archiving the finderinfo via the getattrlist method. * This function is used from the nonea_archive() function. */ -static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( len < 32 ) return -1; - if( Gfinfo == NULL ) + if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; - memcpy(buf, Gfinfo, 32); - Gfinfo = NULL; + memcpy(buf, DARWINATTR_CONTEXT(context)->finfo, 32); + DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } @@ -88,26 +93,26 @@ * This is for extracting the finderinfo via the setattrlist method. * This function is used from the nonea_extract() function. */ -static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { struct attrlist attrs; struct fi finfo; if( len < 32 ) return -1; - if( Gfinfo == NULL ) + if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; - getattrlist(Gfinfo, &attrs, &finfo, sizeof(finfo), 0); + getattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, &finfo, sizeof(finfo), 0); attrs.commonattr = ATTR_CMN_FNDRINFO; - if( setattrlist(Gfinfo, &attrs, buf, 32, 0) != 0 ) + if( setattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, buf, 32, 0) != 0 ) return -1; - Gfinfo = NULL; + DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } #endif /* HAVE_GETATTRLIST */ @@ -116,11 +121,11 @@ * This is the read callback function for archiving the resource fork via * the ..namedfork method. This callback is used from nonea_archive() */ -static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) { +static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; while(1) { - r = read(Fd, inbuf, bsize); + r = read(DARWINATTR_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; return r; @@ -133,11 +138,11 @@ * back to the file via ..namedfork method. This is the callback used * in nonea_extract() and underbar_extract(). */ -static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; do { - r = write(Fd, buf+off, len-off); + r = write(DARWINATTR_CONTEXT(context)->fd, buf+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; @@ -147,57 +152,54 @@ #ifdef __APPLE__ #if defined(HAVE_GETXATTR) -static char *Gbuf = NULL; -static int Glen = 0; -static int Goff = 0; - -static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len) { - if( Gbuf == NULL ) + +static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; - if( (Glen-Goff) <= len ) { - int siz = Glen-Goff; - memcpy(buf, Gbuf+Goff, siz); - free(Gbuf); - Gbuf = NULL; - Goff = 0; - Glen = 0; + if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { + int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); + memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, siz); + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->off = 0; + DARWINATTR_CONTEXT(context)->len = 0; return siz; } - memcpy(buf, Gbuf+Goff, len); - Goff += len; + memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, len); + DARWINATTR_CONTEXT(context)->off += len; - if( Goff == Glen ) { - free(Gbuf); - Gbuf = NULL; - Goff = 0; - Glen = 0; + if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) { + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->off = 0; + DARWINATTR_CONTEXT(context)->len = 0; } return len; } -static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len) { - if( Gbuf == NULL ) +static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; - if( Goff == Glen ) + if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) return 0; - if( (Glen-Goff) <= len ) { - int siz = Glen-Goff; - memcpy(Gbuf+Goff, buf, siz); + if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { + int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); + memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, siz); return siz; } - memcpy(Gbuf+Goff, buf, len); - Goff += len; + memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, len); + DARWINATTR_CONTEXT(context)->off += len; return len; } -static int32_t ea_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t ea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char *buf, *i; int ret, bufsz; int32_t retval = 0; @@ -231,29 +233,29 @@ ret = getxattr(file, i, NULL, 0, 0, XATTR_NOFOLLOW); if( ret < 0 ) continue; - Glen = ret; - Gbuf = malloc(Glen); - if( !Gbuf ) + DARWINATTR_CONTEXT(context)->len = ret; + DARWINATTR_CONTEXT(context)->buf = malloc(DARWINATTR_CONTEXT(context)->len); + if( !DARWINATTR_CONTEXT(context)->buf ) goto BAIL; - ret = getxattr(file, i, Gbuf, Glen, 0, XATTR_NOFOLLOW); + ret = getxattr(file, i, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); if( ret < 0 ) { - free(Gbuf); - Gbuf = NULL; - Glen = 0; + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->len = 0; continue; } memset(tempnam, 0, sizeof(tempnam)); snprintf(tempnam, sizeof(tempnam)-1, "ea/%s", i); - xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read); + xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read, context); } BAIL: free(buf); return retval; } -static int32_t ea_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t ea_extract(xar_t x, xar_file_t f, const char* file, void *context) { const char *prop; xar_iter_t iter; @@ -275,18 +277,18 @@ continue; len = strtol(opt, NULL, 10); - Gbuf = malloc(len); - if( !Gbuf ) + DARWINATTR_CONTEXT(context)->buf = malloc(len); + if( !DARWINATTR_CONTEXT(context)->buf ) return -1; - Glen = len; + DARWINATTR_CONTEXT(context)->len = len; - xar_attrcopy_from_heap(x, f, prop, xar_ea_write); + xar_attrcopy_from_heap(x, f, prop, xar_ea_write, context); - setxattr(file, prop+strlen(XAR_EA_FORK)+1, Gbuf, Glen, 0, XATTR_NOFOLLOW); - free(Gbuf); - Gbuf = NULL; - Glen = 0; - Goff = 0; + setxattr(file, prop+strlen(XAR_EA_FORK)+1, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->len = 0; + DARWINATTR_CONTEXT(context)->off = 0; } return 0; @@ -298,7 +300,7 @@ * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ -static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; struct stat sb; #ifdef HAVE_GETATTRLIST @@ -317,8 +319,8 @@ memset(z, 0, sizeof(z)); if( memcmp(finfo.finderinfo, z, sizeof(finfo.finderinfo)) != 0 ) { - Gfinfo = finfo.finderinfo; - xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read); + DARWINATTR_CONTEXT(context)->finfo = finfo.finderinfo; + xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context); } #endif /* HAVE_GETATTRLIST */ @@ -331,12 +333,12 @@ if( sb.st_size == 0 ) return 0; - Fd = open(rsrcname, O_RDONLY, 0); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDONLY, 0); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; - xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read); - close(Fd); + xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context); + close(DARWINATTR_CONTEXT(context)->fd); return 0; } @@ -345,7 +347,7 @@ * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ -static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; #ifdef HAVE_SETATTRLIST struct attrlist attrs; @@ -360,19 +362,19 @@ if( ret != 0 ) return -1; - Gfinfo = (char *)file; + DARWINATTR_CONTEXT(context)->finfo = (char *)file; - xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write); + xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write, context); #endif /* HAVE_SETATTRLIST */ memset(rsrcname, 0, sizeof(rsrcname)); snprintf(rsrcname, sizeof(rsrcname)-1, "%s/..namedfork/rsrc", file); - Fd = open(rsrcname, O_RDWR|O_TRUNC); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDWR|O_TRUNC); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return 0; - xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context); + close(DARWINATTR_CONTEXT(context)->fd); return 0; } #endif /* __APPLE__ */ @@ -381,13 +383,13 @@ * Check to see if the file we're archiving is a ._ file. If so, * stop the archival process. */ -int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file) { +int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file, void *context) { char *bname, *tmp; tmp = strdup(file); bname = basename(tmp); - if(bname && (bname[0] == '.') && (bname[1] == '_')) { + if(bname && (bname[0] == '.') && (bname[1] == '_')){ free(tmp); return 1; } @@ -398,7 +400,7 @@ #ifdef __APPLE__ /* This only really makes sense on OSX */ -static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file, void *context) { struct stat sb; char underbarname[4096], z[32]; char *dname, *bname, *tmp, *tmp2; @@ -407,6 +409,9 @@ int num_entries = 0, i, r; off_t off; + if( !file ) + return 0; + tmp = strdup(file); tmp2 = strdup(file); dname = dirname(tmp2); @@ -420,13 +425,13 @@ if( stat(underbarname, &sb) != 0 ) return 0; - Fd = open(underbarname, O_RDONLY); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDONLY); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; memset(&ash, 0, sizeof(ash)); memset(&ase, 0, sizeof(ase)); - r = read(Fd, &ash, XAR_ASH_SIZE); + r = read(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); if( r < XAR_ASH_SIZE ) return -1; @@ -440,37 +445,38 @@ for(i = 0; i < num_entries; i++) { off_t entoff; - r = read(Fd, &ase, sizeof(ase)); + r = read(DARWINATTR_CONTEXT(context)->fd, &ase, sizeof(ase)); if( r < sizeof(ase) ) return -1; off+=r; if( ntohl(ase.entry_id) == AS_ID_FINDER ) { entoff = (off_t)ntohl(ase.offset); - if( lseek(Fd, entoff, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) return -1; - r = read(Fd, z, sizeof(z)); + r = read(DARWINATTR_CONTEXT(context)->fd, z, sizeof(z)); if( r < sizeof(z) ) return -1; - Gfinfo = z; - xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read); - if( lseek(Fd, (off_t)off, SEEK_SET) == -1 ) + DARWINATTR_CONTEXT(context)->finfo = z; + xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context); + if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) return -1; } if( ntohl(ase.entry_id) == AS_ID_RESOURCE ) { entoff = (off_t)ntohl(ase.offset); - if( lseek(Fd, entoff, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) return -1; - xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read); + xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context); - if( lseek(Fd, (off_t)off, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) return -1; } } - close(Fd); + close(DARWINATTR_CONTEXT(context)->fd); + DARWINATTR_CONTEXT(context)->fd = 0; return 0; } #endif @@ -479,7 +485,7 @@ * Extract finderinfo and resource fork information to an appledouble * ._ file. */ -static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file, void *context) { char underbarname[4096]; char *dname, *bname, *tmp, *tmp2; const char *rsrclenstr; @@ -510,8 +516,8 @@ free(tmp); free(tmp2); - Fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; xar_prop_get(f, "ea/com.apple.ResourceFork/size", &rsrclenstr); @@ -524,29 +530,31 @@ ash.version = htonl(APPLEDOUBLE_VERSION); ash.entries = htons(num_entries); - write(Fd, &ash, XAR_ASH_SIZE); + write(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); ase.offset = htonl(XAR_ASH_SIZE + ntohs(ash.entries)*12); if( have_fi ) { ase.entry_id = htonl(AS_ID_FINDER); ase.length = htonl(32); - write(Fd, &ase, 12); + write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_rsrc ) { ase.entry_id = htonl(AS_ID_RESOURCE); ase.offset = htonl(ntohl(ase.offset) + ntohl(ase.length)); ase.length = htonl(rsrclen); - write(Fd, &ase, 12); + write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_fi ) - xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write); + xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write, context); if( have_rsrc ) - xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context); + close(DARWINATTR_CONTEXT(context)->fd); - xar_set_perm(x, f, underbarname); + DARWINATTR_CONTEXT(context)->fd = 0; + + xar_set_perm(x, f, underbarname ); return 0; } @@ -554,28 +562,36 @@ int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file) { + struct _darwinattr_context context; + + memset(&context,0,sizeof(struct _darwinattr_context)); + #if defined(__APPLE__) #if defined(HAVE_GETXATTR) - if( ea_archive(x, f, file) == 0 ) + if( ea_archive(x, f, file, (void *)&context) == 0 ) return 0; #endif - if( nonea_archive(x, f, file) == 0 ) + if( nonea_archive(x, f, file, (void *)&context) == 0 ) return 0; - return underbar_archive(x, f, file); + return underbar_archive(x, f, file, (void *)&context); #endif /* __APPLE__ */ return 0; } int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file) { + struct _darwinattr_context context; + + memset(&context,0,sizeof(struct _darwinattr_context)); + #if defined(__APPLE__) #if defined(HAVE_GETXATTR) - if( ea_extract(x, f, file) == 0 ) + if( ea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif - if( nonea_extract(x, f, file) == 0 ) + if( nonea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif /* __APPLE__ */ - return underbar_extract(x, f, file); + return underbar_extract(x, f, file, (void *)&context); } diff -urN xar/lib/data.c xar.context/lib/data.c --- xar/lib/data.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/data.c 2006-03-17 11:00:28.000000000 -0800 @@ -18,24 +18,76 @@ #define O_EXLOCK 0 #endif -static int Fd; +struct _data_context{ + int fd; + void *buffer; + size_t length; + off_t offset; +}; -int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) { +#define DATA_CONTEXT(x) ((struct _data_context*)(x)) + +int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; + /* read from buffer, rather then fd,if available */ + if(DATA_CONTEXT(context)->length){ + char *readbuf = (char *)DATA_CONTEXT(context)->buffer; + size_t sizetoread = DATA_CONTEXT(context)->length - DATA_CONTEXT(context)->offset; + + if( !sizetoread){ + return 0; + } + + if( sizetoread > bsize ){ + sizetoread = bsize; + } + + /* dont read passed the end of the buffer */ + if((DATA_CONTEXT(context)->offset + sizetoread) > DATA_CONTEXT(context)->length){ + return -1; + } + + readbuf += DATA_CONTEXT(context)->offset; + memcpy(inbuf,readbuf,sizetoread); + + DATA_CONTEXT(context)->offset += sizetoread; + + return sizetoread; + } + while(1) { - r = read(Fd, inbuf, bsize); + r = read(DATA_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; return r; - } + } + } -int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len) { +int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; + + /* read from buffer, rather then fd,if available */ + if(DATA_CONTEXT(context)->length){ + char *writebuf = (char *)DATA_CONTEXT(context)->buffer; + + /* dont write passed the end of the buffer */ + if((DATA_CONTEXT(context)->offset + len) > DATA_CONTEXT(context)->length){ + return -1; + } + + writebuf += DATA_CONTEXT(context)->offset; + memcpy(writebuf,buf,len); + + DATA_CONTEXT(context)->offset += len; + + return len; + } + do { - r = write(Fd, buf+off, len-off); + r = write(DATA_CONTEXT(context)->fd, buf+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; @@ -50,6 +102,9 @@ int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file) { const char *opt; int32_t retval = 0; + struct _data_context context; + + memset(&context,0,sizeof(struct _data_context)); xar_prop_get(f, "type", &opt); if(!opt) return 0; @@ -65,60 +120,68 @@ return 0; } - Fd = open(file, O_RDONLY); - if( Fd < 0 ) { + context.fd = open(file, O_RDONLY); + if( context.fd < 0 ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "io: Could not open file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); return -1; - } + } - retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read); + retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read,(void *)(&context)); - close(Fd); + if(context.fd > 0) + close(context.fd); + return retval; } int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file) { const char *opt; - - /* Only regular files are copied in and out of the heap here */ - xar_prop_get(f, "type", &opt); - if( !opt ) return 0; - if( strcmp(opt, "file") != 0 ) { - if( strcmp(opt, "hardlink") == 0 ) { - opt = xar_attr_get(f, "type", "link"); - if( !opt ) - return 0; - if( strcmp(opt, "original") != 0 ) - return 0; - /* else, we're an original hardlink, so keep going */ - } else - return 0; - } - - /* mode 600 since other modules may need to operate on the file - * prior to the real permissions being set. - */ + struct _data_context context; + + memset(&context,0,sizeof(struct _data_context)); + + /* Only regular files are copied in and out of the heap here */ + xar_prop_get(f, "type", &opt); + if( !opt ) return 0; + if( strcmp(opt, "file") != 0 ) { + if( strcmp(opt, "hardlink") == 0 ) { + opt = xar_attr_get(f, "type", "link"); + if( !opt ) + return 0; + if( strcmp(opt, "original") != 0 ) + return 0; + /* else, we're an original hardlink, so keep going */ + } else + return 0; + } + + /* mode 600 since other modules may need to operate on the file + * prior to the real permissions being set. + */ TRYAGAIN: - Fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); - if( Fd < 0 ) { + context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); + if( context.fd < 0 ) { if( errno == ENOENT ) { xar_file_t parent = XAR_FILE(f)->parent; if( parent && (xar_extract(x, parent) == 0) ) goto TRYAGAIN; } + + xar_err_new(x); + xar_err_set_file(x, f); + xar_err_set_string(x, "io: Could not create file"); + xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + return -1; + } - xar_err_new(x); - xar_err_set_file(x, f); - xar_err_set_string(x, "io: Could not create file"); - xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); - return -1; - } - - xar_attrcopy_from_heap(x, f, "data", xar_data_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "data", xar_data_write, (void *)(&context)); + + if( context.fd > 0 ) + close(context.fd); + return 0; } diff -urN xar/lib/fbsdattr.c xar.context/lib/fbsdattr.c --- xar/lib/fbsdattr.c 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/fbsdattr.c 2006-03-17 11:03:08.000000000 -0800 @@ -57,41 +57,45 @@ #endif #ifdef HAVE_SYS_EXTATTR_H -static const char *Gfile = NULL; -static const char *Gattr = NULL; -static void *Gbuf = NULL; -static int Goff = 0; -static int Gbufsz = 0; -static int Gns = 0; +struct _fbsdattr_context{ + const char *file = NULL; + const char *attr = NULL; + void *buf = NULL; + int off = 0; + int bufsz = 0; + int ns = 0; +}; + +#define FBSDATTR_CONTEXT(x) ((struct _fbsdattr_context *)(x)) int32_t xar_fbsdattr_read(xar_t x, xar_file_t f, void *buf, size_t len) { - if( !Gbuf ) { - Gbufsz = extattr_get_link(Gfile, Gns, Gattr, NULL, 0); - if( Gbufsz < 0 ) + if( !FBSDATTR_CONTEXT(context)->buf ) { + FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, NULL, 0); + if( FBSDATTR_CONTEXT(context)->bufsz < 0 ) return -1; - Gbuf = malloc(Gbufsz); - if( !Gbuf ) + FBSDATTR_CONTEXT(context)->buf = malloc(FBSDATTR_CONTEXT(context)->bufsz); + if( !FBSDATTR_CONTEXT(context)->buf ) return -1; - Gbufsz = extattr_get_link(Gfile, Gns, Gattr, Gbuf, Gbufsz); + FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, FBSDATTR_CONTEXT(context)->buf, FBSDATTR_CONTEXT(context)->bufsz); } - if( (Gbufsz - Goff) <= len ) { + if( (FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off) <= len ) { int32_t ret; - ret = Gbufsz - Goff; - memcpy(buf, Gbuf+Goff, ret); - Goff += ret; + ret = FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off; + memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, ret); + FBSDATTR_CONTEXT(context)->off += ret; return(ret); } else { - memcpy(buf, Gbuf+Goff, len); - Gbuf += len; + memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, len); + FBSDATTR_CONTEXT(context)->buf += len; return(len); } } int32_t xar_fbsdattr_write(xar_t x, xar_file_t f, void *buf, size_t len) { - return extattr_set_link(Gfile, Gns, Gattr, buf, len); + return extattr_set_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, buf, len); } #endif @@ -103,7 +107,10 @@ struct statfs sfs; char *fsname = NULL; int namespace = EXTATTR_NAMESPACE_USER; - + struct _fbsdattr_context context; + + memset(&context,0,sizeof(struct _fbsdattr_context)); + TRYAGAIN: /* extattr_list_link()'s man page does not define the return * value. The kernel source comments say 0 for success, -1 for @@ -174,16 +181,16 @@ extattr_namespace_to_string(namespace, &ns); memset(tempnam, 0, sizeof(tempnam)); snprintf(tempnam, sizeof(tempnam)-1, "%s/%s.%s", XAR_EA_FORK, ns, key); - Gns = namespace; - Gfile = file; - Gattr = key; + FBSDATTR_CONTEXT(context).ns = namespace; + FBSDATTR_CONTEXT(context).file = file; + FBSDATTR_CONTEXT(context).attr = key; xar_attr_set(f, tempnam, "fstype", fsname); xar_attrcopy_to_heap(x, f, tempnam, xar_fbsdattr_read); - free(Gbuf); - Gbuf = NULL; - Goff = 0; + free(FBSDATTR_CONTEXT(context).buf); + FBSDATTR_CONTEXT(context).buf = NULL; + FBSDATTR_CONTEXT(context).off = 0; } if( namespace == EXTATTR_NAMESPACE_USER ) { @@ -200,7 +207,7 @@ #endif } -int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file) +int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #ifdef HAVE_SYS_EXTATTR_H char *fsname = "bogus"; @@ -208,7 +215,10 @@ struct statfs sfs; int eaopt = 0; xar_iter_t iter; - + struct _fbsdattr_context context; + + memset(&context,0,sizeof(struct _fbsdattr_context)); + statfs(file, &sfs); fsname = sfs.f_fstypename; @@ -227,16 +237,16 @@ tmp = prop + strlen(XAR_EA_FORK) + 1; if( strncmp(tmp, "user.", 5) == 0 ) { - Gns = EXTATTR_NAMESPACE_USER; - Gattr = tmp + 5; + FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_USER; + FBSDATTR_CONTEXT(context).attr = tmp + 5; } else if( strncmp(tmp, "system.", 7) == 0 ) { - Gns = EXTATTR_NAMESPACE_SYSTEM; - Gattr = tmp + 7; + FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_SYSTEM; + FBSDATTR_CONTEXT(context).attr = tmp + 7; } else { continue; } - Gfile = file; + FBSDATTR_CONTEXT(context).file = file; xar_attrcopy_from_heap(x, f, prop, xar_fbsdattr_write); } diff -urN xar/lib/io.c xar.context/lib/io.c --- xar/lib/io.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/io.c 2006-03-17 11:13:25.000000000 -0800 @@ -104,7 +104,9 @@ } }; -int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb) { +int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context) { + int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); + void *modulecontext[modulecount]; int r, off, i; size_t bsize, rsize; int64_t readsize=0, writesize=0, inc = 0; @@ -114,6 +116,8 @@ off_t orig_heap_offset = XAR(x)->heap_offset; xar_file_t tmpf = NULL; + memset(modulecontext, 0, sizeof(void*)*modulecount); + opt = xar_opt_get(x, XAR_OPT_RSIZE); if( !opt ) { bsize = 4096; @@ -130,7 +134,7 @@ if( !inbuf ) return -1; - r = rcb(x, f, inbuf, bsize); + r = rcb(x, f, inbuf, bsize, context); if( r < 0 ) { free(inbuf); return -1; @@ -141,16 +145,16 @@ rsize = r; /* filter the data through the in modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_in ) { - xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize); + xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize, &modulecontext[i]); } } /* filter the data through the out modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_out ) - xar_datamods[i].th_out(x, f, attr, inbuf, rsize); + xar_datamods[i].th_out(x, f, attr, inbuf, rsize, &modulecontext[i]); } off = 0; @@ -165,7 +169,7 @@ } XAR(x)->heap_offset += off; free(inbuf); - + } @@ -173,16 +177,16 @@ if( readsize == 0 ) { XAR(x)->heap_offset = orig_heap_offset; lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR); - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) - xar_datamods[i].th_done(x, NULL, attr); + xar_datamods[i].th_done(x, NULL, attr, &modulecontext[i]); } return 0; } /* finish up anything that still needs doing */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) - xar_datamods[i].th_done(x, f, attr); + xar_datamods[i].th_done(x, f, attr, &modulecontext[i]); } XAR(x)->heap_len += writesize; @@ -257,7 +261,9 @@ * data from the heap file. * It is assumed the heap_fd is already positioned appropriately. */ -int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb) { +int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context) { + int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); + void *modulecontext[modulecount]; int r, i; size_t bsize, def_bsize; int64_t fsize, inc = 0, seekoff; @@ -265,6 +271,8 @@ const char *opt; char *tmpstr = NULL; + memset(modulecontext, 0, sizeof(void*)*modulecount); + opt = xar_opt_get(x, "rsize"); if( !opt ) { def_bsize = 4096; @@ -279,7 +287,7 @@ xar_prop_get(f, tmpstr, &opt); free(tmpstr); if( !opt ) { - wcb(x, f, NULL, 0); + wcb(x, f, NULL, 0, context); return 0; } else { seekoff = strtoll(opt, NULL, 0); @@ -365,26 +373,30 @@ bsize = r; /* filter the data through the in modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_in ) { int32_t ret; - ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize); + ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize, &modulecontext[i]); if( ret < 0 ) return -1; } } - + + /* skip the write phase, if there is no write function to call */ + if(!wcb) + continue; + /* filter the data through the out modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_out ) { int32_t ret; - ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize); + ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize, &modulecontext[i]); if( ret < 0 ) return -1; } } - wcb(x, f, inbuf, bsize); + wcb(x, f, inbuf, bsize, context); free(inbuf); bsize = def_bsize; inbuf = malloc(bsize); @@ -392,10 +404,10 @@ free(inbuf); /* finish up anything that still needs doing */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_done ) { int32_t ret; - ret = xar_datamods[i].fh_done(x, f, attr); + ret = xar_datamods[i].fh_done(x, f, attr, &modulecontext[i]); if( ret < 0 ) return ret; } diff -urN xar/lib/io.h xar.context/lib/io.h --- xar/lib/io.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/io.h 2006-03-17 11:13:52.000000000 -0800 @@ -34,16 +34,16 @@ #ifndef _XAR_IO_H_ #define _XAR_IO_H_ -typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t); -typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t); +typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context); +typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context); -typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen); -typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr); - -typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen); -typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr); +typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context); +typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr, void **context); + +typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context); +typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr, void **context); struct datamod { fromheap_in fh_in; @@ -54,8 +54,8 @@ toheap_done th_done; }; -int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb); -int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb); +int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context); +int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context); int32_t xar_heap_to_archive(xar_t x); #endif /* _XAR_IO_H_ */ diff -urN xar/lib/linuxattr.c xar.context/lib/linuxattr.c --- xar/lib/linuxattr.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/linuxattr.c 2006-03-17 11:14:35.000000000 -0800 @@ -77,49 +77,54 @@ #endif #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__) -static const char *Gfile = NULL; -static const char *Gattr = NULL; -static void *Gbuf = NULL; -static int Goff = 0; -static int Gbufsz = 0; -int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len) { - - if( !Gbuf ) { +struct _linuxattr_context{ + const char *file; + const char *attr; + void *buf; + int off = 0; + int bufsz = 0; +}; + +#define LINUXATTR_CONTEXT(x) ((struct _linuxattr_context *)(x)) + +int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len, void *context) { + + if( !LINUXATTR_CONTEXT(context)->buf ) { int r; - Gbufsz = 1024; + LINUXATTR_CONTEXT(context)->bufsz = 1024; AGAIN2: - Gbuf = malloc(Gbufsz); - if(!Gbuf) + LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz); + if(!LINUXATTR_CONTEXT(context)->buf) goto AGAIN2; - memset(Gbuf, 0, Gbufsz); - r = lgetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, Gbuf, Gbufsz); + memset(LINUXATTR_CONTEXT(context)->buf, 0, LINUXATTR_CONTEXT(context)->bufsz); + r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, LINUXATTR_CONTEXT(context)->buf, LINUXATTR_CONTEXT(context)->bufsz); if( r < 0 ) { switch(errno) { - case ERANGE: Gbufsz *= 2; free(Gbuf); goto AGAIN2; - case ENOTSUP: free(Gbuf); return 0; + case ERANGE: LINUXATTR_CONTEXT(context)->bufsz *= 2; free(LINUXATTR_CONTEXT(context)->buf); goto AGAIN2; + case ENOTSUP: free(LINUXATTR_CONTEXT(context)->buf); return 0; default: break; }; return -1; } - Gbufsz = r; + LINUXATTR_CONTEXT(context)->bufsz = r; } - if( (Gbufsz-Goff) <= len ) { + if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) { int32_t ret; - ret = Gbufsz - Goff; - memcpy(buf, Gbuf+Goff, ret); - Goff += ret; + ret = LINUXATTR_CONTEXT(context)->bufsz - LINUXATTR_CONTEXT(context)->off; + memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, ret); + LINUXATTR_CONTEXT(context)->off += ret; return(ret); } else { - memcpy(buf, Gbuf+Goff, len); - Gbuf += len; + memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, len); + LINUXATTR_CONTEXT(context)->buf += len; return len; } } -int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len) { - return lsetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, buf, len, 0); +int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + return lsetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, buf, len, 0); } #endif @@ -130,7 +135,10 @@ int ret, retval=0, bufsz = 1024; struct statfs sfs; char *fsname = NULL; - + struct _linuxattr_context context; + + memset(&context,0,sizeof(struct _linuxattr_context)); + TRYAGAIN: buf = malloc(bufsz); if(!buf) @@ -159,18 +167,18 @@ for( i=buf; (i-buf) < ret; i += strlen(i)+1 ) { char tmpnam[1024]; - Gbufsz = 0; - Goff = 0; - Gbuf = NULL; - Gfile = file; + LINUXATTR_CONTEXT(context)->bufsz = 0; + LINUXATTR_CONTEXT(context)->off = 0; + LINUXATTR_CONTEXT(context)->buf = NULL; + LINUXATTR_CONTEXT(context)->file = file; memset(tmpnam, 0, sizeof(tmpnam)); snprintf(tmpnam, sizeof(tmpnam)-1, "%s/%s", XAR_EA_FORK, i); xar_prop_set(f, tmpnam, NULL); xar_attr_set(f, tmpnam, "fstype", fsname); - Gattr = tmpnam; + LINUXATTR_CONTEXT(context)->attr = tmpnam; xar_attrcopy_to_heap(x, f, tmpnam, xar_linuxattr_read); - free(Gbuf); - Gattr = NULL; + free(LINUXATTR_CONTEXT(context)->buf); + LINUXATTR_CONTEXT(context)->attr = NULL; } BAIL: @@ -188,8 +196,10 @@ struct statfs sfs; int eaopt = 0; xar_iter_t iter; - - + struct _linuxattr_context context; + + memset(&context,0,sizeof(struct _linuxattr_context)); + /* Check for EA extraction behavior */ memset(&sfs, 0, sizeof(sfs)); @@ -223,8 +233,8 @@ if( !fs ) continue; - Gfile = file; - Gattr = prop; + LINUXATTR_CONTEXT(context)->file = file; + LINUXATTR_CONTEXT(context)->attr = prop; xar_attrcopy_from_heap(x, f, prop, xar_linuxattr_write); } diff -urN xar/lib/macho.c xar.context/lib/macho.c --- xar/lib/macho.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/macho.c 2006-03-17 11:15:23.000000000 -0800 @@ -21,14 +21,17 @@ int32_t offset; }; -static int initted = 0; -static struct arches *inflight = NULL; -static int32_t numarches = 0; -static int32_t curroffset = 0; +struct _macho_context{ + struct arches *inflight; + int32_t numarches; + int32_t curroffset; +}; + +#define MACHO_CONTEXT(x) ((struct _macho_context *)(*x)) static int32_t parse_arch(xar_file_t f, struct mach_header *mh); -int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { struct mach_header *mh = *in; struct fat_header *fh = *in; uint32_t magic; @@ -37,62 +40,69 @@ if( strcmp(attr, "data") != 0 ) return 0; - if( initted && (inflight != NULL) ) - return 0; - + if(!MACHO_CONTEXT(context)) + *context = calloc(1,sizeof(struct _macho_context)); + else + return 0; /*We only run for the first part of the data stream*/ + /* First, check for fat */ magic = htonl(fh->magic); if( magic == 0xcafebabe ) { struct fat_arch *fa = (struct fat_arch *)((unsigned char *)*in + sizeof(struct fat_header)); - numarches = htonl(fh->nfat_arch); + MACHO_CONTEXT(context)->numarches = htonl(fh->nfat_arch); /* sanity check, arbitrary number */ - if( numarches > 7 ) + if( MACHO_CONTEXT(context)->numarches > 7 ) return 0; xar_prop_set(f, "contents/type", "Mach-O Fat File"); - inflight = malloc( numarches * sizeof(struct arches) ); - if( !inflight ) + MACHO_CONTEXT(context)->inflight = malloc( MACHO_CONTEXT(context)->numarches * sizeof(struct arches) ); + if( !MACHO_CONTEXT(context)->inflight ){ + free(*context); return -1; + } - for( i = 0; i < numarches; ++i ) { + for( i = 0; i < MACHO_CONTEXT(context)->numarches; ++i ) { int32_t sz = htonl(fa[i].size); int32_t off = htonl(fa[i].offset); - inflight[i].size = sz; - inflight[i].offset = off; + MACHO_CONTEXT(context)->inflight[i].size = sz; + MACHO_CONTEXT(context)->inflight[i].offset = off; } - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } - if( inflight ) { - for(i = 0; i < numarches; ++i) { - if( (inflight[i].offset >= curroffset) && (inflight[i].offset < (curroffset+*inlen)) ) { + if( MACHO_CONTEXT(context)->inflight ) { + for(i = 0; i < MACHO_CONTEXT(context)->numarches; ++i) { + if( (MACHO_CONTEXT(context)->inflight[i].offset >= MACHO_CONTEXT(context)->curroffset) && + (MACHO_CONTEXT(context)->inflight[i].offset < (MACHO_CONTEXT(context)->curroffset+*inlen)) ) { - mh = (struct mach_header *)((char *)*in + (inflight[i].offset - curroffset)); + mh = (struct mach_header *)((char *)*in + + (MACHO_CONTEXT(context)->inflight[i].offset - MACHO_CONTEXT(context)->curroffset)); parse_arch(f, mh); } } - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } parse_arch(f, mh); - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } -int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr) { - if( inflight ) - free(inflight); - inflight = NULL; - curroffset = 0; - numarches = 0; - initted = 0; +int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context) { + + if( MACHO_CONTEXT(context) ){ + if( MACHO_CONTEXT(context)->inflight ) + free(MACHO_CONTEXT(context)->inflight); + free(*context); + } + return 0; } diff -urN xar/lib/macho.h xar.context/lib/macho.h --- xar/lib/macho.h 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/macho.h 2006-03-17 11:15:27.000000000 -0800 @@ -31,7 +31,7 @@ uint32_t alighn; }; -int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr); +int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context); #endif /* _MACHO_H_ */ diff -urN xar/lib/md5.c xar.context/lib/md5.c --- xar/lib/md5.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/md5.c 2006-03-17 11:38:29.000000000 -0800 @@ -11,77 +11,112 @@ #endif #include "xar.h" -static EVP_MD_CTX src_ctx, dst_ctx; -static int initted = 0; +struct _md5_context{ + EVP_MD_CTX src_ctx; + EVP_MD_CTX dst_ctx; + uint8_t src; + uint8_t dst; +}; + +#define CONTEXT(x) ((struct _md5_context *)(*x)) static char* xar_format_md5(const unsigned char* m); -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { const EVP_MD *md; - - if( !initted ) { + + if(!context) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _md5_context)); OpenSSL_add_all_digests(); + } + + if( !CONTEXT(context)->src ){ md = EVP_get_digestbyname("md5"); if( md == NULL ) return -1; - EVP_DigestInit(&src_ctx, md); - EVP_DigestInit(&dst_ctx, md); - initted = 1; + EVP_DigestInit(&(CONTEXT(context)->src_ctx), md); + CONTEXT(context)->src = 1; } - + if( *inlen == 0 ) return 0; - - EVP_DigestUpdate(&src_ctx, *in, *inlen); + + EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), *in, *inlen); return 0; } -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen) { +int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context) { const EVP_MD *md; - - if( !initted ) { + + if(!context) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _md5_context)); OpenSSL_add_all_digests(); + } + + if( !CONTEXT(context)->dst ){ md = EVP_get_digestbyname("md5"); if( md == NULL ) return -1; - EVP_DigestInit(&src_ctx, md); - EVP_DigestInit(&dst_ctx, md); - initted = 1; + EVP_DigestInit(&(CONTEXT(context)->dst_ctx), md); + CONTEXT(context)->dst = 1; } - + if( inlen == 0 ) return 0; - - EVP_DigestUpdate(&dst_ctx, in, inlen); + + EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), in, inlen); return 0; } -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr) { +int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr, void **context) { unsigned char md5str[EVP_MAX_MD_SIZE]; char *str, *tmpstr; unsigned int len; - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&src_ctx, md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/extracted-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); + + if(!CONTEXT(context)) + return 0; + + if( CONTEXT(context)->src ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->src_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + + memset(md5str, 0, sizeof(md5str)); + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); + str = xar_format_md5(md5str); + asprintf(&tmpstr, "%s/extracted-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", "md5"); + } + free(tmpstr); + free(str); } - free(tmpstr); - free(str); - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&dst_ctx, md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/archived-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); + + if( CONTEXT(context)->dst ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->dst_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + + memset(md5str, 0, sizeof(md5str)); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); + str = xar_format_md5(md5str); + asprintf(&tmpstr, "%s/archived-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", "md5"); + } + free(tmpstr); + free(str); } - free(tmpstr); - free(str); - - initted = 0; + + if(*context){ + free(*context); + *context = NULL; + } + return 0; } @@ -99,33 +134,46 @@ return result; } -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr) { +int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr, void **context) { const char *uncomp, *uncompstyle; unsigned char md5str[EVP_MAX_MD_SIZE]; unsigned int len; char *tmpstr; - + + if(!CONTEXT(context)) + return 0; + + if( !(CONTEXT(context)->dst || CONTEXT(context)->src) ){ + return 0; + } + asprintf(&tmpstr, "%s/extracted-checksum", attr); xar_prop_get(f, tmpstr, &uncomp); uncompstyle = xar_attr_get(f, tmpstr, "style"); free(tmpstr); - - if( uncomp && uncompstyle && (strcmp(uncompstyle, "md5")==0) ) { + + if( uncomp && uncompstyle && CONTEXT(context)->dst ) { char *str; memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&dst_ctx, md5str, &len); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); str = xar_format_md5(md5str); if(strcmp(uncomp, str) != 0) { xar_err_new(x); xar_err_set_file(x, f); - xar_err_set_string(x, "extracted-checksum MD5's do not match"); + asprintf(&tmpstr, "extracted-checksum MD5's do not match"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); } free(str); } - - EVP_DigestFinal(&src_ctx, md5str, &len); - initted = 0; - + + if( CONTEXT(context)->src ) + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); + + if(*context){ + free(*context); + *context = NULL; + } + return 0; + } diff -urN xar/lib/md5.h xar.context/lib/md5.h --- xar/lib/md5.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/md5.h 2006-03-17 11:32:14.000000000 -0800 @@ -34,9 +34,9 @@ #ifndef _XAR_MD5_H_ #define _XAR_MD5_H_ -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen); -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *); -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *); +int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen, void **context); +int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int32_t xar_md5_done(xar_t x, xar_file_t f, const char *, void **context); +int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_MD5_H_ */ diff -urN xar/lib/script.c xar.context/lib/script.c --- xar/lib/script.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/script.c 2006-03-17 11:15:45.000000000 -0800 @@ -9,14 +9,25 @@ #endif #include "xar.h" -static int initted = 0; +struct _script_context{ + int initted; +}; -int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +#define SCRIPT_CONTEXT(x) ((struct _script_context*)(*x)) + +int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { char *buf = *in; - if( initted ) + if(!SCRIPT_CONTEXT(context)){ + *context = calloc(1,sizeof(struct _script_context)); + } + + if( SCRIPT_CONTEXT(context)->initted ) return 0; + /*We only run on the begining of the file, so once we init, we don't run again*/ + SCRIPT_CONTEXT(context)->initted = 1; + if( (*inlen > 2) && (buf[0] == '#') && (buf[1] == '!') ) { char *exe; int i; @@ -37,7 +48,16 @@ return 0; } -int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr) { - initted = 0; +int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context) { + + if(!SCRIPT_CONTEXT(context)){ + return 0; + } + + if( *context ){ + free(*context); + *context = NULL; + } + return 0; } diff -urN xar/lib/script.h xar.context/lib/script.h --- xar/lib/script.h 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/script.h 2006-03-17 11:15:48.000000000 -0800 @@ -1,7 +1,7 @@ #ifndef _SCRIPT_H_ #define _SCRIPT_H_ -int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr); +int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context); #endif /* _SCRIPT_H_ */ diff -urN xar/lib/zxar.c xar.context/lib/zxar.c --- xar/lib/zxar.c 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/zxar.c 2006-03-17 11:16:23.000000000 -0800 @@ -44,12 +44,10 @@ #include "filetree.h" #include "io.h" -static int initted = 0; -static z_stream zs; +#define GZIP_CONTEXT(x) ((z_stream *)(*x)) +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context); -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr); - -int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { const char *opt; void *out = NULL; size_t outlen, offset = 0; @@ -62,31 +60,27 @@ if( !opt ) return 0; if( strcmp(opt, "application/x-gzip") != 0 ) return 0; - if( !initted ) { - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - - inflateInit(&zs); - initted = 1; + if( !GZIP_CONTEXT(context) ) { + *context = calloc(1,sizeof(z_stream)); + inflateInit(GZIP_CONTEXT(context)); } outlen = *inlen; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + GZIP_CONTEXT(context)->next_in = *in; + GZIP_CONTEXT(context)->avail_in = *inlen; + GZIP_CONTEXT(context)->next_out = out; + GZIP_CONTEXT(context)->avail_out = 0; - while( zs.avail_in != 0 ) { + while( GZIP_CONTEXT(context)->avail_in != 0 ) { outlen = outlen * 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + GZIP_CONTEXT(context)->next_out = out + offset; + GZIP_CONTEXT(context)->avail_out = outlen - offset; - r = inflate(&zs, Z_SYNC_FLUSH); + r = inflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH); if( (r != Z_OK) && (r != Z_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); @@ -94,11 +88,11 @@ xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } - offset += outlen - offset - zs.avail_out; + offset += outlen - offset - GZIP_CONTEXT(context)->avail_out; if( (r == Z_STREAM_END) && (offset == 0) ) { - //r = inflate(&zs, Z_FINISH); - xar_gzip_fromheap_done(x, f, attr); - offset += outlen - offset - zs.avail_out; + //r = inflate(GZIP_CONTEXT(context), Z_FINISH); + xar_gzip_fromheap_done(x, f, attr, context); + offset += outlen - offset - GZIP_CONTEXT(context)->avail_out; break; } } @@ -109,12 +103,17 @@ return 0; } -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) { - initted = 0; - inflateEnd(&zs); +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { + inflateEnd(GZIP_CONTEXT(context)); + + if(GZIP_CONTEXT(context)){ + free(GZIP_CONTEXT(context)); + *context = NULL; + } + return 0; } -int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { const char *opt; char *tmpstr; @@ -124,10 +123,14 @@ if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 ) return 0; + + deflateEnd(GZIP_CONTEXT(context)); - initted = 0; - deflateEnd(&zs); - + if(GZIP_CONTEXT(context)){ + free(GZIP_CONTEXT(context)); + *context = NULL; + } + asprintf(&tmpstr, "%s/encoding", attr); if( f ) { xar_prop_set(f, tmpstr, NULL); @@ -138,7 +141,7 @@ return 0; } -int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { void *out = NULL; size_t outlen, offset = 0; int r; @@ -151,33 +154,32 @@ if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 ) return 0; - if( !initted ) { - memset(&zs, 0, sizeof(zs)); - deflateInit(&zs, Z_BEST_COMPRESSION); - initted = 1; + if( !GZIP_CONTEXT(context) ) { + *context = calloc(1,sizeof(z_stream)); + deflateInit(GZIP_CONTEXT(context), Z_BEST_COMPRESSION); } - + outlen = *inlen/2; if(outlen == 0) outlen = 1024; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + GZIP_CONTEXT(context)->next_in = *in; + GZIP_CONTEXT(context)->avail_in = *inlen; + GZIP_CONTEXT(context)->next_out = out; + GZIP_CONTEXT(context)->avail_out = 0; do { outlen *= 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + GZIP_CONTEXT(context)->next_out = out + offset; + GZIP_CONTEXT(context)->avail_out = outlen - offset; if( *inlen == 0 ) - r = deflate(&zs, Z_FINISH); + r = deflate(GZIP_CONTEXT(context), Z_FINISH); else - r = deflate(&zs, Z_SYNC_FLUSH); - offset = outlen - zs.avail_out; - } while( zs.avail_in != 0 ); + r = deflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH); + offset = outlen - GZIP_CONTEXT(context)->avail_out; + } while( GZIP_CONTEXT(context)->avail_in != 0 ); free(*in); *in = out; diff -urN xar/lib/zxar.h xar.context/lib/zxar.h --- xar/lib/zxar.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/zxar.h 2006-03-17 11:16:27.000000000 -0800 @@ -34,10 +34,10 @@ #ifndef _XAR_ZLIB_H_ #define _XAR_ZLIB_H_ -int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *); +int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context); -int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *); +int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_ZLIB_H_ */