1diff -urN xar/lib/archive.c xar.context/lib/archive.c
2--- xar/lib/archive.c	2006-02-23 23:05:04.000000000 -0800
3+++ xar.context/lib/archive.c	2006-03-17 11:24:36.000000000 -0800
4@@ -64,6 +64,13 @@
5 #define O_SHLOCK 0
6 #endif
7 
8+#ifndef LONG_MAX
9+#define LONG_MAX INT32_MAX
10+#endif
11+#ifndef LONG_MIN
12+#define LONG_MIN INT32_MIN
13+#endif
14+
15 static int32_t xar_unserialize(xar_t x);
16 void xar_serialize(xar_t x, const char *file);
17 
18diff -urN xar/lib/bzxar.c xar.context/lib/bzxar.c
19--- xar/lib/bzxar.c	2006-02-23 23:05:04.000000000 -0800
20+++ xar.context/lib/bzxar.c	2006-03-17 10:57:14.000000000 -0800
21@@ -47,13 +47,12 @@
22 #include "io.h"
23 
24 #ifdef HAVE_LIBBZ2
25-static int initted = 0;
26-static bz_stream zs;
27+#define BZIP2_CONTEXT(x) ((bz_stream *)(*x))
28 #endif
29 
30-int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr);
31+int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context);
32 
33-int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
34+int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
35 #ifdef HAVE_LIBBZ2
36 	const char *opt;
37 	void *out = NULL;
38@@ -67,31 +66,27 @@
39 	if( !opt ) return 0;
40 	if( strcmp(opt, "application/x-bzip2") != 0 ) return 0;
41 
42-	if( !initted ) {
43-		zs.bzalloc = NULL;
44-		zs.bzfree = NULL;
45-		zs.opaque = NULL;
46-
47-		BZ2_bzDecompressInit(&zs, 0, 0);
48-		initted = 1;
49+	if( !BZIP2_CONTEXT(context) ) {
50+		*context = calloc(1,sizeof(bz_stream));
51+		BZ2_bzDecompressInit(BZIP2_CONTEXT(context), 0, 0);
52 	}
53 
54 	outlen = *inlen;
55 
56-	zs.next_in = *in;
57-	zs.avail_in = *inlen;
58-	zs.next_out = out;
59-	zs.avail_out = 0;
60+	BZIP2_CONTEXT(context)->next_in = *in;
61+	BZIP2_CONTEXT(context)->avail_in = *inlen;
62+	BZIP2_CONTEXT(context)->next_out = out;
63+	BZIP2_CONTEXT(context)->avail_out = 0;
64 
65-	while( zs.avail_in != 0 ) {
66+	while( BZIP2_CONTEXT(context)->avail_in != 0 ) {
67 		outlen = outlen * 2;
68 		out = realloc(out, outlen);
69 		if( out == NULL ) abort();
70 
71-		zs.next_out = out + offset;
72-		zs.avail_out = outlen - offset;
73+		BZIP2_CONTEXT(context)->next_out = out + offset;
74+		BZIP2_CONTEXT(context)->avail_out = outlen - offset;
75 
76-		r = BZ2_bzDecompress(&zs);
77+		r = BZ2_bzDecompress(BZIP2_CONTEXT(context));
78 		if( (r != BZ_OK) && (r != BZ_STREAM_END) ) {
79 			xar_err_new(x);
80 			xar_err_set_file(x, f);
81@@ -99,10 +94,10 @@
82 			xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION);
83 			return -1;
84 		}
85-		offset += outlen - offset - zs.avail_out;
86+		offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out;
87 		if( (r == BZ_STREAM_END) && (offset == 0) ) {
88-			xar_bzip_fromheap_done(x, f, attr);
89-			offset += outlen - offset - zs.avail_out;
90+			xar_bzip_fromheap_done(x, f, attr, context);
91+			offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out;
92 			break;
93 		}
94 	}
95@@ -114,14 +109,19 @@
96 	return 0;
97 }
98 
99-int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) {
100+int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) {
101 #ifdef HAVE_LIBBZ2
102-	initted = 0;
103-	BZ2_bzDecompressEnd(&zs);
104+	BZ2_bzDecompressEnd(BZIP2_CONTEXT(context));
105+	
106+	if(BZIP2_CONTEXT(context)){
107+		free(BZIP2_CONTEXT(context));
108+		*context = NULL;
109+	}
110+	
111 #endif /* HAVE_LIBBZ2 */
112 	return 0;
113 }
114-int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr) {
115+int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) {
116 #ifdef HAVE_LIBBZ2
117 	const char *opt;
118 	char *tmpstr;
119@@ -133,9 +133,13 @@
120 	if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 )
121 		return 0;
122 
123-	initted = 0;
124-	BZ2_bzCompressEnd(&zs);
125+	BZ2_bzCompressEnd(BZIP2_CONTEXT(context));
126 
127+	if(BZIP2_CONTEXT(context)){
128+		free(BZIP2_CONTEXT(context));
129+		*context = NULL;
130+	}
131+	
132 	asprintf(&tmpstr, "%s/encoding", attr);
133 	if( f ) {
134 		xar_prop_set(f, tmpstr, NULL);
135@@ -147,7 +151,7 @@
136 	return 0;
137 }
138 
139-int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
140+int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
141 #ifdef HAVE_LIBBZ2
142 	void *out = NULL;
143 	size_t outlen, offset = 0;
144@@ -161,33 +165,32 @@
145 	if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 )
146 		return 0;
147 
148-	if( !initted ) {
149-		memset(&zs, 0, sizeof(zs));
150-		BZ2_bzCompressInit(&zs, 9, 0, 30);
151-		initted = 1;
152+	if( !BZIP2_CONTEXT(context) ) {
153+		*context = calloc(1,sizeof(bz_stream));
154+		BZ2_bzCompressInit(BZIP2_CONTEXT(context), 9, 0, 30);
155 	}
156 
157 	outlen = *inlen/2;
158 	if(outlen == 0) outlen = 1024;
159-	zs.next_in = *in;
160-	zs.avail_in = *inlen;
161-	zs.next_out = out;
162-	zs.avail_out = 0;
163+	BZIP2_CONTEXT(context)->next_in = *in;
164+	BZIP2_CONTEXT(context)->avail_in = *inlen;
165+	BZIP2_CONTEXT(context)->next_out = out;
166+	BZIP2_CONTEXT(context)->avail_out = 0;
167 
168 	do {
169 		outlen *= 2;
170 		out = realloc(out, outlen);
171 		if( out == NULL ) abort();
172 
173-		zs.next_out = out + offset;
174-		zs.avail_out = outlen - offset;
175+		BZIP2_CONTEXT(context)->next_out = out + offset;
176+		BZIP2_CONTEXT(context)->avail_out = outlen - offset;
177 
178-		if( *inlen == 0 )
179-			r = BZ2_bzCompress(&zs, BZ_FINISH);
180+		if( (*inlen == 0) )
181+			r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_FINISH);
182 		else
183-			r = BZ2_bzCompress(&zs, BZ_RUN);
184-		offset = outlen - zs.avail_out;
185-	} while( zs.avail_in != 0 );
186+			r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_RUN);
187+		offset = outlen - BZIP2_CONTEXT(context)->avail_out;
188+	} while( BZIP2_CONTEXT(context)->avail_in != 0 );
189 
190 	free(*in);
191 	*in = out;
192diff -urN xar/lib/bzxar.h xar.context/lib/bzxar.h
193--- xar/lib/bzxar.h	2006-02-17 11:27:10.000000000 -0800
194+++ xar.context/lib/bzxar.h	2006-03-17 10:57:20.000000000 -0800
195@@ -34,10 +34,10 @@
196 #ifndef _XAR_BZLIB_H_
197 #define _XAR_BZLIB_H_
198 
199-int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen);
200-int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *);
201+int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context);
202+int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context);
203 
204-int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen);
205-int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *);
206+int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context);
207+int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context);
208 
209 #endif /* _XAR_BZLIB_H_ */
210diff -urN xar/lib/darwinattr.c xar.context/lib/darwinattr.c
211--- xar/lib/darwinattr.c	2006-02-23 23:05:04.000000000 -0800
212+++ xar.context/lib/darwinattr.c	2006-03-17 11:26:37.000000000 -0800
213@@ -54,8 +54,15 @@
214 #include <sys/xattr.h>
215 #endif
216 
217-static int Fd;
218+struct _darwinattr_context{
219+	int fd;
220+	char *finfo;
221+	char *buf;
222+	int   len;
223+	int   off;
224+};
225 
226+#define DARWINATTR_CONTEXT(x) ((struct _darwinattr_context *)(x))
227 #if defined(__APPLE__)
228 #ifdef HAVE_GETATTRLIST
229 #include <sys/attr.h>
230@@ -66,21 +73,19 @@
231     char finderinfo[32];
232 };
233 
234-static char *Gfinfo = NULL;
235-
236 /* finfo_read
237  * This is for archiving the finderinfo via the getattrlist method.
238  * This function is used from the nonea_archive() function.
239  */
240-static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len) {
241+static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
242 	if( len < 32 )
243 		return -1;
244 
245-	if( Gfinfo == NULL )
246+	if( DARWINATTR_CONTEXT(context)->finfo == NULL )
247 		return 0;
248 
249-	memcpy(buf, Gfinfo, 32);
250-	Gfinfo = NULL;
251+	memcpy(buf, DARWINATTR_CONTEXT(context)->finfo, 32);
252+	DARWINATTR_CONTEXT(context)->finfo = NULL;
253 	return 32;
254 }
255 
256@@ -88,26 +93,26 @@
257  * This is for extracting the finderinfo via the setattrlist method.
258  * This function is used from the nonea_extract() function.
259  */
260-static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len) {
261+static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
262 	struct attrlist attrs;
263 	struct fi finfo;
264 
265 	if( len < 32 )
266 		return -1;
267-	if( Gfinfo == NULL )
268+	if( DARWINATTR_CONTEXT(context)->finfo == NULL )
269 		return 0;
270 
271 	memset(&attrs, 0, sizeof(attrs));
272 	attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
273 	attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO;
274 
275-	getattrlist(Gfinfo, &attrs, &finfo, sizeof(finfo), 0);
276+	getattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, &finfo, sizeof(finfo), 0);
277 
278 	attrs.commonattr = ATTR_CMN_FNDRINFO;
279-	if( setattrlist(Gfinfo, &attrs, buf, 32, 0) != 0 )
280+	if( setattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, buf, 32, 0) != 0 )
281 		return -1;
282 
283-	Gfinfo = NULL;
284+	DARWINATTR_CONTEXT(context)->finfo = NULL;
285 	return 32;
286 }
287 #endif /* HAVE_GETATTRLIST */
288@@ -116,11 +121,11 @@
289  * This is the read callback function for archiving the resource fork via
290  * the ..namedfork method.  This callback is used from nonea_archive()
291  */
292-static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) {
293+static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) {
294 	int32_t r;
295 
296 	while(1) {
297-		r = read(Fd, inbuf, bsize);
298+		r = read(DARWINATTR_CONTEXT(context)->fd, inbuf, bsize);
299 		if( (r < 0) && (errno == EINTR) )
300 			continue;
301 		return r;
302@@ -133,11 +138,11 @@
303  * back to the file via ..namedfork method.  This is the callback used
304  * in nonea_extract() and underbar_extract().
305  */
306-static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len) {
307+static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
308 	int32_t r;
309 	size_t off = 0;
310 	do {
311-		r = write(Fd, buf+off, len-off);
312+		r = write(DARWINATTR_CONTEXT(context)->fd, buf+off, len-off);
313 		if( (r < 0) && (errno != EINTR) )
314 			return r;
315 		off += r;
316@@ -147,57 +152,54 @@
317 
318 #ifdef __APPLE__
319 #if defined(HAVE_GETXATTR)
320-static char *Gbuf = NULL;
321-static int   Glen = 0;
322-static int   Goff = 0;
323-
324-static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len) {
325-	if( Gbuf == NULL )
326+
327+static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
328+	if( DARWINATTR_CONTEXT(context)->buf == NULL )
329 		return 0;
330 
331-	if( (Glen-Goff) <= len ) {
332-		int siz = Glen-Goff;
333-		memcpy(buf, Gbuf+Goff, siz);
334-		free(Gbuf);
335-		Gbuf = NULL;
336-		Goff = 0;
337-		Glen = 0;
338+	if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) {
339+		int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off);
340+		memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, siz);
341+		free(DARWINATTR_CONTEXT(context)->buf);
342+		DARWINATTR_CONTEXT(context)->buf = NULL;
343+		DARWINATTR_CONTEXT(context)->off = 0;
344+		DARWINATTR_CONTEXT(context)->len = 0;
345 		return siz;
346 	}
347 
348-	memcpy(buf, Gbuf+Goff, len);
349-	Goff += len;
350+	memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, len);
351+	DARWINATTR_CONTEXT(context)->off += len;
352 
353-	if( Goff == Glen ) {
354-		free(Gbuf);
355-		Gbuf = NULL;
356-		Goff = 0;
357-		Glen = 0;
358+	if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) {
359+		free(DARWINATTR_CONTEXT(context)->buf);
360+		DARWINATTR_CONTEXT(context)->buf = NULL;
361+		DARWINATTR_CONTEXT(context)->off = 0;
362+		DARWINATTR_CONTEXT(context)->len = 0;
363 	}
364 
365 	return len;
366 }
367 
368-static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len) {
369-	if( Gbuf == NULL )
370+static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
371+	if( DARWINATTR_CONTEXT(context)->buf == NULL )
372 		return 0;
373 
374-	if( Goff == Glen )
375+	if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len )
376 		return 0;
377 
378-	if( (Glen-Goff) <= len ) {
379-		int siz = Glen-Goff;
380-		memcpy(Gbuf+Goff, buf, siz);
381+	if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) {
382+		int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off);
383+		memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, siz);
384 		return siz;
385 	}
386 
387-	memcpy(Gbuf+Goff, buf, len);
388-	Goff += len;
389+	memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, len);
390+	DARWINATTR_CONTEXT(context)->off += len;
391 
392 	return len;
393 }
394 
395-static int32_t ea_archive(xar_t x, xar_file_t f, const char* file) {
396+static int32_t ea_archive(xar_t x, xar_file_t f, const char* file, void *context) {
397 	char *buf, *i;
398 	int ret, bufsz;
399 	int32_t retval = 0;
400@@ -231,29 +233,29 @@
401 		ret = getxattr(file, i, NULL, 0, 0, XATTR_NOFOLLOW);
402 		if( ret < 0 )
403 			continue;
404-		Glen = ret;
405-		Gbuf = malloc(Glen);
406-		if( !Gbuf )
407+		DARWINATTR_CONTEXT(context)->len = ret;
408+		DARWINATTR_CONTEXT(context)->buf = malloc(DARWINATTR_CONTEXT(context)->len);
409+		if( !DARWINATTR_CONTEXT(context)->buf )
410 			goto BAIL;
411 
412-		ret = getxattr(file, i, Gbuf, Glen, 0, XATTR_NOFOLLOW);
413+		ret = getxattr(file, i, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW);
414 		if( ret < 0 ) {
415-			free(Gbuf);
416-			Gbuf = NULL;
417-			Glen = 0;
418+			free(DARWINATTR_CONTEXT(context)->buf);
419+			DARWINATTR_CONTEXT(context)->buf = NULL;
420+			DARWINATTR_CONTEXT(context)->len = 0;
421 			continue;
422 		}
423 
424 		memset(tempnam, 0, sizeof(tempnam));
425 		snprintf(tempnam, sizeof(tempnam)-1, "ea/%s", i);
426-		xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read);
427+		xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read, context);
428 	}
429 BAIL:
430 	free(buf);
431 	return retval;
432 }
433 
434-static int32_t ea_extract(xar_t x, xar_file_t f, const char* file) {
435+static int32_t ea_extract(xar_t x, xar_file_t f, const char* file, void *context) {
436 	const char *prop;
437 	xar_iter_t iter;
438 	
439@@ -275,18 +277,18 @@
440 			continue;
441 
442 		len = strtol(opt, NULL, 10);
443-		Gbuf = malloc(len);
444-		if( !Gbuf )
445+		DARWINATTR_CONTEXT(context)->buf = malloc(len);
446+		if( !DARWINATTR_CONTEXT(context)->buf )
447 			return -1;
448-		Glen = len;
449+		DARWINATTR_CONTEXT(context)->len = len;
450 
451-		xar_attrcopy_from_heap(x, f, prop, xar_ea_write);
452+		xar_attrcopy_from_heap(x, f, prop, xar_ea_write, context);
453 
454-		setxattr(file, prop+strlen(XAR_EA_FORK)+1, Gbuf, Glen, 0, XATTR_NOFOLLOW);
455-		free(Gbuf);
456-		Gbuf = NULL;
457-		Glen = 0;
458-		Goff = 0;
459+		setxattr(file, prop+strlen(XAR_EA_FORK)+1, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW);
460+		free(DARWINATTR_CONTEXT(context)->buf);
461+		DARWINATTR_CONTEXT(context)->buf = NULL;
462+		DARWINATTR_CONTEXT(context)->len = 0;
463+		DARWINATTR_CONTEXT(context)->off = 0;
464 	}
465 
466 	return 0;
467@@ -298,7 +300,7 @@
468  * ..namedfork methods rather than via EAs.  This is mainly for 10.3
469  * and earlier support
470  */
471-static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file) {
472+static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file, void *context) {
473 	char rsrcname[4096];
474 	struct stat sb;
475 #ifdef HAVE_GETATTRLIST
476@@ -317,8 +319,8 @@
477 
478 	memset(z, 0, sizeof(z));
479 	if( memcmp(finfo.finderinfo, z, sizeof(finfo.finderinfo)) != 0 ) {
480-		Gfinfo = finfo.finderinfo;
481-		xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read);
482+		DARWINATTR_CONTEXT(context)->finfo = finfo.finderinfo;
483+		xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context);
484 	}
485 #endif /* HAVE_GETATTRLIST */
486 
487@@ -331,12 +333,12 @@
488 	if( sb.st_size == 0 )
489 		return 0;
490 
491-	Fd = open(rsrcname, O_RDONLY, 0);
492-	if( Fd < 0 )
493+	DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDONLY, 0);
494+	if( DARWINATTR_CONTEXT(context)->fd < 0 )
495 		return -1;
496 
497-	xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read);
498-	close(Fd);
499+	xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context);
500+	close(DARWINATTR_CONTEXT(context)->fd);
501 	return 0;
502 }
503 
504@@ -345,7 +347,7 @@
505  * ..namedfork methods rather than via EAs.  This is mainly for 10.3
506  * and earlier support
507  */
508-static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file) {
509+static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file, void *context) {
510 	char rsrcname[4096];
511 #ifdef HAVE_SETATTRLIST
512 	struct attrlist attrs;
513@@ -360,19 +362,19 @@
514 	if( ret != 0 )
515 		return -1;
516 
517-	Gfinfo = (char *)file;
518+	DARWINATTR_CONTEXT(context)->finfo = (char *)file;
519 
520-	xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write);
521+	xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write, context);
522 #endif /* HAVE_SETATTRLIST */
523 	
524 	memset(rsrcname, 0, sizeof(rsrcname));
525 	snprintf(rsrcname, sizeof(rsrcname)-1, "%s/..namedfork/rsrc", file);
526-	Fd = open(rsrcname, O_RDWR|O_TRUNC);
527-	if( Fd < 0 )
528+	DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDWR|O_TRUNC);
529+	if( DARWINATTR_CONTEXT(context)->fd < 0 )
530 		return 0;
531 
532-	xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write);
533-	close(Fd);
534+	xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context);
535+	close(DARWINATTR_CONTEXT(context)->fd);
536 	return 0;
537 }
538 #endif /* __APPLE__ */
539@@ -381,13 +383,13 @@
540  * Check to see if the file we're archiving is a ._ file.  If so,
541  * stop the archival process.
542  */
543-int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file) {
544+int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file, void *context) {
545 	char *bname, *tmp;
546 
547 	tmp = strdup(file);
548 	bname = basename(tmp);
549 
550-	if(bname && (bname[0] == '.') && (bname[1] == '_')) {
551+	if(bname && (bname[0] == '.') && (bname[1] == '_')){
552 		free(tmp);
553 		return 1;
554 	}
555@@ -398,7 +400,7 @@
556 
557 #ifdef __APPLE__
558 /* This only really makes sense on OSX */
559-static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file) {
560+static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file, void *context) {
561 	struct stat sb;
562 	char underbarname[4096], z[32];
563 	char *dname, *bname, *tmp, *tmp2;
564@@ -407,6 +409,9 @@
565 	int num_entries = 0, i, r;
566 	off_t off;
567 
568+	if( !file )
569+		return 0;
570+	
571 	tmp = strdup(file);
572 	tmp2 = strdup(file);
573 	dname = dirname(tmp2);
574@@ -420,13 +425,13 @@
575 	if( stat(underbarname, &sb) != 0 )
576 		return 0;
577 
578-	Fd = open(underbarname, O_RDONLY);
579-	if( Fd < 0 )
580+	DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDONLY);
581+	if( DARWINATTR_CONTEXT(context)->fd < 0 )
582 		return -1;
583 
584 	memset(&ash, 0, sizeof(ash));
585 	memset(&ase, 0, sizeof(ase));
586-	r = read(Fd, &ash, XAR_ASH_SIZE);
587+	r = read(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE);
588 	if( r < XAR_ASH_SIZE )
589 		return -1;
590 
591@@ -440,37 +445,38 @@
592 
593 	for(i = 0; i < num_entries; i++) {
594 		off_t entoff;
595-		r = read(Fd, &ase, sizeof(ase));
596+		r = read(DARWINATTR_CONTEXT(context)->fd, &ase, sizeof(ase));
597 		if( r < sizeof(ase) )
598 			return -1;
599 		off+=r;
600 
601 		if( ntohl(ase.entry_id) == AS_ID_FINDER ) {
602 			entoff = (off_t)ntohl(ase.offset);
603-			if( lseek(Fd, entoff, SEEK_SET) == -1 )
604+			if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 )
605 				return -1;
606-			r = read(Fd, z, sizeof(z));
607+			r = read(DARWINATTR_CONTEXT(context)->fd, z, sizeof(z));
608 			if( r < sizeof(z) )
609 				return -1;
610 			
611-			Gfinfo = z;
612-			xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read);
613-			if( lseek(Fd, (off_t)off, SEEK_SET) == -1 )
614+			DARWINATTR_CONTEXT(context)->finfo = z;
615+			xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context);
616+			if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 )
617 				return -1;
618 		}
619 		if( ntohl(ase.entry_id) == AS_ID_RESOURCE ) {
620 			entoff = (off_t)ntohl(ase.offset);
621-			if( lseek(Fd, entoff, SEEK_SET) == -1 )
622+			if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 )
623 				return -1;
624 
625-			xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read);
626+			xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context);
627 
628-			if( lseek(Fd, (off_t)off, SEEK_SET) == -1 )
629+			if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 )
630 				return -1;
631 		}
632 	}
633 
634-	close(Fd);
635+	close(DARWINATTR_CONTEXT(context)->fd);
636+	DARWINATTR_CONTEXT(context)->fd = 0;
637 	return 0;
638 }
639 #endif
640@@ -479,7 +485,7 @@
641  * Extract finderinfo and resource fork information to an appledouble
642  * ._ file.
643  */
644-static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file) {
645+static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file, void *context) {
646 	char underbarname[4096];
647 	char *dname, *bname, *tmp, *tmp2;
648 	const char *rsrclenstr;
649@@ -510,8 +516,8 @@
650 	free(tmp);
651 	free(tmp2);
652 
653-	Fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0);
654-	if( Fd < 0 )
655+	DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0);
656+	if( DARWINATTR_CONTEXT(context)->fd < 0 )
657 		return -1;
658 
659 	xar_prop_get(f, "ea/com.apple.ResourceFork/size", &rsrclenstr);
660@@ -524,29 +530,31 @@
661 	ash.version = htonl(APPLEDOUBLE_VERSION);
662 	ash.entries = htons(num_entries);
663 
664-	write(Fd, &ash, XAR_ASH_SIZE);
665+	write(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE);
666 
667 	ase.offset = htonl(XAR_ASH_SIZE + ntohs(ash.entries)*12);
668 	if( have_fi ) {
669 		ase.entry_id = htonl(AS_ID_FINDER);
670 		ase.length = htonl(32);
671-		write(Fd, &ase, 12);
672+		write(DARWINATTR_CONTEXT(context)->fd, &ase, 12);
673 	}
674 
675 	if( have_rsrc ) {
676 		ase.entry_id = htonl(AS_ID_RESOURCE);
677 		ase.offset = htonl(ntohl(ase.offset) + ntohl(ase.length));
678 		ase.length = htonl(rsrclen);
679-		write(Fd, &ase, 12);
680+		write(DARWINATTR_CONTEXT(context)->fd, &ase, 12);
681 	}
682 	
683 	if( have_fi )
684-		xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write);
685+		xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write, context);
686 	if( have_rsrc )
687-		xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write);
688-	close(Fd);
689+		xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context);
690+	close(DARWINATTR_CONTEXT(context)->fd);
691 
692-	xar_set_perm(x, f, underbarname);
693+	DARWINATTR_CONTEXT(context)->fd = 0;
694+
695+	xar_set_perm(x, f, underbarname );
696 	
697 	return 0;
698 }
699@@ -554,28 +562,36 @@
700 
701 int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file)
702 {
703+	struct _darwinattr_context context;
704+	
705+	memset(&context,0,sizeof(struct _darwinattr_context));
706+	
707 #if defined(__APPLE__)
708 #if defined(HAVE_GETXATTR)
709-	if( ea_archive(x, f, file) == 0 )
710+	if( ea_archive(x, f, file, (void *)&context) == 0 )
711 		return 0;
712 #endif
713-	if( nonea_archive(x, f, file) == 0 )
714+	if( nonea_archive(x, f, file, (void *)&context) == 0 )
715 		return 0;
716-	return underbar_archive(x, f, file);
717+	return underbar_archive(x, f, file, (void *)&context);
718 #endif /* __APPLE__ */
719 	return 0;
720 }
721 
722 int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file)
723 {
724+	struct _darwinattr_context context;
725+	
726+	memset(&context,0,sizeof(struct _darwinattr_context));
727+	
728 #if defined(__APPLE__)
729 #if defined(HAVE_GETXATTR)
730-	if( ea_extract(x, f, file) == 0 )
731+	if( ea_extract(x, f, file, (void *)&context) == 0 )
732 		return 0;
733 #endif
734 
735-	if( nonea_extract(x, f, file) == 0 )
736+	if( nonea_extract(x, f, file, (void *)&context) == 0 )
737 		return 0;
738 #endif /* __APPLE__ */
739-	return underbar_extract(x, f, file);
740+	return underbar_extract(x, f, file, (void *)&context);
741 }
742diff -urN xar/lib/data.c xar.context/lib/data.c
743--- xar/lib/data.c	2006-02-23 23:05:04.000000000 -0800
744+++ xar.context/lib/data.c	2006-03-17 11:00:28.000000000 -0800
745@@ -18,24 +18,76 @@
746 #define O_EXLOCK 0
747 #endif
748 
749-static int Fd;
750+struct _data_context{
751+	int fd;
752+	void *buffer;
753+	size_t length;
754+	off_t offset;
755+};
756 
757-int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) {
758+#define DATA_CONTEXT(x) ((struct _data_context*)(x))
759+
760+int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) {
761 	int32_t r;
762 
763+	/* read from buffer, rather then fd,if available */
764+	if(DATA_CONTEXT(context)->length){
765+		char *readbuf = (char *)DATA_CONTEXT(context)->buffer;
766+		size_t sizetoread = DATA_CONTEXT(context)->length - DATA_CONTEXT(context)->offset;
767+		
768+		if( !sizetoread){
769+			return 0;
770+		}
771+		
772+		if( sizetoread > bsize ){
773+			sizetoread = bsize;
774+		}
775+		
776+		/* dont read passed the end of the buffer */
777+		if((DATA_CONTEXT(context)->offset + sizetoread) > DATA_CONTEXT(context)->length){
778+			return -1;
779+		}
780+		
781+		readbuf += DATA_CONTEXT(context)->offset;
782+		memcpy(inbuf,readbuf,sizetoread);
783+		
784+		DATA_CONTEXT(context)->offset += sizetoread;
785+		
786+		return sizetoread;
787+	}
788+	
789 	while(1) {
790-		r = read(Fd, inbuf, bsize);
791+		r = read(DATA_CONTEXT(context)->fd, inbuf, bsize);
792 		if( (r < 0) && (errno == EINTR) )
793 			continue;
794 		return r;
795-	}
796+	}		
797+	
798 }
799 
800-int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len) {
801+int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
802 	int32_t r;
803 	size_t off = 0;
804+	
805+	/* read from buffer, rather then fd,if available */
806+	if(DATA_CONTEXT(context)->length){
807+		char *writebuf = (char *)DATA_CONTEXT(context)->buffer;
808+		
809+		/* dont write passed the end of the buffer */
810+		if((DATA_CONTEXT(context)->offset + len) > DATA_CONTEXT(context)->length){
811+			return -1;
812+		}
813+		
814+		writebuf += DATA_CONTEXT(context)->offset;
815+		memcpy(writebuf,buf,len);
816+		
817+		DATA_CONTEXT(context)->offset += len;
818+		
819+		return len;
820+	}
821+	
822 	do {
823-		r = write(Fd, buf+off, len-off);
824+		r = write(DATA_CONTEXT(context)->fd, buf+off, len-off);
825 		if( (r < 0) && (errno != EINTR) )
826 			return r;
827 		off += r;
828@@ -50,6 +102,9 @@
829 int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file) {
830 	const char *opt;
831 	int32_t retval = 0;
832+	struct _data_context context;
833+	
834+	memset(&context,0,sizeof(struct _data_context));
835 
836 	xar_prop_get(f, "type", &opt);
837 	if(!opt) return 0;
838@@ -65,60 +120,68 @@
839 			return 0;
840 	}
841 
842-	Fd = open(file, O_RDONLY);
843-	if( Fd < 0 ) {
844+	context.fd = open(file, O_RDONLY);
845+	if( context.fd < 0 ) {
846 		xar_err_new(x);
847 		xar_err_set_file(x, f);
848 		xar_err_set_string(x, "io: Could not open file");
849 		xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION);
850 		return -1;
851-	}
852+	}		
853 
854-	retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read);
855+	retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read,(void *)(&context));
856 
857-	close(Fd);
858+	if(context.fd > 0)
859+		close(context.fd);
860+	
861 	return retval;
862 }
863 
864 int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file) {
865 	const char *opt;
866-
867-        /* Only regular files are copied in and out of the heap here */
868-        xar_prop_get(f, "type", &opt);
869-        if( !opt ) return 0;
870-        if( strcmp(opt, "file") != 0 ) {
871-                if( strcmp(opt, "hardlink") == 0 ) {
872-                        opt = xar_attr_get(f, "type", "link");
873-                        if( !opt )
874-                                return 0;
875-                        if( strcmp(opt, "original") != 0 )
876-                                return 0; 
877-                        /* else, we're an original hardlink, so keep going */
878-                } else
879-                        return 0;
880-        }
881-
882-        /* mode 600 since other modules may need to operate on the file
883-         * prior to the real permissions being set.
884-         */
885+	struct _data_context context;
886+	
887+	memset(&context,0,sizeof(struct _data_context));
888+	
889+	/* Only regular files are copied in and out of the heap here */
890+	xar_prop_get(f, "type", &opt);
891+	if( !opt ) return 0;
892+	if( strcmp(opt, "file") != 0 ) {
893+		if( strcmp(opt, "hardlink") == 0 ) {
894+			opt = xar_attr_get(f, "type", "link");
895+			if( !opt )
896+				return 0;
897+			if( strcmp(opt, "original") != 0 )
898+				return 0; 
899+			/* else, we're an original hardlink, so keep going */
900+		} else
901+			return 0;
902+	}
903+	
904+	/* mode 600 since other modules may need to operate on the file
905+	* prior to the real permissions being set.
906+	*/
907 TRYAGAIN:
908-        Fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600);
909-        if( Fd < 0 ) {
910+	context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600);
911+	if( context.fd < 0 ) {
912 		if( errno == ENOENT ) {
913 			xar_file_t parent = XAR_FILE(f)->parent;
914 			if( parent && (xar_extract(x, parent) == 0) )
915 				goto TRYAGAIN;
916 		}
917+		
918+		xar_err_new(x);
919+		xar_err_set_file(x, f);
920+		xar_err_set_string(x, "io: Could not create file");
921+		xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
922+		return -1;
923+	}
924 			
925-               	xar_err_new(x);
926-               	xar_err_set_file(x, f);
927-               	xar_err_set_string(x, "io: Could not create file");
928-               	xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
929-               	return -1;
930-        }
931-
932-	xar_attrcopy_from_heap(x, f, "data", xar_data_write);
933-	close(Fd);
934+	xar_attrcopy_from_heap(x, f, "data", xar_data_write, (void *)(&context));
935+	
936+	if( context.fd > 0 )		
937+		close(context.fd);
938+	
939 	return 0;
940 }
941 
942diff -urN xar/lib/fbsdattr.c xar.context/lib/fbsdattr.c
943--- xar/lib/fbsdattr.c	2006-02-17 11:27:10.000000000 -0800
944+++ xar.context/lib/fbsdattr.c	2006-03-17 11:03:08.000000000 -0800
945@@ -57,41 +57,45 @@
946 #endif
947 
948 #ifdef HAVE_SYS_EXTATTR_H
949-static const char *Gfile = NULL;
950-static const char *Gattr = NULL;
951-static void *Gbuf = NULL;
952-static int Goff = 0;
953-static int Gbufsz = 0;
954-static int Gns = 0;
955+struct _fbsdattr_context{
956+	const char *file = NULL;
957+	const char *attr = NULL;
958+	void *buf = NULL;
959+	int off = 0;
960+	int bufsz = 0;
961+	int ns = 0;
962+};
963+
964+#define FBSDATTR_CONTEXT(x) ((struct _fbsdattr_context *)(x))
965 
966 int32_t xar_fbsdattr_read(xar_t x, xar_file_t f, void *buf, size_t len) {
967-	if( !Gbuf ) {
968-		Gbufsz = extattr_get_link(Gfile, Gns, Gattr, NULL, 0);
969-		if( Gbufsz < 0 )
970+	if( !FBSDATTR_CONTEXT(context)->buf ) {
971+		FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, NULL, 0);
972+		if( FBSDATTR_CONTEXT(context)->bufsz < 0 )
973 			return -1;
974-		Gbuf = malloc(Gbufsz);
975-		if( !Gbuf )
976+		FBSDATTR_CONTEXT(context)->buf = malloc(FBSDATTR_CONTEXT(context)->bufsz);
977+		if( !FBSDATTR_CONTEXT(context)->buf )
978 			return -1;
979 
980-		Gbufsz = extattr_get_link(Gfile, Gns, Gattr, Gbuf, Gbufsz);
981+		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);
982 	}
983 
984-	if( (Gbufsz - Goff) <= len ) {
985+	if( (FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off) <= len ) {
986 		int32_t ret;
987 
988-		ret = Gbufsz - Goff;
989-		memcpy(buf, Gbuf+Goff, ret);
990-		Goff += ret;
991+		ret = FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off;
992+		memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, ret);
993+		FBSDATTR_CONTEXT(context)->off += ret;
994 		return(ret);
995 	} else {
996-		memcpy(buf, Gbuf+Goff, len);
997-		Gbuf += len;
998+		memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, len);
999+		FBSDATTR_CONTEXT(context)->buf += len;
1000 		return(len);
1001 	}
1002 
1003 }
1004 int32_t xar_fbsdattr_write(xar_t x, xar_file_t f, void *buf, size_t len) {
1005-	return extattr_set_link(Gfile, Gns, Gattr, buf, len);
1006+	return extattr_set_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, buf, len);
1007 }
1008 #endif
1009 
1010@@ -103,7 +107,10 @@
1011 	struct statfs sfs;
1012 	char *fsname = NULL;
1013 	int namespace = EXTATTR_NAMESPACE_USER;
1014-
1015+	struct _fbsdattr_context context;
1016+	
1017+	memset(&context,0,sizeof(struct _fbsdattr_context));
1018+	
1019 TRYAGAIN:
1020 	/* extattr_list_link()'s man page does not define the return
1021 	 * value.  The kernel source comments say 0 for success, -1 for
1022@@ -174,16 +181,16 @@
1023 		extattr_namespace_to_string(namespace, &ns);
1024 		memset(tempnam, 0, sizeof(tempnam));
1025 		snprintf(tempnam, sizeof(tempnam)-1, "%s/%s.%s", XAR_EA_FORK, ns, key);
1026-		Gns = namespace;
1027-		Gfile = file;
1028-		Gattr = key;
1029+		FBSDATTR_CONTEXT(context).ns = namespace;
1030+		FBSDATTR_CONTEXT(context).file = file;
1031+		FBSDATTR_CONTEXT(context).attr = key;
1032 
1033 		xar_attr_set(f, tempnam, "fstype", fsname);
1034 		xar_attrcopy_to_heap(x, f, tempnam, xar_fbsdattr_read);
1035 
1036-		free(Gbuf);
1037-		Gbuf = NULL;
1038-		Goff = 0;
1039+		free(FBSDATTR_CONTEXT(context).buf);
1040+		FBSDATTR_CONTEXT(context).buf = NULL;
1041+		FBSDATTR_CONTEXT(context).off = 0;
1042 	}
1043 
1044 	if( namespace == EXTATTR_NAMESPACE_USER ) {
1045@@ -200,7 +207,7 @@
1046 #endif
1047 }
1048 
1049-int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file)
1050+int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len)
1051 {
1052 #ifdef HAVE_SYS_EXTATTR_H
1053 	char *fsname = "bogus";
1054@@ -208,7 +215,10 @@
1055 	struct statfs sfs;
1056 	int eaopt = 0;
1057 	xar_iter_t iter;
1058-
1059+	struct _fbsdattr_context context;
1060+	
1061+	memset(&context,0,sizeof(struct _fbsdattr_context));
1062+		
1063 	statfs(file, &sfs);
1064 	fsname = sfs.f_fstypename;
1065 
1066@@ -227,16 +237,16 @@
1067 
1068 		tmp = prop + strlen(XAR_EA_FORK) + 1;
1069 		if( strncmp(tmp, "user.", 5) == 0 ) {
1070-			Gns = EXTATTR_NAMESPACE_USER;
1071-			Gattr = tmp + 5;
1072+			FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_USER;
1073+			FBSDATTR_CONTEXT(context).attr = tmp + 5;
1074 		} else if( strncmp(tmp, "system.", 7) == 0 ) {
1075-			Gns = EXTATTR_NAMESPACE_SYSTEM;
1076-			Gattr = tmp + 7;
1077+			FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_SYSTEM;
1078+			FBSDATTR_CONTEXT(context).attr = tmp + 7;
1079 		} else {
1080 			continue;
1081 		}
1082 
1083-		Gfile = file;
1084+		FBSDATTR_CONTEXT(context).file = file;
1085 		xar_attrcopy_from_heap(x, f, prop, xar_fbsdattr_write);
1086 	}
1087 
1088diff -urN xar/lib/io.c xar.context/lib/io.c
1089--- xar/lib/io.c	2006-02-23 23:05:04.000000000 -0800
1090+++ xar.context/lib/io.c	2006-03-17 11:13:25.000000000 -0800
1091@@ -104,7 +104,9 @@
1092 	}
1093 };
1094 
1095-int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb) {
1096+int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context) {
1097+	int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod));
1098+	void	*modulecontext[modulecount];
1099 	int r, off, i;
1100 	size_t bsize, rsize;
1101 	int64_t readsize=0, writesize=0, inc = 0;
1102@@ -114,6 +116,8 @@
1103 	off_t orig_heap_offset = XAR(x)->heap_offset;
1104 	xar_file_t tmpf = NULL;
1105 
1106+	memset(modulecontext, 0, sizeof(void*)*modulecount);
1107+
1108 	opt = xar_opt_get(x, XAR_OPT_RSIZE);
1109 	if( !opt ) {
1110 		bsize = 4096;
1111@@ -130,7 +134,7 @@
1112 		if( !inbuf )
1113 			return -1;
1114 
1115-		r = rcb(x, f, inbuf, bsize);
1116+		r = rcb(x, f, inbuf, bsize, context);
1117 		if( r < 0 ) {
1118 			free(inbuf);
1119 			return -1;
1120@@ -141,16 +145,16 @@
1121 		rsize = r;
1122 
1123 		/* filter the data through the in modules */
1124-		for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1125+		for( i = 0; i < modulecount; i++) {
1126 			if( xar_datamods[i].th_in ) {
1127-				xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize);
1128+				xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize, &modulecontext[i]);
1129 			}
1130 		}
1131 
1132 		/* filter the data through the out modules */
1133-		for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1134+		for( i = 0; i < modulecount; i++) {
1135 			if( xar_datamods[i].th_out )
1136-				xar_datamods[i].th_out(x, f, attr, inbuf, rsize);
1137+				xar_datamods[i].th_out(x, f, attr, inbuf, rsize, &modulecontext[i]);
1138 		}
1139 
1140 		off = 0;
1141@@ -165,7 +169,7 @@
1142 		}
1143 		XAR(x)->heap_offset += off;
1144 		free(inbuf);
1145-
1146+		
1147 	}
1148 
1149 
1150@@ -173,16 +177,16 @@
1151 	if( readsize == 0 ) {
1152 		XAR(x)->heap_offset = orig_heap_offset;
1153 		lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR);
1154-		for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1155+		for( i = 0; i < modulecount; i++) {
1156 			if( xar_datamods[i].th_done )
1157-				xar_datamods[i].th_done(x, NULL, attr);
1158+				xar_datamods[i].th_done(x, NULL, attr, &modulecontext[i]);
1159 		}
1160 		return 0;
1161 	}
1162 	/* finish up anything that still needs doing */
1163-	for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1164+	for( i = 0; i < modulecount; i++) {
1165 		if( xar_datamods[i].th_done )
1166-			xar_datamods[i].th_done(x, f, attr);
1167+			xar_datamods[i].th_done(x, f, attr, &modulecontext[i]);
1168 	}
1169 
1170 	XAR(x)->heap_len += writesize;
1171@@ -257,7 +261,9 @@
1172  * data from the heap file.
1173  * It is assumed the heap_fd is already positioned appropriately.
1174  */
1175-int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb) {
1176+int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context) {
1177+	int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod));
1178+	void	*modulecontext[modulecount];
1179 	int r, i;
1180 	size_t bsize, def_bsize;
1181 	int64_t fsize, inc = 0, seekoff;
1182@@ -265,6 +271,8 @@
1183 	const char *opt;
1184 	char *tmpstr = NULL;
1185 
1186+	memset(modulecontext, 0, sizeof(void*)*modulecount);
1187+
1188 	opt = xar_opt_get(x, "rsize");
1189 	if( !opt ) {
1190 		def_bsize = 4096;
1191@@ -279,7 +287,7 @@
1192 	xar_prop_get(f, tmpstr, &opt);
1193 	free(tmpstr);
1194 	if( !opt ) {
1195-		wcb(x, f, NULL, 0);
1196+		wcb(x, f, NULL, 0, context);
1197 		return 0;
1198 	} else {
1199 		seekoff = strtoll(opt, NULL, 0);
1200@@ -365,26 +373,30 @@
1201 		bsize = r;
1202 
1203 		/* filter the data through the in modules */
1204-		for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1205+		for( i = 0; i < modulecount; i++) {
1206 			if( xar_datamods[i].fh_in ) {
1207 				int32_t ret;
1208-				ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize);
1209+				ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize, &modulecontext[i]);
1210 				if( ret < 0 )
1211 					return -1;
1212 			}
1213 		}
1214-
1215+		
1216+		/* skip the write phase, if there is no write function to call */
1217+		if(!wcb)
1218+			continue;
1219+		
1220 		/* filter the data through the out modules */
1221-		for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1222+		for( i = 0; i < modulecount; i++) {
1223 			if( xar_datamods[i].fh_out ) {
1224 				int32_t ret;
1225-				ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize);
1226+				ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize, &modulecontext[i]);
1227 				if( ret < 0 )
1228 					return -1;
1229 			}
1230 		}
1231 
1232-		wcb(x, f, inbuf, bsize);
1233+		wcb(x, f, inbuf, bsize, context);
1234 		free(inbuf);
1235 		bsize = def_bsize;
1236 		inbuf = malloc(bsize);
1237@@ -392,10 +404,10 @@
1238 
1239 	free(inbuf);
1240 	/* finish up anything that still needs doing */
1241-	for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) {
1242+	for( i = 0; i < modulecount; i++) {
1243 		if( xar_datamods[i].fh_done ) {
1244 			int32_t ret;
1245-			ret = xar_datamods[i].fh_done(x, f, attr);
1246+			ret = xar_datamods[i].fh_done(x, f, attr, &modulecontext[i]);
1247 			if( ret < 0 )
1248 				return ret;
1249 		}
1250diff -urN xar/lib/io.h xar.context/lib/io.h
1251--- xar/lib/io.h	2006-02-17 11:27:10.000000000 -0800
1252+++ xar.context/lib/io.h	2006-03-17 11:13:52.000000000 -0800
1253@@ -34,16 +34,16 @@
1254 #ifndef _XAR_IO_H_
1255 #define _XAR_IO_H_
1256 
1257-typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t);
1258-typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t);
1259+typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context);
1260+typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context);
1261 
1262-typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen);
1263-typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen);
1264-typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr);
1265-
1266-typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen);
1267-typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen);
1268-typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr);
1269+typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context);
1270+typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context);
1271+typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr, void **context);
1272+
1273+typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context);
1274+typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context);
1275+typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr, void **context);
1276 
1277 struct datamod {
1278 	fromheap_in      fh_in;
1279@@ -54,8 +54,8 @@
1280 	toheap_done      th_done;
1281 };
1282 
1283-int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb);
1284-int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb);
1285+int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context);
1286+int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context);
1287 int32_t xar_heap_to_archive(xar_t x);
1288 
1289 #endif /* _XAR_IO_H_ */
1290diff -urN xar/lib/linuxattr.c xar.context/lib/linuxattr.c
1291--- xar/lib/linuxattr.c	2006-02-23 23:05:04.000000000 -0800
1292+++ xar.context/lib/linuxattr.c	2006-03-17 11:14:35.000000000 -0800
1293@@ -77,49 +77,54 @@
1294 #endif
1295 
1296 #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__)
1297-static const char *Gfile = NULL;
1298-static const char *Gattr = NULL;
1299-static void *Gbuf = NULL;
1300-static int Goff = 0;
1301-static int Gbufsz = 0;
1302 
1303-int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len) {
1304-
1305-	if( !Gbuf ) {
1306+struct _linuxattr_context{
1307+	const char *file;
1308+	const char *attr;
1309+	void *buf;
1310+	int off = 0;
1311+	int bufsz = 0;
1312+};
1313+
1314+#define LINUXATTR_CONTEXT(x) ((struct _linuxattr_context *)(x))
1315+
1316+int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len, void *context) {
1317+	
1318+	if( !LINUXATTR_CONTEXT(context)->buf ) {
1319 		int r;
1320-		Gbufsz = 1024;
1321+		LINUXATTR_CONTEXT(context)->bufsz = 1024;
1322 AGAIN2:
1323-		Gbuf = malloc(Gbufsz);
1324-		if(!Gbuf)
1325+		LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz);
1326+		if(!LINUXATTR_CONTEXT(context)->buf)
1327 			goto AGAIN2;
1328-		memset(Gbuf, 0, Gbufsz);
1329-		r = lgetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, Gbuf, Gbufsz);
1330+		memset(LINUXATTR_CONTEXT(context)->buf, 0, LINUXATTR_CONTEXT(context)->bufsz);
1331+		r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, LINUXATTR_CONTEXT(context)->buf, LINUXATTR_CONTEXT(context)->bufsz);
1332 		if( r < 0 ) {
1333 			switch(errno) {
1334-			case ERANGE: Gbufsz *= 2; free(Gbuf); goto AGAIN2;
1335-			case ENOTSUP: free(Gbuf); return 0;
1336+			case ERANGE: LINUXATTR_CONTEXT(context)->bufsz *= 2; free(LINUXATTR_CONTEXT(context)->buf); goto AGAIN2;
1337+			case ENOTSUP: free(LINUXATTR_CONTEXT(context)->buf); return 0;
1338 			default: break;
1339 			};
1340 			return -1;
1341 		}
1342-		Gbufsz = r;
1343+		LINUXATTR_CONTEXT(context)->bufsz = r;
1344 	}
1345 
1346-	if( (Gbufsz-Goff) <= len ) {
1347+	if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) {
1348 		int32_t ret;
1349-		ret = Gbufsz - Goff;
1350-		memcpy(buf, Gbuf+Goff, ret);
1351-		Goff += ret;
1352+		ret = LINUXATTR_CONTEXT(context)->bufsz - LINUXATTR_CONTEXT(context)->off;
1353+		memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, ret);
1354+		LINUXATTR_CONTEXT(context)->off += ret;
1355 		return(ret);
1356 	} else {
1357-		memcpy(buf, Gbuf+Goff, len);
1358-		Gbuf += len;
1359+		memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, len);
1360+		LINUXATTR_CONTEXT(context)->buf += len;
1361 		return len;
1362 	}
1363 }
1364 
1365-int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len) {
1366-	return lsetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, buf, len, 0);
1367+int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) {
1368+	return lsetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, buf, len, 0);
1369 }
1370 #endif
1371 
1372@@ -130,7 +135,10 @@
1373 	int ret, retval=0, bufsz = 1024;
1374 	struct statfs sfs;
1375 	char *fsname = NULL;
1376-
1377+	struct _linuxattr_context context;
1378+	
1379+	memset(&context,0,sizeof(struct _linuxattr_context));
1380+	
1381 TRYAGAIN:
1382 	buf = malloc(bufsz);
1383 	if(!buf)
1384@@ -159,18 +167,18 @@
1385 	for( i=buf; (i-buf) < ret; i += strlen(i)+1 ) {
1386 		char tmpnam[1024];
1387 
1388-		Gbufsz = 0;
1389-		Goff = 0;
1390-		Gbuf = NULL;
1391-		Gfile = file;
1392+		LINUXATTR_CONTEXT(context)->bufsz = 0;
1393+		LINUXATTR_CONTEXT(context)->off = 0;
1394+		LINUXATTR_CONTEXT(context)->buf = NULL;
1395+		LINUXATTR_CONTEXT(context)->file = file;
1396 		memset(tmpnam, 0, sizeof(tmpnam));
1397 		snprintf(tmpnam, sizeof(tmpnam)-1, "%s/%s", XAR_EA_FORK, i);
1398 		xar_prop_set(f, tmpnam, NULL);
1399 		xar_attr_set(f, tmpnam, "fstype", fsname);
1400-		Gattr = tmpnam;
1401+		LINUXATTR_CONTEXT(context)->attr = tmpnam;
1402 		xar_attrcopy_to_heap(x, f, tmpnam, xar_linuxattr_read);
1403-		free(Gbuf);
1404-		Gattr = NULL;
1405+		free(LINUXATTR_CONTEXT(context)->buf);
1406+		LINUXATTR_CONTEXT(context)->attr = NULL;
1407 	}
1408 
1409 BAIL:
1410@@ -188,8 +196,10 @@
1411 	struct statfs sfs;
1412 	int eaopt = 0;
1413 	xar_iter_t iter;
1414-
1415-
1416+	struct _linuxattr_context context;
1417+	
1418+	memset(&context,0,sizeof(struct _linuxattr_context));
1419+	
1420 	/* Check for EA extraction behavior */
1421 
1422 	memset(&sfs, 0, sizeof(sfs));
1423@@ -223,8 +233,8 @@
1424 		if( !fs )
1425 			continue;
1426 
1427-		Gfile = file;
1428-		Gattr = prop;
1429+		LINUXATTR_CONTEXT(context)->file = file;
1430+		LINUXATTR_CONTEXT(context)->attr = prop;
1431 		xar_attrcopy_from_heap(x, f, prop, xar_linuxattr_write);
1432 
1433 	}
1434diff -urN xar/lib/macho.c xar.context/lib/macho.c
1435--- xar/lib/macho.c	2006-02-23 23:05:04.000000000 -0800
1436+++ xar.context/lib/macho.c	2006-03-17 11:15:23.000000000 -0800
1437@@ -21,14 +21,17 @@
1438 	int32_t offset;
1439 };
1440 
1441-static int initted = 0;
1442-static struct arches *inflight = NULL;
1443-static int32_t numarches = 0;
1444-static int32_t curroffset = 0;
1445+struct _macho_context{
1446+	struct arches *inflight;
1447+	int32_t numarches;
1448+	int32_t curroffset;
1449+};
1450+
1451+#define MACHO_CONTEXT(x) ((struct _macho_context *)(*x))
1452 
1453 static int32_t parse_arch(xar_file_t f, struct mach_header *mh);
1454 
1455-int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
1456+int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
1457 	struct mach_header *mh = *in;
1458 	struct fat_header *fh = *in;
1459 	uint32_t magic;
1460@@ -37,62 +40,69 @@
1461 	if( strcmp(attr, "data") != 0 )
1462 		return 0;
1463 
1464-	if( initted && (inflight != NULL) )
1465-		return 0;
1466-
1467+	if(!MACHO_CONTEXT(context))
1468+		*context = calloc(1,sizeof(struct _macho_context));
1469+	else
1470+		return 0; /*We only run for the first part of the data stream*/
1471+	
1472 	/* First, check for fat */
1473 	magic = htonl(fh->magic);
1474 	if( magic == 0xcafebabe ) {
1475 		struct fat_arch *fa = (struct fat_arch *)((unsigned char *)*in + sizeof(struct fat_header));
1476-		numarches = htonl(fh->nfat_arch);
1477+		MACHO_CONTEXT(context)->numarches = htonl(fh->nfat_arch);
1478 
1479 		/* sanity check, arbitrary number */
1480-		if( numarches > 7 )
1481+		if( MACHO_CONTEXT(context)->numarches > 7 )
1482 			return 0;
1483 
1484 		xar_prop_set(f, "contents/type", "Mach-O Fat File");
1485 
1486-		inflight = malloc( numarches * sizeof(struct arches) );
1487-		if( !inflight )
1488+		MACHO_CONTEXT(context)->inflight = malloc( MACHO_CONTEXT(context)->numarches * sizeof(struct arches) );
1489+		if( !MACHO_CONTEXT(context)->inflight ){
1490+			free(*context);
1491 			return -1;
1492+		}
1493 		
1494-		for( i = 0; i < numarches; ++i ) {
1495+		for( i = 0; i < MACHO_CONTEXT(context)->numarches; ++i ) {
1496 			int32_t sz = htonl(fa[i].size);
1497 			int32_t off = htonl(fa[i].offset);
1498 
1499-			inflight[i].size = sz;
1500-			inflight[i].offset = off;
1501+			MACHO_CONTEXT(context)->inflight[i].size = sz;
1502+			MACHO_CONTEXT(context)->inflight[i].offset = off;
1503 		}
1504-		curroffset += *inlen;
1505+		MACHO_CONTEXT(context)->curroffset += *inlen;
1506 		return 0;
1507 	}
1508 
1509-	if( inflight ) {
1510-		for(i = 0; i < numarches; ++i) {
1511-			if( (inflight[i].offset >= curroffset) && (inflight[i].offset < (curroffset+*inlen)) ) {
1512+	if( MACHO_CONTEXT(context)->inflight ) {
1513+		for(i = 0; i < MACHO_CONTEXT(context)->numarches; ++i) {
1514+			if( (MACHO_CONTEXT(context)->inflight[i].offset >= MACHO_CONTEXT(context)->curroffset) &&
1515+				(MACHO_CONTEXT(context)->inflight[i].offset < (MACHO_CONTEXT(context)->curroffset+*inlen)) ) {
1516 
1517-				mh = (struct mach_header *)((char *)*in + (inflight[i].offset - curroffset));
1518+				mh = (struct mach_header *)((char *)*in + 
1519+											(MACHO_CONTEXT(context)->inflight[i].offset - MACHO_CONTEXT(context)->curroffset));
1520 				parse_arch(f, mh);
1521 			}
1522 		}
1523-		curroffset += *inlen;
1524+		MACHO_CONTEXT(context)->curroffset += *inlen;
1525 		return 0;
1526 	}
1527 
1528 	parse_arch(f, mh);
1529 
1530-	curroffset += *inlen;
1531+	MACHO_CONTEXT(context)->curroffset += *inlen;
1532 
1533 	return 0;
1534 }
1535 
1536-int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr) {
1537-	if( inflight )
1538-		free(inflight);
1539-	inflight = NULL;
1540-	curroffset = 0;
1541-	numarches = 0;
1542-	initted = 0;
1543+int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1544+
1545+	if( MACHO_CONTEXT(context) ){
1546+		if( MACHO_CONTEXT(context)->inflight )
1547+			free(MACHO_CONTEXT(context)->inflight);
1548+		free(*context);
1549+	}
1550+	
1551 	return 0;
1552 }
1553 
1554diff -urN xar/lib/macho.h xar.context/lib/macho.h
1555--- xar/lib/macho.h	2006-02-23 23:05:04.000000000 -0800
1556+++ xar.context/lib/macho.h	2006-03-17 11:15:27.000000000 -0800
1557@@ -31,7 +31,7 @@
1558 	uint32_t alighn;
1559 };
1560 
1561-int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen);
1562-int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr);
1563+int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context);
1564+int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context);
1565 
1566 #endif /* _MACHO_H_ */
1567diff -urN xar/lib/md5.c xar.context/lib/md5.c
1568--- xar/lib/md5.c	2006-02-23 23:05:04.000000000 -0800
1569+++ xar.context/lib/md5.c	2006-03-17 11:38:29.000000000 -0800
1570@@ -11,77 +11,112 @@
1571 #endif
1572 #include "xar.h"
1573 
1574-static EVP_MD_CTX src_ctx, dst_ctx;
1575-static int initted = 0;
1576+struct _md5_context{
1577+	EVP_MD_CTX src_ctx;
1578+	EVP_MD_CTX dst_ctx;
1579+	uint8_t	src;
1580+	uint8_t dst;
1581+};
1582+
1583+#define CONTEXT(x) ((struct _md5_context *)(*x))
1584 
1585 static char* xar_format_md5(const unsigned char* m);
1586 
1587-int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
1588+int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
1589 	const EVP_MD *md;
1590-
1591-	if( !initted ) {
1592+	
1593+	if(!context)
1594+		return 0;
1595+		
1596+	if(!CONTEXT(context)){
1597+		*context = calloc(1,sizeof(struct _md5_context));
1598 		OpenSSL_add_all_digests();
1599+	}
1600+	
1601+	if( !CONTEXT(context)->src ){
1602 		md = EVP_get_digestbyname("md5");
1603 		if( md == NULL ) return -1;
1604-		EVP_DigestInit(&src_ctx, md);
1605-		EVP_DigestInit(&dst_ctx, md);
1606-		initted = 1;
1607+		EVP_DigestInit(&(CONTEXT(context)->src_ctx), md);
1608+		CONTEXT(context)->src = 1;		
1609 	}
1610-
1611+	
1612 	if( *inlen == 0 )
1613 		return 0;
1614-
1615-	EVP_DigestUpdate(&src_ctx, *in, *inlen);
1616+	
1617+	EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), *in, *inlen);
1618 	return 0;
1619 }
1620 
1621-int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen) {
1622+int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context) {
1623 	const EVP_MD *md;
1624-
1625-	if( !initted ) {
1626+	
1627+	if(!context)
1628+		return 0;
1629+	
1630+	if(!CONTEXT(context)){
1631+		*context = calloc(1,sizeof(struct _md5_context));
1632 		OpenSSL_add_all_digests();
1633+	}
1634+	
1635+	if( !CONTEXT(context)->dst ){
1636 		md = EVP_get_digestbyname("md5");
1637 		if( md == NULL ) return -1;
1638-		EVP_DigestInit(&src_ctx, md);
1639-		EVP_DigestInit(&dst_ctx, md);
1640-		initted = 1;
1641+		EVP_DigestInit(&(CONTEXT(context)->dst_ctx), md);
1642+		CONTEXT(context)->dst = 1;		
1643 	}
1644-
1645+	
1646 	if( inlen == 0 )
1647 		return 0;
1648-
1649-	EVP_DigestUpdate(&dst_ctx, in, inlen);
1650+	
1651+	EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), in, inlen);
1652 	return 0;
1653 }
1654 
1655-int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr) {
1656+int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1657 	unsigned char md5str[EVP_MAX_MD_SIZE];
1658 	char *str, *tmpstr;
1659 	unsigned int len;
1660-
1661-	memset(md5str, 0, sizeof(md5str));
1662-	EVP_DigestFinal(&src_ctx, md5str, &len);
1663-	str = xar_format_md5(md5str);
1664-	asprintf(&tmpstr, "%s/extracted-checksum", attr);
1665-	if( f ) {
1666-		xar_prop_set(f, tmpstr, str);
1667-		xar_attr_set(f, tmpstr, "style", "md5");
1668+	
1669+	if(!CONTEXT(context))
1670+		return 0;
1671+	
1672+	if( CONTEXT(context)->src ){
1673+		EVP_MD_CTX		*ctx = &CONTEXT(context)->src_ctx;
1674+		const EVP_MD			*md = EVP_MD_CTX_md(ctx);
1675+		
1676+		memset(md5str, 0, sizeof(md5str));
1677+		EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len);
1678+		str = xar_format_md5(md5str);
1679+		asprintf(&tmpstr, "%s/extracted-checksum", attr);
1680+		if( f ) {
1681+			xar_prop_set(f, tmpstr, str);
1682+			xar_attr_set(f, tmpstr, "style", "md5");
1683+		}
1684+		free(tmpstr);
1685+		free(str);		
1686 	}
1687-	free(tmpstr);
1688-	free(str);
1689-
1690-	memset(md5str, 0, sizeof(md5str));
1691-	EVP_DigestFinal(&dst_ctx, md5str, &len);
1692-	str = xar_format_md5(md5str);
1693-	asprintf(&tmpstr, "%s/archived-checksum", attr);
1694-	if( f ) {
1695-		xar_prop_set(f, tmpstr, str);
1696-		xar_attr_set(f, tmpstr, "style", "md5");
1697+	
1698+	if( CONTEXT(context)->dst ){
1699+		EVP_MD_CTX				*ctx = &CONTEXT(context)->dst_ctx;
1700+		const EVP_MD			*md = EVP_MD_CTX_md(ctx);
1701+		
1702+		memset(md5str, 0, sizeof(md5str));
1703+		EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len);
1704+		str = xar_format_md5(md5str);
1705+		asprintf(&tmpstr, "%s/archived-checksum", attr);
1706+		if( f ) {
1707+			xar_prop_set(f, tmpstr, str);
1708+			xar_attr_set(f, tmpstr, "style", "md5");
1709+		}
1710+		free(tmpstr);
1711+		free(str);
1712 	}
1713-	free(tmpstr);
1714-	free(str);
1715-
1716-	initted = 0;
1717+	
1718+	if(*context){
1719+		free(*context);
1720+		*context = NULL;		
1721+	}
1722+	
1723 	return 0;
1724 }
1725 
1726@@ -99,33 +134,46 @@
1727 	return result;
1728 }
1729 
1730-int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr) {
1731+int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1732 	const char *uncomp, *uncompstyle;
1733 	unsigned char md5str[EVP_MAX_MD_SIZE];
1734 	unsigned int len;
1735 	char *tmpstr;
1736-
1737+	
1738+	if(!CONTEXT(context))
1739+		return 0;
1740+	
1741+	if( !(CONTEXT(context)->dst || CONTEXT(context)->src) ){
1742+		return 0;
1743+	}
1744+	
1745 	asprintf(&tmpstr, "%s/extracted-checksum", attr);
1746 	xar_prop_get(f, tmpstr, &uncomp);
1747 	uncompstyle = xar_attr_get(f, tmpstr, "style");
1748 	free(tmpstr);
1749-
1750-	if( uncomp && uncompstyle && (strcmp(uncompstyle, "md5")==0) ) {
1751+		
1752+	if( uncomp && uncompstyle && CONTEXT(context)->dst ) {
1753 		char *str;
1754 		memset(md5str, 0, sizeof(md5str));
1755-		EVP_DigestFinal(&dst_ctx, md5str, &len);
1756+		EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len);
1757 		str = xar_format_md5(md5str);
1758 		if(strcmp(uncomp, str) != 0) {
1759 			xar_err_new(x);
1760 			xar_err_set_file(x, f);
1761-			xar_err_set_string(x, "extracted-checksum MD5's do not match");
1762+			asprintf(&tmpstr, "extracted-checksum MD5's do not match");
1763 			xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION);
1764 		}
1765 		free(str);
1766 	}
1767-
1768-	EVP_DigestFinal(&src_ctx, md5str, &len);
1769-	initted = 0;
1770-
1771+	
1772+	if( CONTEXT(context)->src )
1773+	    EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len);
1774+	
1775+	if(*context){
1776+		free(*context);
1777+		*context = NULL;
1778+	}
1779+	
1780 	return 0;
1781+	
1782 }
1783diff -urN xar/lib/md5.h xar.context/lib/md5.h
1784--- xar/lib/md5.h	2006-02-17 11:27:10.000000000 -0800
1785+++ xar.context/lib/md5.h	2006-03-17 11:32:14.000000000 -0800
1786@@ -34,9 +34,9 @@
1787 #ifndef _XAR_MD5_H_
1788 #define _XAR_MD5_H_
1789 
1790-int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen);
1791-int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen);
1792-int32_t xar_md5_done(xar_t x, xar_file_t f, const char *);
1793-int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *);
1794+int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen, void **context);
1795+int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context);
1796+int32_t xar_md5_done(xar_t x, xar_file_t f, const char *, void **context);
1797+int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *, void **context);
1798 
1799 #endif /* _XAR_MD5_H_ */
1800diff -urN xar/lib/script.c xar.context/lib/script.c
1801--- xar/lib/script.c	2006-02-23 23:05:04.000000000 -0800
1802+++ xar.context/lib/script.c	2006-03-17 11:15:45.000000000 -0800
1803@@ -9,14 +9,25 @@
1804 #endif
1805 #include "xar.h"
1806 
1807-static int initted = 0;
1808+struct _script_context{
1809+	int initted;
1810+};
1811 
1812-int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
1813+#define SCRIPT_CONTEXT(x) ((struct _script_context*)(*x))
1814+
1815+int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
1816 	char *buf = *in;
1817 
1818-	if( initted )
1819+	if(!SCRIPT_CONTEXT(context)){
1820+		*context = calloc(1,sizeof(struct _script_context));
1821+	}
1822+
1823+	if( SCRIPT_CONTEXT(context)->initted )
1824 		return 0;
1825 
1826+	/*We only run on the begining of the file, so once we init, we don't run again*/
1827+	SCRIPT_CONTEXT(context)->initted = 1;
1828+	
1829 	if( (*inlen > 2) && (buf[0] == '#') && (buf[1] == '!') ) {
1830 		char *exe;
1831 		int i;
1832@@ -37,7 +48,16 @@
1833 	return 0;
1834 }
1835 
1836-int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr) {
1837-	initted = 0;
1838+int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1839+
1840+	if(!SCRIPT_CONTEXT(context)){
1841+		return 0;
1842+	}
1843+		
1844+	if( *context ){
1845+		free(*context);
1846+		*context = NULL;
1847+	}
1848+
1849 	return 0;
1850 }
1851diff -urN xar/lib/script.h xar.context/lib/script.h
1852--- xar/lib/script.h	2006-02-23 23:05:04.000000000 -0800
1853+++ xar.context/lib/script.h	2006-03-17 11:15:48.000000000 -0800
1854@@ -1,7 +1,7 @@
1855 #ifndef _SCRIPT_H_
1856 #define _SCRIPT_H_
1857 
1858-int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen);
1859-int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr);
1860+int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context);
1861+int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context);
1862 
1863 #endif /* _SCRIPT_H_ */
1864diff -urN xar/lib/zxar.c xar.context/lib/zxar.c
1865--- xar/lib/zxar.c	2006-02-17 11:27:10.000000000 -0800
1866+++ xar.context/lib/zxar.c	2006-03-17 11:16:23.000000000 -0800
1867@@ -44,12 +44,10 @@
1868 #include "filetree.h"
1869 #include "io.h"
1870 
1871-static int initted = 0;
1872-static z_stream zs;
1873+#define GZIP_CONTEXT(x) ((z_stream *)(*x))
1874+int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context);
1875 
1876-int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr);
1877-
1878-int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
1879+int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
1880 	const char *opt;
1881 	void *out = NULL;
1882 	size_t outlen, offset = 0;
1883@@ -62,31 +60,27 @@
1884 	if( !opt ) return 0;
1885 	if( strcmp(opt, "application/x-gzip") != 0 ) return 0;
1886 
1887-	if( !initted ) {
1888-		zs.zalloc = Z_NULL;
1889-		zs.zfree = Z_NULL;
1890-		zs.opaque = Z_NULL;
1891-
1892-		inflateInit(&zs);
1893-		initted = 1;
1894+	if( !GZIP_CONTEXT(context) ) {
1895+		*context = calloc(1,sizeof(z_stream));
1896+		inflateInit(GZIP_CONTEXT(context));
1897 	}
1898 
1899 	outlen = *inlen;
1900 
1901-	zs.next_in = *in;
1902-	zs.avail_in = *inlen;
1903-	zs.next_out = out;
1904-	zs.avail_out = 0;
1905+	GZIP_CONTEXT(context)->next_in = *in;
1906+	GZIP_CONTEXT(context)->avail_in = *inlen;
1907+	GZIP_CONTEXT(context)->next_out = out;
1908+	GZIP_CONTEXT(context)->avail_out = 0;
1909 
1910-	while( zs.avail_in != 0 ) {
1911+	while( GZIP_CONTEXT(context)->avail_in != 0 ) {
1912 		outlen = outlen * 2;
1913 		out = realloc(out, outlen);
1914 		if( out == NULL ) abort();
1915 
1916-		zs.next_out = out + offset;
1917-		zs.avail_out = outlen - offset;
1918+		GZIP_CONTEXT(context)->next_out = out + offset;
1919+		GZIP_CONTEXT(context)->avail_out = outlen - offset;
1920 
1921-		r = inflate(&zs, Z_SYNC_FLUSH);
1922+		r = inflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH);
1923 		if( (r != Z_OK) && (r != Z_STREAM_END) ) {
1924 			xar_err_new(x);
1925 			xar_err_set_file(x, f);
1926@@ -94,11 +88,11 @@
1927 			xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION);
1928 			return -1;
1929 		}
1930-		offset += outlen - offset - zs.avail_out;
1931+		offset += outlen - offset - GZIP_CONTEXT(context)->avail_out;
1932 		if( (r == Z_STREAM_END) && (offset == 0) ) {
1933-			//r = inflate(&zs, Z_FINISH);
1934-			xar_gzip_fromheap_done(x, f, attr);
1935-			offset += outlen - offset - zs.avail_out;
1936+			//r = inflate(GZIP_CONTEXT(context), Z_FINISH);
1937+			xar_gzip_fromheap_done(x, f, attr, context);
1938+			offset += outlen - offset - GZIP_CONTEXT(context)->avail_out;
1939 			break;
1940 		}
1941 	}
1942@@ -109,12 +103,17 @@
1943 	return 0;
1944 }
1945 
1946-int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) {
1947-	initted = 0;
1948-	inflateEnd(&zs);
1949+int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1950+	inflateEnd(GZIP_CONTEXT(context));
1951+	
1952+	if(GZIP_CONTEXT(context)){
1953+		free(GZIP_CONTEXT(context));
1954+		*context = NULL;
1955+	}
1956+	
1957 	return 0;
1958 }
1959-int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr) {
1960+int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) {
1961 	const char *opt;
1962 	char *tmpstr;
1963 
1964@@ -124,10 +123,14 @@
1965 
1966 	if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 )
1967 		return 0;
1968+	
1969+	deflateEnd(GZIP_CONTEXT(context));
1970 
1971-	initted = 0;
1972-	deflateEnd(&zs);
1973-
1974+	if(GZIP_CONTEXT(context)){
1975+		free(GZIP_CONTEXT(context));
1976+		*context = NULL;
1977+	}
1978+	
1979 	asprintf(&tmpstr, "%s/encoding", attr);
1980 	if( f ) {
1981 		xar_prop_set(f, tmpstr, NULL);
1982@@ -138,7 +141,7 @@
1983 	return 0;
1984 }
1985 
1986-int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) {
1987+int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) {
1988 	void *out = NULL;
1989 	size_t outlen, offset = 0;
1990 	int r;
1991@@ -151,33 +154,32 @@
1992 	if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 )
1993 		return 0;
1994 
1995-	if( !initted ) {
1996-		memset(&zs, 0, sizeof(zs));
1997-		deflateInit(&zs, Z_BEST_COMPRESSION);
1998-		initted = 1;
1999+	if( !GZIP_CONTEXT(context) ) {
2000+		*context = calloc(1,sizeof(z_stream));
2001+		deflateInit(GZIP_CONTEXT(context), Z_BEST_COMPRESSION);
2002 	}
2003-
2004+	
2005 	outlen = *inlen/2;
2006 	if(outlen == 0) outlen = 1024;
2007-	zs.next_in = *in;
2008-	zs.avail_in = *inlen;
2009-	zs.next_out = out;
2010-	zs.avail_out = 0;
2011+	GZIP_CONTEXT(context)->next_in = *in;
2012+	GZIP_CONTEXT(context)->avail_in = *inlen;
2013+	GZIP_CONTEXT(context)->next_out = out;
2014+	GZIP_CONTEXT(context)->avail_out = 0;
2015 
2016 	do {
2017 		outlen *= 2;
2018 		out = realloc(out, outlen);
2019 		if( out == NULL ) abort();
2020 
2021-		zs.next_out = out + offset;
2022-		zs.avail_out = outlen - offset;
2023+		GZIP_CONTEXT(context)->next_out = out + offset;
2024+		GZIP_CONTEXT(context)->avail_out = outlen - offset;
2025 
2026 		if( *inlen == 0 )
2027-			r = deflate(&zs, Z_FINISH);
2028+			r = deflate(GZIP_CONTEXT(context), Z_FINISH);
2029 		else
2030-			r = deflate(&zs, Z_SYNC_FLUSH);
2031-		offset = outlen - zs.avail_out;
2032-	} while( zs.avail_in != 0 );
2033+			r = deflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH);
2034+		offset = outlen - GZIP_CONTEXT(context)->avail_out;
2035+	} while( GZIP_CONTEXT(context)->avail_in != 0 );
2036 
2037 	free(*in);
2038 	*in = out;
2039diff -urN xar/lib/zxar.h xar.context/lib/zxar.h
2040--- xar/lib/zxar.h	2006-02-17 11:27:10.000000000 -0800
2041+++ xar.context/lib/zxar.h	2006-03-17 11:16:27.000000000 -0800
2042@@ -34,10 +34,10 @@
2043 #ifndef _XAR_ZLIB_H_
2044 #define _XAR_ZLIB_H_
2045 
2046-int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen);
2047-int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *);
2048+int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context);
2049+int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context);
2050 
2051-int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen);
2052-int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *);
2053+int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context);
2054+int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context);
2055 
2056 #endif /* _XAR_ZLIB_H_ */
2057