context.diff   [plain text]


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 <sys/xattr.h>
 #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 <sys/attr.h>
@@ -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_ */