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