pax_global_header00006660000000000000000000000064144663327530014527gustar00rootroot0000000000000052 comment=eaeb03d085970f94938dc6785cd86d22eaa54b47 xar-xar-498/000077500000000000000000000000001446633275300127775ustar00rootroot00000000000000xar-xar-498/README000066400000000000000000000012141446633275300136550ustar00rootroot00000000000000######################################################################################### # Project Created by Christopher Ryan (ryanc@apple.com) # # Sources based on tot as of 7/12/06 # # cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/Volumes/src/cvs/od co -P xar # # # # Patched folder, included in the project contain some # # patches on the original project xar-1.4.tar.gz. This # # project was created because creating changes ontop of # # the original open source project has become a serious # # hassle. # ######################################################################################### xar-xar-498/Revision.plist000066400000000000000000000000731446633275300156520ustar00rootroot00000000000000bplist00ÑXrevisionS185 xar-xar-498/patches/000077500000000000000000000000001446633275300144265ustar00rootroot00000000000000xar-xar-498/patches/appleadditions.diff000066400000000000000000001117361446633275300202710ustar00rootroot00000000000000diff -urN xar.hash/include/xar.h.in xar.final/include/xar.h.in --- xar.hash/include/xar.h.in 2006-03-17 13:36:32.000000000 -0800 +++ xar.final/include/xar.h.in 2006-03-17 10:35:14.000000000 -0800 @@ -101,8 +101,20 @@ xar_t xar_open(const char *file, int32_t flags); int xar_close(xar_t x); xar_file_t xar_add(xar_t x, const char *path); + +xar_file_t xar_add_frombuffer(xar_t x, xar_file_t parent, const char *name, char *buffer, size_t length); +xar_file_t xar_add_folder(xar_t x, xar_file_t f, const char *name, struct stat *info); +xar_file_t xar_add_frompath(xar_t x, xar_file_t parent, const char *name, const char *realpath); + +xar_file_t xar_add_from_archive(xar_t x, xar_file_t parent, const char *name, xar_t sourcearchive, xar_file_t sourcefile); + int32_t xar_extract(xar_t x, xar_file_t f); int32_t xar_extract_tofile(xar_t x, xar_file_t f, const char *path); +int32_t xar_extract_tobuffer(xar_t x, xar_file_t f, char **buffer); + +int32_t xar_verify(xar_t x, xar_file_t f); + + const char *xar_opt_get(xar_t x, const char *option); int32_t xar_opt_set(xar_t x, const char *option, const char *value); @@ -148,6 +160,7 @@ int32_t xar_err_callback(xar_t x, int32_t sev, int32_t err); char *xar_get_path(xar_file_t f); +off_t xar_get_heap_offset(xar_t x); uint64_t xar_ntoh64(uint64_t num); #endif /* _XAR_H_ */ diff -urN xar.hash/lib/archive.c xar.final/lib/archive.c --- xar.hash/lib/archive.c 2006-03-17 11:25:05.000000000 -0800 +++ xar.final/lib/archive.c 2006-03-17 10:35:14.000000000 -0800 @@ -217,6 +217,7 @@ XAR(ret)->heap_len += 20; xar_opt_set(ret, XAR_OPT_COMPRESSION, XAR_OPT_VAL_GZIP); + xar_opt_set(ret, XAR_OPT_FILECKSUM, XAR_OPT_VAL_SHA1); } else { unsigned char toccksum[EVP_MAX_MD_SIZE]; unsigned char cval[EVP_MAX_MD_SIZE]; @@ -455,6 +456,7 @@ if( XAR(x)->docksum ) { unsigned int l = r; + memset(chkstr, 0, sizeof(chkstr)); EVP_DigestFinal(&XAR(x)->toc_ctx, chkstr, &l); r = l; @@ -588,19 +590,25 @@ * x: archive the file should belong to * f: parent node, possibly NULL * name: name of the node to add + * realpath: real path to item, this is used if the item being archived is to be located at a different location in the tree + * then it is on the real filesystem. * Returns: newly allocated and populated node * Summary: helper function which adds a child of f and populates * its properties. If f is NULL, the node will be added as a top * level node of the archive, x. */ -static xar_file_t xar_add_node(xar_t x, xar_file_t f, const char *name, const char *prefix, int srcpath) { +static xar_file_t xar_add_node(xar_t x, xar_file_t f, const char *name, const char *prefix, const char *realpath, int srcpath) { xar_file_t ret; const char *path; char *tmp; char idstr[32]; if( !f ) { - asprintf(&tmp, "%s%s%s", XAR(x)->path_prefix, prefix, name); + if( realpath ) + asprintf(&tmp, "%s", realpath); + else + asprintf(&tmp, "%s%s%s", XAR(x)->path_prefix, prefix, name); + if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; @@ -631,7 +639,12 @@ } } - asprintf(&tmp, "%s/%s%s", path, prefix, name); + + if( realpath ){ + asprintf(&tmp, "%s", realpath); + }else + asprintf(&tmp, "%s/%s%s", path, prefix, name); + if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; @@ -648,7 +661,7 @@ xar_prop_set(ret, "name", name); - if( xar_arcmod_archive(x, ret, XAR_FILE(ret)->fspath) < 0 ) { + if( xar_arcmod_archive(x, ret, XAR_FILE(ret)->fspath, NULL, 0) < 0 ) { xar_file_t i; if( f ) { for( i = XAR_FILE(f)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); @@ -736,9 +749,9 @@ /* tmp3 was not found in children of start, so we add it */ if( tmp2 ) { - ret = xar_add_node(x, f, tmp3, prefix, 1); + ret = xar_add_node(x, f, tmp3, prefix, NULL, 1); } else { - ret = xar_add_node(x, f, tmp3, prefix, 0); + ret = xar_add_node(x, f, tmp3, prefix, NULL, 0); } if( !ret ) { @@ -783,18 +796,209 @@ return xar_add_r(x, NULL, path, ""); } +/* xar_add_frombuffer +* x: archive to add the file to +* parent: parent node, possibly NULL +* name: name of file +* buffer: buffer for file contents +* length: length of buffer +* Returns: allocated an populated xar_file_t representing the +* specified file. +* Summary: Use this to add chunks of named data to a xar without +* using the filesystem. +*/ + +xar_file_t xar_add_frombuffer(xar_t x, xar_file_t parent, const char *name, char *buffer, size_t length) { + xar_file_t ret; + char *tmp; + char idstr[32]; + + if( !parent ) { + ret = xar_file_new(NULL); + if( !ret ) + return NULL; + memset(idstr, 0, sizeof(idstr)); + snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); + xar_attr_set(ret, NULL, "id", idstr); + XAR_FILE(ret)->parent = NULL; + if( XAR(x)->files == NULL ) + XAR(x)->files = ret; + else { + XAR_FILE(ret)->next = XAR(x)->files; + XAR(x)->files = ret; + } + } else { + ret = xar_file_new(parent); + if( !ret ) + return NULL; + memset(idstr, 0, sizeof(idstr)); + snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); + xar_attr_set(ret, NULL, "id", idstr); + XAR_FILE(ret)->fspath = tmp; + } + + xar_prop_set(ret, "name", name); + + //int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) + if( xar_arcmod_archive(x, ret, NULL , buffer , length) < 0 ) { + xar_file_t i; + if( parent ) { + for( i = XAR_FILE(parent)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); + } else { + for( i = XAR(x)->files; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); + } + if( i ) + XAR_FILE(i)->next = XAR_FILE(ret)->next; + xar_file_free(ret); + return NULL; + } + + return ret; +} + +xar_file_t xar_add_folder(xar_t x, xar_file_t f, const char *name, struct stat *info) +{ + xar_file_t ret; + char idstr[32]; + + if( info ) + memcpy(&XAR(x)->sbcache,info,sizeof(struct stat)); + + ret = xar_file_new(f); + if( !ret ) + return NULL; + + memset(idstr, 0, sizeof(idstr)); + snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); + xar_attr_set(ret, NULL, "id", idstr); + XAR_FILE(ret)->fspath = NULL; + + if( !f ) { + XAR_FILE(ret)->parent = NULL; + + if( XAR(x)->files == NULL ) + XAR(x)->files = ret; + else { + XAR_FILE(ret)->next = XAR(x)->files; + XAR(x)->files = ret; + } + } + + xar_prop_set(ret, "name", name); + + if( xar_arcmod_archive(x, ret, XAR_FILE(ret)->fspath, NULL, 0) < 0 ) { + xar_file_t i; + if( f ) { + for( i = XAR_FILE(f)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); + } else { + for( i = XAR(x)->files; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); + } + if( i ) + XAR_FILE(i)->next = XAR_FILE(ret)->next; + xar_file_free(ret); + return NULL; + } + + return ret; +} + +xar_file_t xar_add_frompath(xar_t x, xar_file_t parent, const char *name, const char *realpath) +{ + return xar_add_node(x, parent, name , "" , realpath, 1); +} + +xar_file_t xar_add_from_archive(xar_t x, xar_file_t parent, const char *name, xar_t sourcearchive, xar_file_t sourcefile) +{ + xar_file_t ret; + char idstr[32]; + + ret = xar_file_replicate(sourcefile, parent); + + if( !ret ) + return NULL; + + memset(idstr, 0, sizeof(idstr)); + snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); + xar_attr_set(ret, NULL, "id", idstr); + XAR_FILE(ret)->fspath = NULL; + + if( !parent ) { + XAR_FILE(ret)->parent = NULL; + + if( XAR(x)->files == NULL ) + XAR(x)->files = ret; + else { + XAR_FILE(ret)->next = XAR(x)->files; + XAR(x)->files = ret; + } + } + + xar_prop_set(ret, "name", name); + + /* iterate through all the properties, see if any of them have an offset */ + xar_iter_t iter = xar_iter_new(); + const char *attr = xar_prop_first(ret , iter); + char *tmpstr = NULL; + + do{ + asprintf(&tmpstr, "%s/offset", attr); + if(0 == xar_prop_get(ret, tmpstr, NULL) ){ + if( 0 != xar_attrcopy_from_heap_to_heap(sourcearchive, sourcefile, attr, x, ret)){ + xar_file_free(ret); + ret = NULL; + break; + } + } + free(tmpstr); + + }while( (attr = xar_prop_next(iter)) ); + + xar_iter_free(iter); + + return ret; +} + /* xar_extract_tofile - * x: archive to extract from - * f: file associated with x - * Returns 0 on success, -1 on failure - * Summary: This actually does the file extraction. - * No traversal is performed, it is assumed all directory paths - * leading up to f already exist. - */ +* x: archive to extract from +* f: file associated with x +* Returns 0 on success, -1 on failure +* Summary: This actually does the file extraction. +* No traversal is performed, it is assumed all directory paths +* leading up to f already exist. +*/ int32_t xar_extract_tofile(xar_t x, xar_file_t f, const char *path) { - return xar_arcmod_extract(x, f, path); + return xar_arcmod_extract(x, f, path,NULL, 0); } + +/* xar_extract_tobuffer +* x: archive to extract from +* buffer: buffer to extract to +* Returns 0 on success, -1 on failure. +* Summary: This is the entry point for extraction to a buffer. +* On success, a buffer is allocated with the contents of the file +* specified. The caller is responsible for freeing the returend buffer. +* Example: xar_extract_tobuffer(x, "foo/bar/blah",&buffer) +*/ +int32_t xar_extract_tobuffer(xar_t x, xar_file_t f, char **buffer) { + size_t size; + const char *sizestring = NULL; + + if(0 != xar_prop_get(f,"data/size",&sizestring)){ + return -1; + } + + size = strtoull(sizestring, (char **)NULL, 10); + *buffer = malloc(size); + + if(!(*buffer)){ + return -1; + } + + return xar_arcmod_extract(x,f,NULL,*buffer,size); +} + + /* xar_extract * x: archive to extract from * path: path to file to extract @@ -828,6 +1032,18 @@ return xar_extract_tofile(x, f, XAR_FILE(f)->fspath); } +/* xar_extract +* x: archive to extract from +* f: file to verify +* Returns 0 on success, -1 on failure. +* Summary: This function allows for verification of +* an entry without extraction. If there is no checksum +* the verification will pass. +*/ +int32_t xar_verify(xar_t x, xar_file_t f) { + return xar_arcmod_verify(x,f); +} + /* read_callback * context: context passed through from the reader * buffer: buffer to read into diff -urN xar.hash/lib/archive.h xar.final/lib/archive.h --- xar.hash/lib/archive.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/archive.h 2006-03-17 10:35:14.000000000 -0800 @@ -55,28 +55,28 @@ const char *ns; const char *filler1; const char *filler2; - xar_file_t files; /* file forest */ - const char *filename; /* name of the archive we are operating on */ - char *dirname; /* directory of the archive, used in creation */ - int fd; /* open file descriptor for the archive */ - int heap_fd; /* fd for tmp heap archive, used in creation */ - off_t heap_offset; /* current offset within the heap */ - off_t heap_len; /* current length of the heap */ - xar_header_t header; /* header of the xar archive */ - void *readbuf; /* buffer for reading/writing compressed toc */ - size_t readbuf_len; /* length of readbuf */ - size_t offset; /* offset into readbuf for keeping track - * between callbacks. */ - size_t toc_count; /* current bytes read of the toc */ - z_stream zs; /* gz state for compressing/decompressing toc */ - char *path_prefix; /* used for distinguishing absolute paths */ - err_handler ercallback; /* callback for errors/warnings */ - struct errctx errctx; /* error callback context */ - xar_subdoc_t subdocs; /* linked list of subdocs */ - uint64_t last_fileid; /* unique fileid's in the archive */ - xmlHashTablePtr ino_hash;/* Hash for looking up hardlinked files (add)*/ - xmlHashTablePtr link_hash;/* Hash for looking up hardlinked files (extract)*/ - xmlHashTablePtr csum_hash;/* Hash for looking up checksums of files */ + xar_file_t files; /* file forest */ + const char *filename; /* name of the archive we are operating on */ + char *dirname; /* directory of the archive, used in creation */ + int fd; /* open file descriptor for the archive */ + int heap_fd; /* fd for tmp heap archive, used in creation */ + off_t heap_offset; /* current offset within the heap */ + off_t heap_len; /* current length of the heap */ + xar_header_t header; /* header of the xar archive */ + void *readbuf; /* buffer for reading/writing compressed toc */ + size_t readbuf_len; /* length of readbuf */ + size_t offset; /* offset into readbuf for keeping track + * between callbacks. */ + size_t toc_count; /* current bytes read of the toc */ + z_stream zs; /* gz state for compressing/decompressing toc */ + char *path_prefix; /* used for distinguishing absolute paths */ + err_handler ercallback; /* callback for errors/warnings */ + struct errctx errctx; /* error callback context */ + xar_subdoc_t subdocs; /* linked list of subdocs */ + uint64_t last_fileid; /* unique fileid's in the archive */ + xmlHashTablePtr ino_hash; /* Hash for looking up hardlinked files (add)*/ + xmlHashTablePtr link_hash; /* Hash for looking up hardlinked files (extract)*/ + xmlHashTablePtr csum_hash; /* Hash for looking up checksums of files */ EVP_MD_CTX toc_ctx; int docksum; int skipwarn; diff -urN xar.hash/lib/arcmod.c xar.final/lib/arcmod.c --- xar.hash/lib/arcmod.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/arcmod.c 2006-03-17 10:35:14.000000000 -0800 @@ -57,12 +57,12 @@ * Returns: 0 on success * Summary: This is the entry point to actual file archival. */ -int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file) { +int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { int i; int32_t ret; for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { if( xar_arcmods[i].archive ) { - ret = xar_arcmods[i].archive(x, f, file); + ret = xar_arcmods[i].archive(x, f, file, buffer, len); if( ret < 0 ) { return ret; } @@ -81,12 +81,12 @@ * Returns: 0 on success * Summary: This is the entry point to actual file archival. */ -int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file) { +int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { int i; int32_t ret; for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { if( xar_arcmods[i].extract ) { - ret = xar_arcmods[i].extract(x, f, file); + ret = xar_arcmods[i].extract(x, f, file, buffer, len); if( ret < 0 ) { return ret; } @@ -97,3 +97,8 @@ } return 0; } + + +int32_t xar_arcmod_verify(xar_t x, xar_file_t f){ + return xar_data_verify(x,f); +} diff -urN xar.hash/lib/arcmod.h xar.final/lib/arcmod.h --- xar.hash/lib/arcmod.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/arcmod.h 2006-03-17 10:35:14.000000000 -0800 @@ -37,15 +37,17 @@ #include "filetree.h" -typedef int32_t (*arcmod_archive)(xar_t x, xar_file_t f, const char* file); -typedef int32_t (*arcmod_extract)(xar_t x, xar_file_t f, const char* file); +typedef int32_t (*arcmod_archive)(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +typedef int32_t (*arcmod_extract)(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); struct arcmod { arcmod_archive archive; arcmod_extract extract; }; -int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file); -int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file); +int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); +int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); + +int32_t xar_arcmod_verify(xar_t x, xar_file_t f); #endif /* _XAR_ARCMOD_H_ */ diff -urN xar.hash/lib/darwinattr.c xar.final/lib/darwinattr.c --- xar.hash/lib/darwinattr.c 2006-03-17 11:26:55.000000000 -0800 +++ xar.final/lib/darwinattr.c 2006-03-17 10:35:14.000000000 -0800 @@ -554,19 +554,21 @@ DARWINATTR_CONTEXT(context)->fd = 0; - xar_set_perm(x, f, underbarname ); + xar_set_perm(x, f, underbarname, NULL, 0 ); return 0; } -int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file) +int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { struct _darwinattr_context context; memset(&context,0,sizeof(struct _darwinattr_context)); #if defined(__APPLE__) + if( len ) + return 0; #if defined(HAVE_GETXATTR) if( ea_archive(x, f, file, (void *)&context) == 0 ) return 0; @@ -578,13 +580,15 @@ return 0; } -int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file) +int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { struct _darwinattr_context context; memset(&context,0,sizeof(struct _darwinattr_context)); #if defined(__APPLE__) + if( len ) + return 0; #if defined(HAVE_GETXATTR) if( ea_extract(x, f, file, (void *)&context) == 0 ) return 0; diff -urN xar.hash/lib/darwinattr.h xar.final/lib/darwinattr.h --- xar.hash/lib/darwinattr.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/darwinattr.h 2006-03-17 10:35:14.000000000 -0800 @@ -6,6 +6,6 @@ #ifndef _XAR_DARWINATTR_H_ #define _XAR_DARWINATTR_H_ int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file); -int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file); -int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file); +int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_DARWINATTR_H_ */ diff -urN xar.hash/lib/data.c xar.final/lib/data.c --- xar.hash/lib/data.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/data.c 2006-03-17 10:35:14.000000000 -0800 @@ -99,7 +99,7 @@ * This is the arcmod archival entry point for archiving the file's * data into the heap file. */ -int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file) { +int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { const char *opt; int32_t retval = 0; struct _data_context context; @@ -120,14 +120,20 @@ return 0; } - context.fd = open(file, O_RDONLY); - if( context.fd < 0 ) { - xar_err_new(x); - xar_err_set_file(x, f); - xar_err_set_string(x, "io: Could not open file"); - xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); - return -1; - } + if( 0 == len ){ + context.fd = open(file, O_RDONLY); + if( context.fd < 0 ) { + xar_err_new(x); + xar_err_set_file(x, f); + xar_err_set_string(x, "io: Could not open file"); + xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); + return -1; + } + }else{ + context.buffer = (void *)buffer; + context.length = len; + context.offset = 0; + } retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read,(void *)(&context)); @@ -137,7 +143,7 @@ return retval; } -int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file) { +int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; struct _data_context context; @@ -158,25 +164,32 @@ return 0; } - /* mode 600 since other modules may need to operate on the file - * prior to the real permissions being set. - */ + if ( len ){ + context.length = len; + context.buffer = buffer; + context.offset = 0; + }else{ + /* mode 600 since other modules may need to operate on the file + * prior to the real permissions being set. + */ TRYAGAIN: - context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); - if( context.fd < 0 ) { - if( errno == ENOENT ) { - xar_file_t parent = XAR_FILE(f)->parent; - if( parent && (xar_extract(x, parent) == 0) ) - goto TRYAGAIN; + context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); + if( context.fd < 0 ) { + if( errno == ENOENT ) { + xar_file_t parent = XAR_FILE(f)->parent; + if( parent && (xar_extract(x, parent) == 0) ) + goto TRYAGAIN; + } + + xar_err_new(x); + xar_err_set_file(x, f); + xar_err_set_string(x, "io: Could not create file"); + xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + return -1; } - xar_err_new(x); - xar_err_set_file(x, f); - xar_err_set_string(x, "io: Could not create file"); - xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); - return -1; } - + xar_attrcopy_from_heap(x, f, "data", xar_data_write, (void *)(&context)); if( context.fd > 0 ) @@ -185,3 +198,19 @@ return 0; } +int32_t xar_data_verify(xar_t x, xar_file_t f) +{ + const char *opt; + struct _data_context context; + + memset(&context,0,sizeof(struct _data_context)); + + /* Only regular files are copied in and out of the heap here */ + xar_prop_get(f, "type", &opt); + if( !opt ) return 0; + if( strcmp(opt, "directory") == 0 ) { + return 0; + } + + return xar_attrcopy_from_heap(x, f, "data", NULL , (void *)(&context)); +} diff -urN xar.hash/lib/data.h xar.final/lib/data.h --- xar.hash/lib/data.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/data.h 2006-03-17 10:35:14.000000000 -0800 @@ -5,6 +5,8 @@ */ #ifndef _XAR_DATA_H_ #define _XAR_DATA_H_ -int32_t xar_data_archive(xar_t x, xar_file_t f, const char* file); -int32_t xar_data_extract(xar_t x, xar_file_t f, const char* file); +int32_t xar_data_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +int32_t xar_data_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); + +int32_t xar_data_verify(xar_t x, xar_file_t f); #endif /* _XAR_DATA_H_ */ diff -urN xar.hash/lib/ext2.c xar.final/lib/ext2.c --- xar.hash/lib/ext2.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/ext2.c 2006-03-17 10:35:14.000000000 -0800 @@ -70,9 +70,14 @@ } #endif -int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file) +int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { int ret = 0; + + /* if archiving from a buffer, then there is no place to get extattr */ + if ( len ) + return 0; + #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) int fd, flags=0, version; char *vstr; @@ -158,8 +163,12 @@ } #endif -int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file) +int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { + /* if extracting to a buffer, then there is no place to write extattr */ + if ( len ) + return 0; + #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) int fd = -1, version, flags = 0; char *tmp; diff -urN xar.hash/lib/ext2.h xar.final/lib/ext2.h --- xar.hash/lib/ext2.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/ext2.h 2006-03-17 10:35:14.000000000 -0800 @@ -6,6 +6,6 @@ #ifndef _XAR_EXT2_H_ #define _XAR_EXT2_H_ #define XAR_ATTR_FORK "attribute" -int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file); -int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file); +int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_EXT2_H_ */ diff -urN xar.hash/lib/fbsdattr.c xar.final/lib/fbsdattr.c --- xar.hash/lib/fbsdattr.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/fbsdattr.c 2006-03-17 10:54:53.000000000 -0800 @@ -99,7 +99,7 @@ } #endif -int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file) +int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { #ifdef HAVE_SYS_EXTATTR_H char *buf = NULL; @@ -110,6 +110,11 @@ struct _fbsdattr_context context; memset(&context,0,sizeof(struct _fbsdattr_context)); + + /* no fbsdattr attributes for data to a buffer */ + if(len){ + return 0; + } TRYAGAIN: /* extattr_list_link()'s man page does not define the return @@ -218,7 +223,12 @@ struct _fbsdattr_context context; memset(&context,0,sizeof(struct _fbsdattr_context)); - + + /* no fbsdattr attributes for data to a buffer */ + if(len){ + return 0; + } + statfs(file, &sfs); fsname = sfs.f_fstypename; diff -urN xar.hash/lib/fbsdattr.h xar.final/lib/fbsdattr.h --- xar.hash/lib/fbsdattr.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/fbsdattr.h 2006-03-17 10:35:14.000000000 -0800 @@ -5,6 +5,6 @@ */ #ifndef _XAR_FBSDATTR_H_ #define _XAR_FBSDATTR_H_ -int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file); -int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file); +int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_FBSDATTR_H_ */ diff -urN xar.hash/lib/filetree.c xar.final/lib/filetree.c --- xar.hash/lib/filetree.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/filetree.c 2006-03-17 10:35:14.000000000 -0800 @@ -545,6 +545,51 @@ return 0; } +/* xar_prop_replicate_r +* f: file to attach property +* p: property (list) to iterate and add +* parent: parent property +* Summary: Recursivley adds property list (p) to file (f) and parent (parent). +*/ + +void xar_prop_replicate_r(xar_file_t f, xar_prop_t p, xar_prop_t parent ) +{ + xar_prop_t property = p; + + /* look through properties */ + for( property = p; property; property = property->next ){ + xar_prop_t newprop = xar_prop_new( f, parent ); + + /* copy the key value for the property */ + XAR_PROP(newprop)->key = strdup(property->key); + if(property->value) + XAR_PROP(newprop)->value = strdup(property->value); + + /* loop through the attributes and copy them */ + xar_attr_t a = NULL; + xar_attr_t last = NULL; + + /* copy attributes for file */ + for(a = property->attrs; a; a = a->next) { + if( NULL == newprop->attrs ){ + last = xar_attr_new(); + XAR_PROP(newprop)->attrs = last; + }else{ + XAR_ATTR(last)->next = xar_attr_new(); + last = XAR_ATTR(last)->next; + } + + XAR_ATTR(last)->key = strdup(a->key); + if(a->value) + XAR_ATTR(last)->value = strdup(a->value); + } + + /* loop through the children properties and recursively add them */ + xar_prop_replicate_r(f, property->children, newprop ); + } + +} + /* xar_prop_free * p: property to free * Summary: frees the specified property and all its children. @@ -621,6 +666,26 @@ return ret; } +xar_file_t xar_file_replicate(xar_file_t original, xar_file_t newparent) +{ + xar_file_t ret = xar_file_new(newparent); + xar_attr_t a; + + /* copy attributes for file */ + for(a = XAR_FILE(original)->attrs; a; a = XAR_ATTR(a)->next) { + /* skip the id attribute */ + if( 0 == strcmp(a->key, "id" ) ) + continue; + + xar_attr_set(ret, NULL , a->key, a->value ); + } + + /* recursively copy properties */ + xar_prop_replicate_r(ret, XAR_FILE(original)->props, NULL); + + return ret; +} + /* xar_file_free * f: file to free * Summary: frees the specified file and all children, diff -urN xar.hash/lib/filetree.h xar.final/lib/filetree.h --- xar.hash/lib/filetree.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/filetree.h 2006-03-17 10:35:14.000000000 -0800 @@ -82,6 +82,7 @@ xar_file_t xar_file_unserialize(xar_t x, xar_file_t parent, xmlTextReaderPtr reader); xar_file_t xar_file_find(xar_file_t f, const char *path); xar_file_t xar_file_new(xar_file_t f); +xar_file_t xar_file_replicate(xar_file_t original, xar_file_t newparent); void xar_file_free(xar_file_t f); void xar_prop_serialize(xar_prop_t p, xmlTextWriterPtr writer); diff -urN xar.hash/lib/io.c xar.final/lib/io.c --- xar.hash/lib/io.c 2006-03-17 11:20:06.000000000 -0800 +++ xar.final/lib/io.c 2006-03-17 10:35:14.000000000 -0800 @@ -415,6 +415,140 @@ return 0; } +/* xar_attrcopy_from_heap_to_heap +* This does a simple copy of the heap data from one head (read-only) to another heap (write only). +* This does not set any properties or attributes of the file, so this should not be used alone. +*/ +int32_t xar_attrcopy_from_heap_to_heap(xar_t xsource, xar_file_t fsource, const char *attr, xar_t xdest, xar_file_t fdest){ + int r, off; + size_t bsize; + int64_t fsize, inc = 0, seekoff, writesize=0; + off_t orig_heap_offset = XAR(xdest)->heap_offset; + void *inbuf; + const char *opt; + char *tmpstr = NULL, *tmpstr2 = NULL; + + opt = xar_opt_get(xsource, "rsize"); + if( !opt ) { + bsize = 4096; + } else { + bsize = strtol(opt, NULL, 0); + if( ((bsize == LONG_MAX) || (bsize == LONG_MIN)) && (errno == ERANGE) ) { + bsize = 4096; + } + } + + asprintf(&tmpstr, "%s/offset", attr); + xar_prop_get(fsource, tmpstr, &opt); + free(tmpstr); + + seekoff = strtoll(opt, NULL, 0); + + if( ((seekoff == LLONG_MAX) || (seekoff == LLONG_MIN)) && (errno == ERANGE) ) { + return -1; + } + + seekoff += XAR(xsource)->toc_count + sizeof(xar_header_t); + + if( XAR(xsource)->fd > 1 ) { + r = lseek(XAR(xsource)->fd, seekoff, SEEK_SET); + if( r == -1 ) { + if( errno == ESPIPE ) { + ssize_t rr; + char *buf; + unsigned int len; + + len = seekoff - XAR(xsource)->toc_count; + len -= sizeof(xar_header_t); + if( XAR(xsource)->heap_offset > len ) { + xar_err_new(xsource); + xar_err_set_file(xsource, fsource); + xar_err_set_string(xsource, "Unable to seek"); + xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + } else { + len -= XAR(xsource)->heap_offset; + buf = malloc(len); + assert(buf); + rr = read(XAR(xsource)->fd, buf, len); + if( rr < len ) { + xar_err_new(xsource); + xar_err_set_file(xsource, fsource); + xar_err_set_string(xsource, "Unable to seek"); + xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + } + free(buf); + } + } else { + xar_err_new(xsource); + xar_err_set_file(xsource, fsource); + xar_err_set_string(xsource, "Unable to seek"); + xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + } + } + } + + asprintf(&tmpstr, "%s/length", attr); + xar_prop_get(fsource, tmpstr, &opt); + free(tmpstr); + if( !opt ) { + return 0; + } else { + fsize = strtoll(opt, NULL, 10); + if( ((fsize == LLONG_MAX) || (fsize == LLONG_MIN)) && (errno == ERANGE) ) { + return -1; + } + } + + inbuf = malloc(bsize); + if( !inbuf ) { + return -1; + } + + + while(1) { + /* Size has been reached */ + if( fsize == inc ) + break; + if( (fsize - inc) < bsize ) + bsize = fsize - inc; + r = read(XAR(xsource)->fd, inbuf, bsize); + if( r == 0 ) + break; + if( (r < 0) && (errno == EINTR) ) + continue; + if( r < 0 ) { + free(inbuf); + return -1; + } + + XAR(xsource)->heap_offset += r; + inc += r; + bsize = r; + + off = 0; + + do { + r = write(XAR(xdest)->heap_fd, inbuf+off, r-off ); + off += r; + writesize += r; + } while( off < r ); + XAR(xdest)->heap_offset += off; + XAR(xdest)->heap_len += off; + } + + asprintf(&tmpstr, "%"PRIu64, (uint64_t)orig_heap_offset); + asprintf(&tmpstr2, "%s/offset", attr); + xar_prop_set(fdest, tmpstr2, tmpstr); + free(tmpstr); + free(tmpstr2); + + + free(inbuf); + + /* It is the caller's responsibility to copy the attributes of the file, etc, this only copies the data in the heap */ + + return 0; +} /* xar_heap_to_archive * x: archive to operate on * Returns 0 on success, -1 on error diff -urN xar.hash/lib/io.h xar.final/lib/io.h --- xar.hash/lib/io.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/io.h 2006-03-17 10:35:14.000000000 -0800 @@ -56,6 +56,7 @@ int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context); int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context); +int32_t xar_attrcopy_from_heap_to_heap(xar_t xsource, xar_file_t fsource, const char *attr, xar_t xdest, xar_file_t fdest); int32_t xar_heap_to_archive(xar_t x); #endif /* _XAR_IO_H_ */ diff -urN xar.hash/lib/linuxattr.c xar.final/lib/linuxattr.c --- xar.hash/lib/linuxattr.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/linuxattr.c 2006-03-17 13:38:53.000000000 -0800 @@ -128,7 +128,7 @@ } #endif -int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file) +int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__) char *i, *buf = NULL; @@ -139,6 +139,11 @@ memset(&context,0,sizeof(struct _linuxattr_context)); + /* data from buffers don't have linuxattr */ + if(len){ + return 0; + } + TRYAGAIN: buf = malloc(bufsz); if(!buf) @@ -188,7 +193,7 @@ return 0; } -int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file) +int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #if defined HAVE_SYS_XATTR_H && defined(HAVE_LSETXATTR) && !defined(__APPLE__) const char *fsname = "bogus"; @@ -200,6 +205,11 @@ memset(&context,0,sizeof(struct _linuxattr_context)); + /* data buffers, can't store linux attrs */ + if(len){ + return 0; + } + /* Check for EA extraction behavior */ memset(&sfs, 0, sizeof(sfs)); diff -urN xar.hash/lib/linuxattr.h xar.final/lib/linuxattr.h --- xar.hash/lib/linuxattr.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/linuxattr.h 2006-03-17 13:38:55.000000000 -0800 @@ -5,6 +5,6 @@ */ #ifndef _XAR_LINUXATTR_H_ #define _XAR_LINUXATTR_H_ -int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file); -int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file); +int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); +int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_LINUXATTR_H_ */ diff -urN xar.hash/lib/stat.c xar.final/lib/stat.c --- xar.hash/lib/stat.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/stat.c 2006-03-17 10:35:14.000000000 -0800 @@ -214,7 +214,7 @@ return 0; } -int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file) { +int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { char *tmpstr; struct passwd *pw; struct group *gr; @@ -222,6 +222,12 @@ struct tm t; const char *type; + /* no stat attributes for data from a buffer, it is just a file */ + if(len){ + xar_prop_set(f, "type", "file"); + return 0; + } + if( S_ISREG(XAR(x)->sbcache.st_mode) && (XAR(x)->sbcache.st_nlink > 1) ) { xar_file_t tmpf; const char *id = xar_attr_get(f, NULL, "id"); @@ -304,7 +310,7 @@ return 0; } -int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file) { +int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; int32_t m=0, mset=0; uid_t u; @@ -314,6 +320,10 @@ enum {ATIME=0, MTIME}; struct timeval tv[2]; + /* when writing to a buffer, there are no permissions to set */ + if ( len ) + return 0; + /* in case we don't find anything useful in the archive */ u = geteuid(); g = getegid(); @@ -433,7 +443,7 @@ return 0; } -int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file) { +int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; int ret, fd; diff -urN xar.hash/lib/stat.h xar.final/lib/stat.h --- xar.hash/lib/stat.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/stat.h 2006-03-17 10:35:14.000000000 -0800 @@ -36,8 +36,8 @@ #include "xar.h" -int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file); -int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file); -int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file); +int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); +int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); +int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); #endif /* _XAR_STAT_H_ */ diff -urN xar.hash/lib/util.c xar.final/lib/util.c --- xar.hash/lib/util.c 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/util.c 2006-03-17 10:35:14.000000000 -0800 @@ -30,6 +30,7 @@ * 03-Apr-2005 * DRI: Rob Braun */ + #include #include #include @@ -42,6 +43,7 @@ #include "asprintf.h" #endif #include "xar.h" +#include "archive.h" #include "filetree.h" uint64_t xar_ntoh64(uint64_t num) { @@ -97,6 +99,10 @@ return ret; } +off_t xar_get_heap_offset(xar_t x) { + return XAR(x)->toc_count + sizeof(xar_header_t); +} + /* xar_read_fd * Summary: Reads from a file descriptor a certain number of bytes to a specific * buffer. This simple wrapper just handles certain retryable error situations. diff -urN xar.hash/lib/util.h xar.final/lib/util.h --- xar.hash/lib/util.h 2006-03-17 11:19:16.000000000 -0800 +++ xar.final/lib/util.h 2006-03-17 10:35:14.000000000 -0800 @@ -41,6 +41,7 @@ uint64_t xar_ntoh64(uint64_t num); uint32_t xar_swap32(uint32_t num); char *xar_get_path(xar_file_t f); +off_t xar_get_heap_offset(xar_t x); ssize_t xar_read_fd(int fd, void * buffer, size_t nbytes); ssize_t xar_write_fd(int fd, void * buffer, size_t nbytes); xar-xar-498/patches/context.diff000066400000000000000000001733231446633275300167550ustar00rootroot00000000000000diff -urN xar/lib/archive.c xar.context/lib/archive.c --- xar/lib/archive.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/archive.c 2006-03-17 11:24:36.000000000 -0800 @@ -64,6 +64,13 @@ #define O_SHLOCK 0 #endif +#ifndef LONG_MAX +#define LONG_MAX INT32_MAX +#endif +#ifndef LONG_MIN +#define LONG_MIN INT32_MIN +#endif + static int32_t xar_unserialize(xar_t x); void xar_serialize(xar_t x, const char *file); diff -urN xar/lib/bzxar.c xar.context/lib/bzxar.c --- xar/lib/bzxar.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/bzxar.c 2006-03-17 10:57:14.000000000 -0800 @@ -47,13 +47,12 @@ #include "io.h" #ifdef HAVE_LIBBZ2 -static int initted = 0; -static bz_stream zs; +#define BZIP2_CONTEXT(x) ((bz_stream *)(*x)) #endif -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr); +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context); -int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { #ifdef HAVE_LIBBZ2 const char *opt; void *out = NULL; @@ -67,31 +66,27 @@ if( !opt ) return 0; if( strcmp(opt, "application/x-bzip2") != 0 ) return 0; - if( !initted ) { - zs.bzalloc = NULL; - zs.bzfree = NULL; - zs.opaque = NULL; - - BZ2_bzDecompressInit(&zs, 0, 0); - initted = 1; + if( !BZIP2_CONTEXT(context) ) { + *context = calloc(1,sizeof(bz_stream)); + BZ2_bzDecompressInit(BZIP2_CONTEXT(context), 0, 0); } outlen = *inlen; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + BZIP2_CONTEXT(context)->next_in = *in; + BZIP2_CONTEXT(context)->avail_in = *inlen; + BZIP2_CONTEXT(context)->next_out = out; + BZIP2_CONTEXT(context)->avail_out = 0; - while( zs.avail_in != 0 ) { + while( BZIP2_CONTEXT(context)->avail_in != 0 ) { outlen = outlen * 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + BZIP2_CONTEXT(context)->next_out = out + offset; + BZIP2_CONTEXT(context)->avail_out = outlen - offset; - r = BZ2_bzDecompress(&zs); + r = BZ2_bzDecompress(BZIP2_CONTEXT(context)); if( (r != BZ_OK) && (r != BZ_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); @@ -99,10 +94,10 @@ xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } - offset += outlen - offset - zs.avail_out; + offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out; if( (r == BZ_STREAM_END) && (offset == 0) ) { - xar_bzip_fromheap_done(x, f, attr); - offset += outlen - offset - zs.avail_out; + xar_bzip_fromheap_done(x, f, attr, context); + offset += outlen - offset - BZIP2_CONTEXT(context)->avail_out; break; } } @@ -114,14 +109,19 @@ return 0; } -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { #ifdef HAVE_LIBBZ2 - initted = 0; - BZ2_bzDecompressEnd(&zs); + BZ2_bzDecompressEnd(BZIP2_CONTEXT(context)); + + if(BZIP2_CONTEXT(context)){ + free(BZIP2_CONTEXT(context)); + *context = NULL; + } + #endif /* HAVE_LIBBZ2 */ return 0; } -int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { #ifdef HAVE_LIBBZ2 const char *opt; char *tmpstr; @@ -133,9 +133,13 @@ if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; - initted = 0; - BZ2_bzCompressEnd(&zs); + BZ2_bzCompressEnd(BZIP2_CONTEXT(context)); + if(BZIP2_CONTEXT(context)){ + free(BZIP2_CONTEXT(context)); + *context = NULL; + } + asprintf(&tmpstr, "%s/encoding", attr); if( f ) { xar_prop_set(f, tmpstr, NULL); @@ -147,7 +151,7 @@ return 0; } -int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { #ifdef HAVE_LIBBZ2 void *out = NULL; size_t outlen, offset = 0; @@ -161,33 +165,32 @@ if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; - if( !initted ) { - memset(&zs, 0, sizeof(zs)); - BZ2_bzCompressInit(&zs, 9, 0, 30); - initted = 1; + if( !BZIP2_CONTEXT(context) ) { + *context = calloc(1,sizeof(bz_stream)); + BZ2_bzCompressInit(BZIP2_CONTEXT(context), 9, 0, 30); } outlen = *inlen/2; if(outlen == 0) outlen = 1024; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + BZIP2_CONTEXT(context)->next_in = *in; + BZIP2_CONTEXT(context)->avail_in = *inlen; + BZIP2_CONTEXT(context)->next_out = out; + BZIP2_CONTEXT(context)->avail_out = 0; do { outlen *= 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + BZIP2_CONTEXT(context)->next_out = out + offset; + BZIP2_CONTEXT(context)->avail_out = outlen - offset; - if( *inlen == 0 ) - r = BZ2_bzCompress(&zs, BZ_FINISH); + if( (*inlen == 0) ) + r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_FINISH); else - r = BZ2_bzCompress(&zs, BZ_RUN); - offset = outlen - zs.avail_out; - } while( zs.avail_in != 0 ); + r = BZ2_bzCompress(BZIP2_CONTEXT(context), BZ_RUN); + offset = outlen - BZIP2_CONTEXT(context)->avail_out; + } while( BZIP2_CONTEXT(context)->avail_in != 0 ); free(*in); *in = out; diff -urN xar/lib/bzxar.h xar.context/lib/bzxar.h --- xar/lib/bzxar.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/bzxar.h 2006-03-17 10:57:20.000000000 -0800 @@ -34,10 +34,10 @@ #ifndef _XAR_BZLIB_H_ #define _XAR_BZLIB_H_ -int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *); +int xar_bzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_bzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context); -int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *); +int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_bzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_BZLIB_H_ */ diff -urN xar/lib/darwinattr.c xar.context/lib/darwinattr.c --- xar/lib/darwinattr.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/darwinattr.c 2006-03-17 11:26:37.000000000 -0800 @@ -54,8 +54,15 @@ #include #endif -static int Fd; +struct _darwinattr_context{ + int fd; + char *finfo; + char *buf; + int len; + int off; +}; +#define DARWINATTR_CONTEXT(x) ((struct _darwinattr_context *)(x)) #if defined(__APPLE__) #ifdef HAVE_GETATTRLIST #include @@ -66,21 +73,19 @@ char finderinfo[32]; }; -static char *Gfinfo = NULL; - /* finfo_read * This is for archiving the finderinfo via the getattrlist method. * This function is used from the nonea_archive() function. */ -static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( len < 32 ) return -1; - if( Gfinfo == NULL ) + if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; - memcpy(buf, Gfinfo, 32); - Gfinfo = NULL; + memcpy(buf, DARWINATTR_CONTEXT(context)->finfo, 32); + DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } @@ -88,26 +93,26 @@ * This is for extracting the finderinfo via the setattrlist method. * This function is used from the nonea_extract() function. */ -static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { struct attrlist attrs; struct fi finfo; if( len < 32 ) return -1; - if( Gfinfo == NULL ) + if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; - getattrlist(Gfinfo, &attrs, &finfo, sizeof(finfo), 0); + getattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, &finfo, sizeof(finfo), 0); attrs.commonattr = ATTR_CMN_FNDRINFO; - if( setattrlist(Gfinfo, &attrs, buf, 32, 0) != 0 ) + if( setattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, buf, 32, 0) != 0 ) return -1; - Gfinfo = NULL; + DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } #endif /* HAVE_GETATTRLIST */ @@ -116,11 +121,11 @@ * This is the read callback function for archiving the resource fork via * the ..namedfork method. This callback is used from nonea_archive() */ -static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) { +static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; while(1) { - r = read(Fd, inbuf, bsize); + r = read(DARWINATTR_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; return r; @@ -133,11 +138,11 @@ * back to the file via ..namedfork method. This is the callback used * in nonea_extract() and underbar_extract(). */ -static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len) { +static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; do { - r = write(Fd, buf+off, len-off); + r = write(DARWINATTR_CONTEXT(context)->fd, buf+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; @@ -147,57 +152,54 @@ #ifdef __APPLE__ #if defined(HAVE_GETXATTR) -static char *Gbuf = NULL; -static int Glen = 0; -static int Goff = 0; - -static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len) { - if( Gbuf == NULL ) + +static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; - if( (Glen-Goff) <= len ) { - int siz = Glen-Goff; - memcpy(buf, Gbuf+Goff, siz); - free(Gbuf); - Gbuf = NULL; - Goff = 0; - Glen = 0; + if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { + int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); + memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, siz); + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->off = 0; + DARWINATTR_CONTEXT(context)->len = 0; return siz; } - memcpy(buf, Gbuf+Goff, len); - Goff += len; + memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, len); + DARWINATTR_CONTEXT(context)->off += len; - if( Goff == Glen ) { - free(Gbuf); - Gbuf = NULL; - Goff = 0; - Glen = 0; + if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) { + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->off = 0; + DARWINATTR_CONTEXT(context)->len = 0; } return len; } -static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len) { - if( Gbuf == NULL ) +static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; - if( Goff == Glen ) + if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) return 0; - if( (Glen-Goff) <= len ) { - int siz = Glen-Goff; - memcpy(Gbuf+Goff, buf, siz); + if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { + int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); + memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, siz); return siz; } - memcpy(Gbuf+Goff, buf, len); - Goff += len; + memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, len); + DARWINATTR_CONTEXT(context)->off += len; return len; } -static int32_t ea_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t ea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char *buf, *i; int ret, bufsz; int32_t retval = 0; @@ -231,29 +233,29 @@ ret = getxattr(file, i, NULL, 0, 0, XATTR_NOFOLLOW); if( ret < 0 ) continue; - Glen = ret; - Gbuf = malloc(Glen); - if( !Gbuf ) + DARWINATTR_CONTEXT(context)->len = ret; + DARWINATTR_CONTEXT(context)->buf = malloc(DARWINATTR_CONTEXT(context)->len); + if( !DARWINATTR_CONTEXT(context)->buf ) goto BAIL; - ret = getxattr(file, i, Gbuf, Glen, 0, XATTR_NOFOLLOW); + ret = getxattr(file, i, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); if( ret < 0 ) { - free(Gbuf); - Gbuf = NULL; - Glen = 0; + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->len = 0; continue; } memset(tempnam, 0, sizeof(tempnam)); snprintf(tempnam, sizeof(tempnam)-1, "ea/%s", i); - xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read); + xar_attrcopy_to_heap(x, f, tempnam, xar_ea_read, context); } BAIL: free(buf); return retval; } -static int32_t ea_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t ea_extract(xar_t x, xar_file_t f, const char* file, void *context) { const char *prop; xar_iter_t iter; @@ -275,18 +277,18 @@ continue; len = strtol(opt, NULL, 10); - Gbuf = malloc(len); - if( !Gbuf ) + DARWINATTR_CONTEXT(context)->buf = malloc(len); + if( !DARWINATTR_CONTEXT(context)->buf ) return -1; - Glen = len; + DARWINATTR_CONTEXT(context)->len = len; - xar_attrcopy_from_heap(x, f, prop, xar_ea_write); + xar_attrcopy_from_heap(x, f, prop, xar_ea_write, context); - setxattr(file, prop+strlen(XAR_EA_FORK)+1, Gbuf, Glen, 0, XATTR_NOFOLLOW); - free(Gbuf); - Gbuf = NULL; - Glen = 0; - Goff = 0; + setxattr(file, prop+strlen(XAR_EA_FORK)+1, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); + free(DARWINATTR_CONTEXT(context)->buf); + DARWINATTR_CONTEXT(context)->buf = NULL; + DARWINATTR_CONTEXT(context)->len = 0; + DARWINATTR_CONTEXT(context)->off = 0; } return 0; @@ -298,7 +300,7 @@ * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ -static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; struct stat sb; #ifdef HAVE_GETATTRLIST @@ -317,8 +319,8 @@ memset(z, 0, sizeof(z)); if( memcmp(finfo.finderinfo, z, sizeof(finfo.finderinfo)) != 0 ) { - Gfinfo = finfo.finderinfo; - xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read); + DARWINATTR_CONTEXT(context)->finfo = finfo.finderinfo; + xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context); } #endif /* HAVE_GETATTRLIST */ @@ -331,12 +333,12 @@ if( sb.st_size == 0 ) return 0; - Fd = open(rsrcname, O_RDONLY, 0); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDONLY, 0); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; - xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read); - close(Fd); + xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context); + close(DARWINATTR_CONTEXT(context)->fd); return 0; } @@ -345,7 +347,7 @@ * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ -static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; #ifdef HAVE_SETATTRLIST struct attrlist attrs; @@ -360,19 +362,19 @@ if( ret != 0 ) return -1; - Gfinfo = (char *)file; + DARWINATTR_CONTEXT(context)->finfo = (char *)file; - xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write); + xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", finfo_write, context); #endif /* HAVE_SETATTRLIST */ memset(rsrcname, 0, sizeof(rsrcname)); snprintf(rsrcname, sizeof(rsrcname)-1, "%s/..namedfork/rsrc", file); - Fd = open(rsrcname, O_RDWR|O_TRUNC); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDWR|O_TRUNC); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return 0; - xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context); + close(DARWINATTR_CONTEXT(context)->fd); return 0; } #endif /* __APPLE__ */ @@ -381,13 +383,13 @@ * Check to see if the file we're archiving is a ._ file. If so, * stop the archival process. */ -int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file) { +int32_t xar_underbar_check(xar_t x, xar_file_t f, const char* file, void *context) { char *bname, *tmp; tmp = strdup(file); bname = basename(tmp); - if(bname && (bname[0] == '.') && (bname[1] == '_')) { + if(bname && (bname[0] == '.') && (bname[1] == '_')){ free(tmp); return 1; } @@ -398,7 +400,7 @@ #ifdef __APPLE__ /* This only really makes sense on OSX */ -static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file) { +static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file, void *context) { struct stat sb; char underbarname[4096], z[32]; char *dname, *bname, *tmp, *tmp2; @@ -407,6 +409,9 @@ int num_entries = 0, i, r; off_t off; + if( !file ) + return 0; + tmp = strdup(file); tmp2 = strdup(file); dname = dirname(tmp2); @@ -420,13 +425,13 @@ if( stat(underbarname, &sb) != 0 ) return 0; - Fd = open(underbarname, O_RDONLY); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDONLY); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; memset(&ash, 0, sizeof(ash)); memset(&ase, 0, sizeof(ase)); - r = read(Fd, &ash, XAR_ASH_SIZE); + r = read(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); if( r < XAR_ASH_SIZE ) return -1; @@ -440,37 +445,38 @@ for(i = 0; i < num_entries; i++) { off_t entoff; - r = read(Fd, &ase, sizeof(ase)); + r = read(DARWINATTR_CONTEXT(context)->fd, &ase, sizeof(ase)); if( r < sizeof(ase) ) return -1; off+=r; if( ntohl(ase.entry_id) == AS_ID_FINDER ) { entoff = (off_t)ntohl(ase.offset); - if( lseek(Fd, entoff, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) return -1; - r = read(Fd, z, sizeof(z)); + r = read(DARWINATTR_CONTEXT(context)->fd, z, sizeof(z)); if( r < sizeof(z) ) return -1; - Gfinfo = z; - xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read); - if( lseek(Fd, (off_t)off, SEEK_SET) == -1 ) + DARWINATTR_CONTEXT(context)->finfo = z; + xar_attrcopy_to_heap(x, f, "ea/com.apple.FinderInfo", finfo_read, context); + if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) return -1; } if( ntohl(ase.entry_id) == AS_ID_RESOURCE ) { entoff = (off_t)ntohl(ase.offset); - if( lseek(Fd, entoff, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) return -1; - xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read); + xar_attrcopy_to_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_read, context); - if( lseek(Fd, (off_t)off, SEEK_SET) == -1 ) + if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) return -1; } } - close(Fd); + close(DARWINATTR_CONTEXT(context)->fd); + DARWINATTR_CONTEXT(context)->fd = 0; return 0; } #endif @@ -479,7 +485,7 @@ * Extract finderinfo and resource fork information to an appledouble * ._ file. */ -static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file) { +static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file, void *context) { char underbarname[4096]; char *dname, *bname, *tmp, *tmp2; const char *rsrclenstr; @@ -510,8 +516,8 @@ free(tmp); free(tmp2); - Fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0); - if( Fd < 0 ) + DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0); + if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; xar_prop_get(f, "ea/com.apple.ResourceFork/size", &rsrclenstr); @@ -524,29 +530,31 @@ ash.version = htonl(APPLEDOUBLE_VERSION); ash.entries = htons(num_entries); - write(Fd, &ash, XAR_ASH_SIZE); + write(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); ase.offset = htonl(XAR_ASH_SIZE + ntohs(ash.entries)*12); if( have_fi ) { ase.entry_id = htonl(AS_ID_FINDER); ase.length = htonl(32); - write(Fd, &ase, 12); + write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_rsrc ) { ase.entry_id = htonl(AS_ID_RESOURCE); ase.offset = htonl(ntohl(ase.offset) + ntohl(ase.length)); ase.length = htonl(rsrclen); - write(Fd, &ase, 12); + write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_fi ) - xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write); + xar_attrcopy_from_heap(x, f, "ea/com.apple.FinderInfo", xar_rsrc_write, context); if( have_rsrc ) - xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "ea/com.apple.ResourceFork", xar_rsrc_write, context); + close(DARWINATTR_CONTEXT(context)->fd); - xar_set_perm(x, f, underbarname); + DARWINATTR_CONTEXT(context)->fd = 0; + + xar_set_perm(x, f, underbarname ); return 0; } @@ -554,28 +562,36 @@ int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file) { + struct _darwinattr_context context; + + memset(&context,0,sizeof(struct _darwinattr_context)); + #if defined(__APPLE__) #if defined(HAVE_GETXATTR) - if( ea_archive(x, f, file) == 0 ) + if( ea_archive(x, f, file, (void *)&context) == 0 ) return 0; #endif - if( nonea_archive(x, f, file) == 0 ) + if( nonea_archive(x, f, file, (void *)&context) == 0 ) return 0; - return underbar_archive(x, f, file); + return underbar_archive(x, f, file, (void *)&context); #endif /* __APPLE__ */ return 0; } int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file) { + struct _darwinattr_context context; + + memset(&context,0,sizeof(struct _darwinattr_context)); + #if defined(__APPLE__) #if defined(HAVE_GETXATTR) - if( ea_extract(x, f, file) == 0 ) + if( ea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif - if( nonea_extract(x, f, file) == 0 ) + if( nonea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif /* __APPLE__ */ - return underbar_extract(x, f, file); + return underbar_extract(x, f, file, (void *)&context); } diff -urN xar/lib/data.c xar.context/lib/data.c --- xar/lib/data.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/data.c 2006-03-17 11:00:28.000000000 -0800 @@ -18,24 +18,76 @@ #define O_EXLOCK 0 #endif -static int Fd; +struct _data_context{ + int fd; + void *buffer; + size_t length; + off_t offset; +}; -int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize) { +#define DATA_CONTEXT(x) ((struct _data_context*)(x)) + +int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; + /* read from buffer, rather then fd,if available */ + if(DATA_CONTEXT(context)->length){ + char *readbuf = (char *)DATA_CONTEXT(context)->buffer; + size_t sizetoread = DATA_CONTEXT(context)->length - DATA_CONTEXT(context)->offset; + + if( !sizetoread){ + return 0; + } + + if( sizetoread > bsize ){ + sizetoread = bsize; + } + + /* dont read passed the end of the buffer */ + if((DATA_CONTEXT(context)->offset + sizetoread) > DATA_CONTEXT(context)->length){ + return -1; + } + + readbuf += DATA_CONTEXT(context)->offset; + memcpy(inbuf,readbuf,sizetoread); + + DATA_CONTEXT(context)->offset += sizetoread; + + return sizetoread; + } + while(1) { - r = read(Fd, inbuf, bsize); + r = read(DATA_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; return r; - } + } + } -int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len) { +int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; + + /* read from buffer, rather then fd,if available */ + if(DATA_CONTEXT(context)->length){ + char *writebuf = (char *)DATA_CONTEXT(context)->buffer; + + /* dont write passed the end of the buffer */ + if((DATA_CONTEXT(context)->offset + len) > DATA_CONTEXT(context)->length){ + return -1; + } + + writebuf += DATA_CONTEXT(context)->offset; + memcpy(writebuf,buf,len); + + DATA_CONTEXT(context)->offset += len; + + return len; + } + do { - r = write(Fd, buf+off, len-off); + r = write(DATA_CONTEXT(context)->fd, buf+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; @@ -50,6 +102,9 @@ int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file) { const char *opt; int32_t retval = 0; + struct _data_context context; + + memset(&context,0,sizeof(struct _data_context)); xar_prop_get(f, "type", &opt); if(!opt) return 0; @@ -65,60 +120,68 @@ return 0; } - Fd = open(file, O_RDONLY); - if( Fd < 0 ) { + context.fd = open(file, O_RDONLY); + if( context.fd < 0 ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "io: Could not open file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); return -1; - } + } - retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read); + retval = xar_attrcopy_to_heap(x, f, "data", xar_data_read,(void *)(&context)); - close(Fd); + if(context.fd > 0) + close(context.fd); + return retval; } int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file) { const char *opt; - - /* Only regular files are copied in and out of the heap here */ - xar_prop_get(f, "type", &opt); - if( !opt ) return 0; - if( strcmp(opt, "file") != 0 ) { - if( strcmp(opt, "hardlink") == 0 ) { - opt = xar_attr_get(f, "type", "link"); - if( !opt ) - return 0; - if( strcmp(opt, "original") != 0 ) - return 0; - /* else, we're an original hardlink, so keep going */ - } else - return 0; - } - - /* mode 600 since other modules may need to operate on the file - * prior to the real permissions being set. - */ + struct _data_context context; + + memset(&context,0,sizeof(struct _data_context)); + + /* Only regular files are copied in and out of the heap here */ + xar_prop_get(f, "type", &opt); + if( !opt ) return 0; + if( strcmp(opt, "file") != 0 ) { + if( strcmp(opt, "hardlink") == 0 ) { + opt = xar_attr_get(f, "type", "link"); + if( !opt ) + return 0; + if( strcmp(opt, "original") != 0 ) + return 0; + /* else, we're an original hardlink, so keep going */ + } else + return 0; + } + + /* mode 600 since other modules may need to operate on the file + * prior to the real permissions being set. + */ TRYAGAIN: - Fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); - if( Fd < 0 ) { + context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); + if( context.fd < 0 ) { if( errno == ENOENT ) { xar_file_t parent = XAR_FILE(f)->parent; if( parent && (xar_extract(x, parent) == 0) ) goto TRYAGAIN; } + + xar_err_new(x); + xar_err_set_file(x, f); + xar_err_set_string(x, "io: Could not create file"); + xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); + return -1; + } - xar_err_new(x); - xar_err_set_file(x, f); - xar_err_set_string(x, "io: Could not create file"); - xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); - return -1; - } - - xar_attrcopy_from_heap(x, f, "data", xar_data_write); - close(Fd); + xar_attrcopy_from_heap(x, f, "data", xar_data_write, (void *)(&context)); + + if( context.fd > 0 ) + close(context.fd); + return 0; } diff -urN xar/lib/fbsdattr.c xar.context/lib/fbsdattr.c --- xar/lib/fbsdattr.c 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/fbsdattr.c 2006-03-17 11:03:08.000000000 -0800 @@ -57,41 +57,45 @@ #endif #ifdef HAVE_SYS_EXTATTR_H -static const char *Gfile = NULL; -static const char *Gattr = NULL; -static void *Gbuf = NULL; -static int Goff = 0; -static int Gbufsz = 0; -static int Gns = 0; +struct _fbsdattr_context{ + const char *file = NULL; + const char *attr = NULL; + void *buf = NULL; + int off = 0; + int bufsz = 0; + int ns = 0; +}; + +#define FBSDATTR_CONTEXT(x) ((struct _fbsdattr_context *)(x)) int32_t xar_fbsdattr_read(xar_t x, xar_file_t f, void *buf, size_t len) { - if( !Gbuf ) { - Gbufsz = extattr_get_link(Gfile, Gns, Gattr, NULL, 0); - if( Gbufsz < 0 ) + if( !FBSDATTR_CONTEXT(context)->buf ) { + FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, NULL, 0); + if( FBSDATTR_CONTEXT(context)->bufsz < 0 ) return -1; - Gbuf = malloc(Gbufsz); - if( !Gbuf ) + FBSDATTR_CONTEXT(context)->buf = malloc(FBSDATTR_CONTEXT(context)->bufsz); + if( !FBSDATTR_CONTEXT(context)->buf ) return -1; - Gbufsz = extattr_get_link(Gfile, Gns, Gattr, Gbuf, Gbufsz); + FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, FBSDATTR_CONTEXT(context)->buf, FBSDATTR_CONTEXT(context)->bufsz); } - if( (Gbufsz - Goff) <= len ) { + if( (FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off) <= len ) { int32_t ret; - ret = Gbufsz - Goff; - memcpy(buf, Gbuf+Goff, ret); - Goff += ret; + ret = FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off; + memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, ret); + FBSDATTR_CONTEXT(context)->off += ret; return(ret); } else { - memcpy(buf, Gbuf+Goff, len); - Gbuf += len; + memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, len); + FBSDATTR_CONTEXT(context)->buf += len; return(len); } } int32_t xar_fbsdattr_write(xar_t x, xar_file_t f, void *buf, size_t len) { - return extattr_set_link(Gfile, Gns, Gattr, buf, len); + return extattr_set_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attr, buf, len); } #endif @@ -103,7 +107,10 @@ struct statfs sfs; char *fsname = NULL; int namespace = EXTATTR_NAMESPACE_USER; - + struct _fbsdattr_context context; + + memset(&context,0,sizeof(struct _fbsdattr_context)); + TRYAGAIN: /* extattr_list_link()'s man page does not define the return * value. The kernel source comments say 0 for success, -1 for @@ -174,16 +181,16 @@ extattr_namespace_to_string(namespace, &ns); memset(tempnam, 0, sizeof(tempnam)); snprintf(tempnam, sizeof(tempnam)-1, "%s/%s.%s", XAR_EA_FORK, ns, key); - Gns = namespace; - Gfile = file; - Gattr = key; + FBSDATTR_CONTEXT(context).ns = namespace; + FBSDATTR_CONTEXT(context).file = file; + FBSDATTR_CONTEXT(context).attr = key; xar_attr_set(f, tempnam, "fstype", fsname); xar_attrcopy_to_heap(x, f, tempnam, xar_fbsdattr_read); - free(Gbuf); - Gbuf = NULL; - Goff = 0; + free(FBSDATTR_CONTEXT(context).buf); + FBSDATTR_CONTEXT(context).buf = NULL; + FBSDATTR_CONTEXT(context).off = 0; } if( namespace == EXTATTR_NAMESPACE_USER ) { @@ -200,7 +207,7 @@ #endif } -int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file) +int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #ifdef HAVE_SYS_EXTATTR_H char *fsname = "bogus"; @@ -208,7 +215,10 @@ struct statfs sfs; int eaopt = 0; xar_iter_t iter; - + struct _fbsdattr_context context; + + memset(&context,0,sizeof(struct _fbsdattr_context)); + statfs(file, &sfs); fsname = sfs.f_fstypename; @@ -227,16 +237,16 @@ tmp = prop + strlen(XAR_EA_FORK) + 1; if( strncmp(tmp, "user.", 5) == 0 ) { - Gns = EXTATTR_NAMESPACE_USER; - Gattr = tmp + 5; + FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_USER; + FBSDATTR_CONTEXT(context).attr = tmp + 5; } else if( strncmp(tmp, "system.", 7) == 0 ) { - Gns = EXTATTR_NAMESPACE_SYSTEM; - Gattr = tmp + 7; + FBSDATTR_CONTEXT(context).ns = EXTATTR_NAMESPACE_SYSTEM; + FBSDATTR_CONTEXT(context).attr = tmp + 7; } else { continue; } - Gfile = file; + FBSDATTR_CONTEXT(context).file = file; xar_attrcopy_from_heap(x, f, prop, xar_fbsdattr_write); } diff -urN xar/lib/io.c xar.context/lib/io.c --- xar/lib/io.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/io.c 2006-03-17 11:13:25.000000000 -0800 @@ -104,7 +104,9 @@ } }; -int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb) { +int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context) { + int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); + void *modulecontext[modulecount]; int r, off, i; size_t bsize, rsize; int64_t readsize=0, writesize=0, inc = 0; @@ -114,6 +116,8 @@ off_t orig_heap_offset = XAR(x)->heap_offset; xar_file_t tmpf = NULL; + memset(modulecontext, 0, sizeof(void*)*modulecount); + opt = xar_opt_get(x, XAR_OPT_RSIZE); if( !opt ) { bsize = 4096; @@ -130,7 +134,7 @@ if( !inbuf ) return -1; - r = rcb(x, f, inbuf, bsize); + r = rcb(x, f, inbuf, bsize, context); if( r < 0 ) { free(inbuf); return -1; @@ -141,16 +145,16 @@ rsize = r; /* filter the data through the in modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_in ) { - xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize); + xar_datamods[i].th_in(x, f, attr, &inbuf, &rsize, &modulecontext[i]); } } /* filter the data through the out modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_out ) - xar_datamods[i].th_out(x, f, attr, inbuf, rsize); + xar_datamods[i].th_out(x, f, attr, inbuf, rsize, &modulecontext[i]); } off = 0; @@ -165,7 +169,7 @@ } XAR(x)->heap_offset += off; free(inbuf); - + } @@ -173,16 +177,16 @@ if( readsize == 0 ) { XAR(x)->heap_offset = orig_heap_offset; lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR); - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) - xar_datamods[i].th_done(x, NULL, attr); + xar_datamods[i].th_done(x, NULL, attr, &modulecontext[i]); } return 0; } /* finish up anything that still needs doing */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) - xar_datamods[i].th_done(x, f, attr); + xar_datamods[i].th_done(x, f, attr, &modulecontext[i]); } XAR(x)->heap_len += writesize; @@ -257,7 +261,9 @@ * data from the heap file. * It is assumed the heap_fd is already positioned appropriately. */ -int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb) { +int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context) { + int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); + void *modulecontext[modulecount]; int r, i; size_t bsize, def_bsize; int64_t fsize, inc = 0, seekoff; @@ -265,6 +271,8 @@ const char *opt; char *tmpstr = NULL; + memset(modulecontext, 0, sizeof(void*)*modulecount); + opt = xar_opt_get(x, "rsize"); if( !opt ) { def_bsize = 4096; @@ -279,7 +287,7 @@ xar_prop_get(f, tmpstr, &opt); free(tmpstr); if( !opt ) { - wcb(x, f, NULL, 0); + wcb(x, f, NULL, 0, context); return 0; } else { seekoff = strtoll(opt, NULL, 0); @@ -365,26 +373,30 @@ bsize = r; /* filter the data through the in modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_in ) { int32_t ret; - ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize); + ret = xar_datamods[i].fh_in(x, f, attr, &inbuf, &bsize, &modulecontext[i]); if( ret < 0 ) return -1; } } - + + /* skip the write phase, if there is no write function to call */ + if(!wcb) + continue; + /* filter the data through the out modules */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_out ) { int32_t ret; - ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize); + ret = xar_datamods[i].fh_out(x, f, attr, inbuf, bsize, &modulecontext[i]); if( ret < 0 ) return -1; } } - wcb(x, f, inbuf, bsize); + wcb(x, f, inbuf, bsize, context); free(inbuf); bsize = def_bsize; inbuf = malloc(bsize); @@ -392,10 +404,10 @@ free(inbuf); /* finish up anything that still needs doing */ - for( i = 0; i < (sizeof(xar_datamods)/sizeof(struct datamod)); i++) { + for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_done ) { int32_t ret; - ret = xar_datamods[i].fh_done(x, f, attr); + ret = xar_datamods[i].fh_done(x, f, attr, &modulecontext[i]); if( ret < 0 ) return ret; } diff -urN xar/lib/io.h xar.context/lib/io.h --- xar/lib/io.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/io.h 2006-03-17 11:13:52.000000000 -0800 @@ -34,16 +34,16 @@ #ifndef _XAR_IO_H_ #define _XAR_IO_H_ -typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t); -typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t); +typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context); +typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context); -typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen); -typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr); - -typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen); -typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr); +typedef int (*fromheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +typedef int (*fromheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context); +typedef int (*fromheap_done)(xar_t x, xar_file_t f, const char *attr, void **context); + +typedef int (*toheap_in)(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +typedef int (*toheap_out)(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context); +typedef int (*toheap_done)(xar_t x, xar_file_t f, const char *attr, void **context); struct datamod { fromheap_in fh_in; @@ -54,8 +54,8 @@ toheap_done th_done; }; -int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb); -int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb); +int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, const char *attr, read_callback rcb, void *context); +int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, const char *attr, write_callback wcb, void *context); int32_t xar_heap_to_archive(xar_t x); #endif /* _XAR_IO_H_ */ diff -urN xar/lib/linuxattr.c xar.context/lib/linuxattr.c --- xar/lib/linuxattr.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/linuxattr.c 2006-03-17 11:14:35.000000000 -0800 @@ -77,49 +77,54 @@ #endif #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__) -static const char *Gfile = NULL; -static const char *Gattr = NULL; -static void *Gbuf = NULL; -static int Goff = 0; -static int Gbufsz = 0; -int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len) { - - if( !Gbuf ) { +struct _linuxattr_context{ + const char *file; + const char *attr; + void *buf; + int off = 0; + int bufsz = 0; +}; + +#define LINUXATTR_CONTEXT(x) ((struct _linuxattr_context *)(x)) + +int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len, void *context) { + + if( !LINUXATTR_CONTEXT(context)->buf ) { int r; - Gbufsz = 1024; + LINUXATTR_CONTEXT(context)->bufsz = 1024; AGAIN2: - Gbuf = malloc(Gbufsz); - if(!Gbuf) + LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz); + if(!LINUXATTR_CONTEXT(context)->buf) goto AGAIN2; - memset(Gbuf, 0, Gbufsz); - r = lgetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, Gbuf, Gbufsz); + memset(LINUXATTR_CONTEXT(context)->buf, 0, LINUXATTR_CONTEXT(context)->bufsz); + r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, LINUXATTR_CONTEXT(context)->buf, LINUXATTR_CONTEXT(context)->bufsz); if( r < 0 ) { switch(errno) { - case ERANGE: Gbufsz *= 2; free(Gbuf); goto AGAIN2; - case ENOTSUP: free(Gbuf); return 0; + case ERANGE: LINUXATTR_CONTEXT(context)->bufsz *= 2; free(LINUXATTR_CONTEXT(context)->buf); goto AGAIN2; + case ENOTSUP: free(LINUXATTR_CONTEXT(context)->buf); return 0; default: break; }; return -1; } - Gbufsz = r; + LINUXATTR_CONTEXT(context)->bufsz = r; } - if( (Gbufsz-Goff) <= len ) { + if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) { int32_t ret; - ret = Gbufsz - Goff; - memcpy(buf, Gbuf+Goff, ret); - Goff += ret; + ret = LINUXATTR_CONTEXT(context)->bufsz - LINUXATTR_CONTEXT(context)->off; + memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, ret); + LINUXATTR_CONTEXT(context)->off += ret; return(ret); } else { - memcpy(buf, Gbuf+Goff, len); - Gbuf += len; + memcpy(buf, LINUXATTR_CONTEXT(context)->buf+LINUXATTR_CONTEXT(context)->off, len); + LINUXATTR_CONTEXT(context)->buf += len; return len; } } -int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len) { - return lsetxattr(Gfile, Gattr+strlen(XAR_EA_FORK)+1, buf, len, 0); +int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { + return lsetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attr+strlen(XAR_EA_FORK)+1, buf, len, 0); } #endif @@ -130,7 +135,10 @@ int ret, retval=0, bufsz = 1024; struct statfs sfs; char *fsname = NULL; - + struct _linuxattr_context context; + + memset(&context,0,sizeof(struct _linuxattr_context)); + TRYAGAIN: buf = malloc(bufsz); if(!buf) @@ -159,18 +167,18 @@ for( i=buf; (i-buf) < ret; i += strlen(i)+1 ) { char tmpnam[1024]; - Gbufsz = 0; - Goff = 0; - Gbuf = NULL; - Gfile = file; + LINUXATTR_CONTEXT(context)->bufsz = 0; + LINUXATTR_CONTEXT(context)->off = 0; + LINUXATTR_CONTEXT(context)->buf = NULL; + LINUXATTR_CONTEXT(context)->file = file; memset(tmpnam, 0, sizeof(tmpnam)); snprintf(tmpnam, sizeof(tmpnam)-1, "%s/%s", XAR_EA_FORK, i); xar_prop_set(f, tmpnam, NULL); xar_attr_set(f, tmpnam, "fstype", fsname); - Gattr = tmpnam; + LINUXATTR_CONTEXT(context)->attr = tmpnam; xar_attrcopy_to_heap(x, f, tmpnam, xar_linuxattr_read); - free(Gbuf); - Gattr = NULL; + free(LINUXATTR_CONTEXT(context)->buf); + LINUXATTR_CONTEXT(context)->attr = NULL; } BAIL: @@ -188,8 +196,10 @@ struct statfs sfs; int eaopt = 0; xar_iter_t iter; - - + struct _linuxattr_context context; + + memset(&context,0,sizeof(struct _linuxattr_context)); + /* Check for EA extraction behavior */ memset(&sfs, 0, sizeof(sfs)); @@ -223,8 +233,8 @@ if( !fs ) continue; - Gfile = file; - Gattr = prop; + LINUXATTR_CONTEXT(context)->file = file; + LINUXATTR_CONTEXT(context)->attr = prop; xar_attrcopy_from_heap(x, f, prop, xar_linuxattr_write); } diff -urN xar/lib/macho.c xar.context/lib/macho.c --- xar/lib/macho.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/macho.c 2006-03-17 11:15:23.000000000 -0800 @@ -21,14 +21,17 @@ int32_t offset; }; -static int initted = 0; -static struct arches *inflight = NULL; -static int32_t numarches = 0; -static int32_t curroffset = 0; +struct _macho_context{ + struct arches *inflight; + int32_t numarches; + int32_t curroffset; +}; + +#define MACHO_CONTEXT(x) ((struct _macho_context *)(*x)) static int32_t parse_arch(xar_file_t f, struct mach_header *mh); -int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { struct mach_header *mh = *in; struct fat_header *fh = *in; uint32_t magic; @@ -37,62 +40,69 @@ if( strcmp(attr, "data") != 0 ) return 0; - if( initted && (inflight != NULL) ) - return 0; - + if(!MACHO_CONTEXT(context)) + *context = calloc(1,sizeof(struct _macho_context)); + else + return 0; /*We only run for the first part of the data stream*/ + /* First, check for fat */ magic = htonl(fh->magic); if( magic == 0xcafebabe ) { struct fat_arch *fa = (struct fat_arch *)((unsigned char *)*in + sizeof(struct fat_header)); - numarches = htonl(fh->nfat_arch); + MACHO_CONTEXT(context)->numarches = htonl(fh->nfat_arch); /* sanity check, arbitrary number */ - if( numarches > 7 ) + if( MACHO_CONTEXT(context)->numarches > 7 ) return 0; xar_prop_set(f, "contents/type", "Mach-O Fat File"); - inflight = malloc( numarches * sizeof(struct arches) ); - if( !inflight ) + MACHO_CONTEXT(context)->inflight = malloc( MACHO_CONTEXT(context)->numarches * sizeof(struct arches) ); + if( !MACHO_CONTEXT(context)->inflight ){ + free(*context); return -1; + } - for( i = 0; i < numarches; ++i ) { + for( i = 0; i < MACHO_CONTEXT(context)->numarches; ++i ) { int32_t sz = htonl(fa[i].size); int32_t off = htonl(fa[i].offset); - inflight[i].size = sz; - inflight[i].offset = off; + MACHO_CONTEXT(context)->inflight[i].size = sz; + MACHO_CONTEXT(context)->inflight[i].offset = off; } - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } - if( inflight ) { - for(i = 0; i < numarches; ++i) { - if( (inflight[i].offset >= curroffset) && (inflight[i].offset < (curroffset+*inlen)) ) { + if( MACHO_CONTEXT(context)->inflight ) { + for(i = 0; i < MACHO_CONTEXT(context)->numarches; ++i) { + if( (MACHO_CONTEXT(context)->inflight[i].offset >= MACHO_CONTEXT(context)->curroffset) && + (MACHO_CONTEXT(context)->inflight[i].offset < (MACHO_CONTEXT(context)->curroffset+*inlen)) ) { - mh = (struct mach_header *)((char *)*in + (inflight[i].offset - curroffset)); + mh = (struct mach_header *)((char *)*in + + (MACHO_CONTEXT(context)->inflight[i].offset - MACHO_CONTEXT(context)->curroffset)); parse_arch(f, mh); } } - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } parse_arch(f, mh); - curroffset += *inlen; + MACHO_CONTEXT(context)->curroffset += *inlen; return 0; } -int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr) { - if( inflight ) - free(inflight); - inflight = NULL; - curroffset = 0; - numarches = 0; - initted = 0; +int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context) { + + if( MACHO_CONTEXT(context) ){ + if( MACHO_CONTEXT(context)->inflight ) + free(MACHO_CONTEXT(context)->inflight); + free(*context); + } + return 0; } diff -urN xar/lib/macho.h xar.context/lib/macho.h --- xar/lib/macho.h 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/macho.h 2006-03-17 11:15:27.000000000 -0800 @@ -31,7 +31,7 @@ uint32_t alighn; }; -int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr); +int32_t xar_macho_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +int32_t xar_macho_done(xar_t x, xar_file_t f, const char *attr, void **context); #endif /* _MACHO_H_ */ diff -urN xar/lib/md5.c xar.context/lib/md5.c --- xar/lib/md5.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/md5.c 2006-03-17 11:38:29.000000000 -0800 @@ -11,77 +11,112 @@ #endif #include "xar.h" -static EVP_MD_CTX src_ctx, dst_ctx; -static int initted = 0; +struct _md5_context{ + EVP_MD_CTX src_ctx; + EVP_MD_CTX dst_ctx; + uint8_t src; + uint8_t dst; +}; + +#define CONTEXT(x) ((struct _md5_context *)(*x)) static char* xar_format_md5(const unsigned char* m); -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { const EVP_MD *md; - - if( !initted ) { + + if(!context) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _md5_context)); OpenSSL_add_all_digests(); + } + + if( !CONTEXT(context)->src ){ md = EVP_get_digestbyname("md5"); if( md == NULL ) return -1; - EVP_DigestInit(&src_ctx, md); - EVP_DigestInit(&dst_ctx, md); - initted = 1; + EVP_DigestInit(&(CONTEXT(context)->src_ctx), md); + CONTEXT(context)->src = 1; } - + if( *inlen == 0 ) return 0; - - EVP_DigestUpdate(&src_ctx, *in, *inlen); + + EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), *in, *inlen); return 0; } -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen) { +int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context) { const EVP_MD *md; - - if( !initted ) { + + if(!context) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _md5_context)); OpenSSL_add_all_digests(); + } + + if( !CONTEXT(context)->dst ){ md = EVP_get_digestbyname("md5"); if( md == NULL ) return -1; - EVP_DigestInit(&src_ctx, md); - EVP_DigestInit(&dst_ctx, md); - initted = 1; + EVP_DigestInit(&(CONTEXT(context)->dst_ctx), md); + CONTEXT(context)->dst = 1; } - + if( inlen == 0 ) return 0; - - EVP_DigestUpdate(&dst_ctx, in, inlen); + + EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), in, inlen); return 0; } -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr) { +int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr, void **context) { unsigned char md5str[EVP_MAX_MD_SIZE]; char *str, *tmpstr; unsigned int len; - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&src_ctx, md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/extracted-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); + + if(!CONTEXT(context)) + return 0; + + if( CONTEXT(context)->src ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->src_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + + memset(md5str, 0, sizeof(md5str)); + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); + str = xar_format_md5(md5str); + asprintf(&tmpstr, "%s/extracted-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", "md5"); + } + free(tmpstr); + free(str); } - free(tmpstr); - free(str); - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&dst_ctx, md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/archived-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); + + if( CONTEXT(context)->dst ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->dst_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + + memset(md5str, 0, sizeof(md5str)); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); + str = xar_format_md5(md5str); + asprintf(&tmpstr, "%s/archived-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", "md5"); + } + free(tmpstr); + free(str); } - free(tmpstr); - free(str); - - initted = 0; + + if(*context){ + free(*context); + *context = NULL; + } + return 0; } @@ -99,33 +134,46 @@ return result; } -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr) { +int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr, void **context) { const char *uncomp, *uncompstyle; unsigned char md5str[EVP_MAX_MD_SIZE]; unsigned int len; char *tmpstr; - + + if(!CONTEXT(context)) + return 0; + + if( !(CONTEXT(context)->dst || CONTEXT(context)->src) ){ + return 0; + } + asprintf(&tmpstr, "%s/extracted-checksum", attr); xar_prop_get(f, tmpstr, &uncomp); uncompstyle = xar_attr_get(f, tmpstr, "style"); free(tmpstr); - - if( uncomp && uncompstyle && (strcmp(uncompstyle, "md5")==0) ) { + + if( uncomp && uncompstyle && CONTEXT(context)->dst ) { char *str; memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&dst_ctx, md5str, &len); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); str = xar_format_md5(md5str); if(strcmp(uncomp, str) != 0) { xar_err_new(x); xar_err_set_file(x, f); - xar_err_set_string(x, "extracted-checksum MD5's do not match"); + asprintf(&tmpstr, "extracted-checksum MD5's do not match"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); } free(str); } - - EVP_DigestFinal(&src_ctx, md5str, &len); - initted = 0; - + + if( CONTEXT(context)->src ) + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); + + if(*context){ + free(*context); + *context = NULL; + } + return 0; + } diff -urN xar/lib/md5.h xar.context/lib/md5.h --- xar/lib/md5.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/md5.h 2006-03-17 11:32:14.000000000 -0800 @@ -34,9 +34,9 @@ #ifndef _XAR_MD5_H_ #define _XAR_MD5_H_ -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen); -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *); -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *); +int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen, void **context); +int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int32_t xar_md5_done(xar_t x, xar_file_t f, const char *, void **context); +int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_MD5_H_ */ diff -urN xar/lib/script.c xar.context/lib/script.c --- xar/lib/script.c 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/script.c 2006-03-17 11:15:45.000000000 -0800 @@ -9,14 +9,25 @@ #endif #include "xar.h" -static int initted = 0; +struct _script_context{ + int initted; +}; -int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +#define SCRIPT_CONTEXT(x) ((struct _script_context*)(*x)) + +int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { char *buf = *in; - if( initted ) + if(!SCRIPT_CONTEXT(context)){ + *context = calloc(1,sizeof(struct _script_context)); + } + + if( SCRIPT_CONTEXT(context)->initted ) return 0; + /*We only run on the begining of the file, so once we init, we don't run again*/ + SCRIPT_CONTEXT(context)->initted = 1; + if( (*inlen > 2) && (buf[0] == '#') && (buf[1] == '!') ) { char *exe; int i; @@ -37,7 +48,16 @@ return 0; } -int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr) { - initted = 0; +int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context) { + + if(!SCRIPT_CONTEXT(context)){ + return 0; + } + + if( *context ){ + free(*context); + *context = NULL; + } + return 0; } diff -urN xar/lib/script.h xar.context/lib/script.h --- xar/lib/script.h 2006-02-23 23:05:04.000000000 -0800 +++ xar.context/lib/script.h 2006-03-17 11:15:48.000000000 -0800 @@ -1,7 +1,7 @@ #ifndef _SCRIPT_H_ #define _SCRIPT_H_ -int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen); -int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr); +int32_t xar_script_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context); +int32_t xar_script_done(xar_t x, xar_file_t f, const char *attr, void **context); #endif /* _SCRIPT_H_ */ diff -urN xar/lib/zxar.c xar.context/lib/zxar.c --- xar/lib/zxar.c 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/zxar.c 2006-03-17 11:16:23.000000000 -0800 @@ -44,12 +44,10 @@ #include "filetree.h" #include "io.h" -static int initted = 0; -static z_stream zs; +#define GZIP_CONTEXT(x) ((z_stream *)(*x)) +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context); -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr); - -int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { const char *opt; void *out = NULL; size_t outlen, offset = 0; @@ -62,31 +60,27 @@ if( !opt ) return 0; if( strcmp(opt, "application/x-gzip") != 0 ) return 0; - if( !initted ) { - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - - inflateInit(&zs); - initted = 1; + if( !GZIP_CONTEXT(context) ) { + *context = calloc(1,sizeof(z_stream)); + inflateInit(GZIP_CONTEXT(context)); } outlen = *inlen; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + GZIP_CONTEXT(context)->next_in = *in; + GZIP_CONTEXT(context)->avail_in = *inlen; + GZIP_CONTEXT(context)->next_out = out; + GZIP_CONTEXT(context)->avail_out = 0; - while( zs.avail_in != 0 ) { + while( GZIP_CONTEXT(context)->avail_in != 0 ) { outlen = outlen * 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + GZIP_CONTEXT(context)->next_out = out + offset; + GZIP_CONTEXT(context)->avail_out = outlen - offset; - r = inflate(&zs, Z_SYNC_FLUSH); + r = inflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH); if( (r != Z_OK) && (r != Z_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); @@ -94,11 +88,11 @@ xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } - offset += outlen - offset - zs.avail_out; + offset += outlen - offset - GZIP_CONTEXT(context)->avail_out; if( (r == Z_STREAM_END) && (offset == 0) ) { - //r = inflate(&zs, Z_FINISH); - xar_gzip_fromheap_done(x, f, attr); - offset += outlen - offset - zs.avail_out; + //r = inflate(GZIP_CONTEXT(context), Z_FINISH); + xar_gzip_fromheap_done(x, f, attr, context); + offset += outlen - offset - GZIP_CONTEXT(context)->avail_out; break; } } @@ -109,12 +103,17 @@ return 0; } -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr) { - initted = 0; - inflateEnd(&zs); +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { + inflateEnd(GZIP_CONTEXT(context)); + + if(GZIP_CONTEXT(context)){ + free(GZIP_CONTEXT(context)); + *context = NULL; + } + return 0; } -int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr) { +int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *attr, void **context) { const char *opt; char *tmpstr; @@ -124,10 +123,14 @@ if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 ) return 0; + + deflateEnd(GZIP_CONTEXT(context)); - initted = 0; - deflateEnd(&zs); - + if(GZIP_CONTEXT(context)){ + free(GZIP_CONTEXT(context)); + *context = NULL; + } + asprintf(&tmpstr, "%s/encoding", attr); if( f ) { xar_prop_set(f, tmpstr, NULL); @@ -138,7 +141,7 @@ return 0; } -int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen) { +int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { void *out = NULL; size_t outlen, offset = 0; int r; @@ -151,33 +154,32 @@ if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 ) return 0; - if( !initted ) { - memset(&zs, 0, sizeof(zs)); - deflateInit(&zs, Z_BEST_COMPRESSION); - initted = 1; + if( !GZIP_CONTEXT(context) ) { + *context = calloc(1,sizeof(z_stream)); + deflateInit(GZIP_CONTEXT(context), Z_BEST_COMPRESSION); } - + outlen = *inlen/2; if(outlen == 0) outlen = 1024; - zs.next_in = *in; - zs.avail_in = *inlen; - zs.next_out = out; - zs.avail_out = 0; + GZIP_CONTEXT(context)->next_in = *in; + GZIP_CONTEXT(context)->avail_in = *inlen; + GZIP_CONTEXT(context)->next_out = out; + GZIP_CONTEXT(context)->avail_out = 0; do { outlen *= 2; out = realloc(out, outlen); if( out == NULL ) abort(); - zs.next_out = out + offset; - zs.avail_out = outlen - offset; + GZIP_CONTEXT(context)->next_out = out + offset; + GZIP_CONTEXT(context)->avail_out = outlen - offset; if( *inlen == 0 ) - r = deflate(&zs, Z_FINISH); + r = deflate(GZIP_CONTEXT(context), Z_FINISH); else - r = deflate(&zs, Z_SYNC_FLUSH); - offset = outlen - zs.avail_out; - } while( zs.avail_in != 0 ); + r = deflate(GZIP_CONTEXT(context), Z_SYNC_FLUSH); + offset = outlen - GZIP_CONTEXT(context)->avail_out; + } while( GZIP_CONTEXT(context)->avail_in != 0 ); free(*in); *in = out; diff -urN xar/lib/zxar.h xar.context/lib/zxar.h --- xar/lib/zxar.h 2006-02-17 11:27:10.000000000 -0800 +++ xar.context/lib/zxar.h 2006-03-17 11:16:27.000000000 -0800 @@ -34,10 +34,10 @@ #ifndef _XAR_ZLIB_H_ #define _XAR_ZLIB_H_ -int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *); +int xar_gzip_fromheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_gzip_fromheap_done(xar_t x, xar_file_t f, const char *, void **context); -int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen); -int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *); +int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int xar_gzip_toheap_done(xar_t x, xar_file_t f, const char *, void **context); #endif /* _XAR_ZLIB_H_ */ xar-xar-498/patches/hash.diff000066400000000000000000000375741446633275300162230ustar00rootroot00000000000000diff -urN xar/include/xar.h.in xar.hash/include/xar.h.in --- xar/include/xar.h.in 2006-03-19 20:57:56.000000000 -0800 +++ xar.hash/include/xar.h.in 2006-03-19 20:58:35.000000000 -0800 @@ -38,6 +38,7 @@ #include #include +#include struct xar_header { uint32_t magic; @@ -71,7 +72,8 @@ #define XAR_OPT_VAL_SYMBOLIC "symbolic" /* set owner/group based on names */ #define XAR_OPT_VAL_NUMERIC "numeric" /* set owner/group based on uid/gid */ -#define XAR_OPT_TOCCKSUM "toc-cksum" /* set the toc checksum algorithm */ +#define XAR_OPT_TOCCKSUM "toc-cksum" /* set the toc checksum algorithm */ +#define XAR_OPT_FILECKSUM "file-chksum" /* set the file checksum algorithm */ #define XAR_OPT_VAL_NONE "none" #define XAR_OPT_VAL_SHA1 "sha1" #define XAR_OPT_VAL_MD5 "md5" diff -urN xar/lib/Makefile.inc.in xar.hash/lib/Makefile.inc.in --- xar/lib/Makefile.inc.in 2006-03-19 20:57:56.000000000 -0800 +++ xar.hash/lib/Makefile.inc.in 2006-03-19 20:58:35.000000000 -0800 @@ -16,7 +16,7 @@ # Sources. LIBXAR_SRCS := archive.c arcmod.c b64.c bzxar.c darwinattr.c data.c err.c -LIBXAR_SRCS += ext2.c fbsdattr.c filetree.c io.c linuxattr.c md5.c stat.c +LIBXAR_SRCS += ext2.c fbsdattr.c filetree.c io.c linuxattr.c hash.c stat.c LIBXAR_SRCS += subdoc.c util.c zxar.c script.c macho.c LIBXAR_SRCS := $(patsubst %, @srcroot@lib/%, $(LIBXAR_SRCS)) diff -urN xar/lib/hash.c xar.hash/lib/hash.c --- xar/lib/hash.c 1969-12-31 16:00:00.000000000 -0800 +++ xar.hash/lib/hash.c 2006-03-19 20:58:51.000000000 -0800 @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#ifndef HAVE_ASPRINTF +#include "asprintf.h" +#endif +#include "xar.h" + + +struct _hash_context{ + EVP_MD_CTX src_ctx; + EVP_MD_CTX dst_ctx; + uint8_t src; + uint8_t dst; +}; + +#define CONTEXT(x) ((struct _hash_context *)(*x)) + +static char* xar_format_hash(const unsigned char* m,unsigned int len); + +int32_t xar_hash_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { + const char *opt; + char *tmpstr; + const EVP_MD *md; + + if(!context) + return 0; + + asprintf(&tmpstr, "%s/extracted-checksum", attr); + opt = xar_attr_get(f, tmpstr, "style"); + free(tmpstr); + + if( !opt ) + opt = xar_opt_get(x, XAR_OPT_FILECKSUM); + + if( !opt || (0 == strcmp(opt, XAR_OPT_VAL_NONE) ) ) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _hash_context)); + OpenSSL_add_all_digests(); + } + + if( !CONTEXT(context)->src ){ + md = EVP_get_digestbyname(opt); + if( md == NULL ) return -1; + EVP_DigestInit(&(CONTEXT(context)->src_ctx), md); + CONTEXT(context)->src = 1; + } + + if( *inlen == 0 ) + return 0; + + EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), *in, *inlen); + return 0; +} + +int32_t xar_hash_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context) { + const char *opt; + const EVP_MD *md; + char *tmpstr; + + if(!context) + return 0; + + asprintf(&tmpstr, "%s/archived-checksum", attr); + opt = xar_attr_get(f, tmpstr, "style"); + free(tmpstr); + + if( !opt ) + opt = xar_opt_get(x, XAR_OPT_FILECKSUM); + + if( !opt || (0 == strcmp(opt, XAR_OPT_VAL_NONE) ) ) + return 0; + + if(!CONTEXT(context)){ + *context = calloc(1,sizeof(struct _hash_context)); + OpenSSL_add_all_digests(); + } + + if ( !CONTEXT(context)->dst ){ + md = EVP_get_digestbyname(opt); + if( md == NULL ) return -1; + EVP_DigestInit(&(CONTEXT(context)->dst_ctx), md); + CONTEXT(context)->dst = 1; + } + + if( inlen == 0 ) + return 0; + + EVP_DigestUpdate(&(CONTEXT(context)->dst_ctx), in, inlen); + return 0; +} + +int32_t xar_hash_done(xar_t x, xar_file_t f, const char *attr, void **context) { + unsigned char hashstr[EVP_MAX_MD_SIZE]; + char *str, *tmpstr; + unsigned int len; + + if(!CONTEXT(context)) + return 0; + + if( CONTEXT(context)->src ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->src_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + const char *type = EVP_MD_name(md); + + memset(hashstr, 0, sizeof(hashstr)); + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), hashstr, &len); + str = xar_format_hash(hashstr,len); + asprintf(&tmpstr, "%s/extracted-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", type); + } + free(tmpstr); + free(str); + } + + if( CONTEXT(context)->dst ){ + EVP_MD_CTX *ctx = &CONTEXT(context)->dst_ctx; + const EVP_MD *md = EVP_MD_CTX_md(ctx); + const char *type = EVP_MD_name(md); + + memset(hashstr, 0, sizeof(hashstr)); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), hashstr, &len); + str = xar_format_hash(hashstr,len); + asprintf(&tmpstr, "%s/archived-checksum", attr); + if( f ) { + xar_prop_set(f, tmpstr, str); + xar_attr_set(f, tmpstr, "style", type); + } + free(tmpstr); + free(str); + } + + if(*context){ + free(*context); + *context = NULL; + } + + return 0; +} + +static char* xar_format_hash(const unsigned char* m,unsigned int len) { + char* result = malloc((2*len)+1); + char hexValue[3]; + unsigned int itr = 0; + + result[0] = '\0'; + + for(itr = 0;itr < len;itr++){ + sprintf(hexValue,"%02x",m[itr]); + strncat(result,hexValue,2); + } + + return result; +} + +int32_t xar_hash_out_done(xar_t x, xar_file_t f, const char *attr, void **context) { + const char *uncomp, *uncompstyle; + unsigned char hashstr[EVP_MAX_MD_SIZE]; + unsigned int len; + char *tmpstr; + const EVP_MD *md; + + if(!CONTEXT(context)) + return 0; + + if( !(CONTEXT(context)->dst || CONTEXT(context)->src) ){ + return 0; + } + + asprintf(&tmpstr, "%s/extracted-checksum", attr); + xar_prop_get(f, tmpstr, &uncomp); + uncompstyle = xar_attr_get(f, tmpstr, "style"); + free(tmpstr); + + md = EVP_get_digestbyname(uncompstyle); + + if( uncomp && uncompstyle && md && CONTEXT(context)->dst ) { + char *str; + memset(hashstr, 0, sizeof(hashstr)); + EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), hashstr, &len); + str = xar_format_hash(hashstr,len); + if(strcmp(uncomp, str) != 0) { + xar_err_new(x); + xar_err_set_file(x, f); + asprintf(&tmpstr, "extracted-checksum %s's do not match",uncompstyle); + xar_err_set_string(x, tmpstr); + xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); + } + free(str); + } + + if( CONTEXT(context)->src ) + EVP_DigestFinal(&(CONTEXT(context)->src_ctx), hashstr, &len); + + if(*context){ + free(*context); + *context = NULL; + } + + return 0; +} diff -urN xar/lib/hash.h xar.hash/lib/hash.h --- xar/lib/hash.h 1969-12-31 16:00:00.000000000 -0800 +++ xar.hash/lib/hash.h 2006-03-19 20:58:35.000000000 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005 Rob Braun + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Rob Braun nor the names of his contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * 03-Apr-2005 + * DRI: Rob Braun + */ + +#ifndef _XAR_HASH_H_ +#define _XAR_HASH_H_ + +int32_t xar_hash_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen, void **context); +int32_t xar_hash_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); +int32_t xar_hash_done(xar_t x, xar_file_t f, const char *, void **context); +int32_t xar_hash_out_done(xar_t x, xar_file_t f, const char *, void **context); + +#endif /* _XAR_HASH_H_ */ diff -urN xar/lib/io.c xar.hash/lib/io.c --- xar/lib/io.c 2006-03-19 20:58:13.000000000 -0800 +++ xar.hash/lib/io.c 2006-03-19 20:58:35.000000000 -0800 @@ -54,7 +54,7 @@ #include "io.h" #include "zxar.h" #include "bzxar.h" -#include "md5.h" +#include "hash.h" #include "script.h" #include "macho.h" @@ -68,11 +68,11 @@ struct datamod xar_datamods[] = { { (fromheap_in)NULL, - xar_md5_compressed, - xar_md5out_done, - xar_md5_uncompressed, - xar_md5_compressed, - xar_md5_done + xar_hash_compressed, + xar_hash_out_done, + xar_hash_uncompressed, + xar_hash_compressed, + xar_hash_done }, { (fromheap_in)NULL, (fromheap_out)NULL, diff -urN xar/lib/md5.c xar.hash/lib/md5.c --- xar/lib/md5.c 2006-03-19 20:58:13.000000000 -0800 +++ xar.hash/lib/md5.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,179 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "config.h" -#ifndef HAVE_ASPRINTF -#include "asprintf.h" -#endif -#include "xar.h" - -struct _md5_context{ - EVP_MD_CTX src_ctx; - EVP_MD_CTX dst_ctx; - uint8_t src; - uint8_t dst; -}; - -#define CONTEXT(x) ((struct _md5_context *)(*x)) - -static char* xar_format_md5(const unsigned char* m); - -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *attr, void **in, size_t *inlen, void **context) { - const EVP_MD *md; - - if(!context) - return 0; - - if(!CONTEXT(context)){ - *context = calloc(1,sizeof(struct _md5_context)); - OpenSSL_add_all_digests(); - } - - if( !CONTEXT(context)->src ){ - md = EVP_get_digestbyname("md5"); - if( md == NULL ) return -1; - EVP_DigestInit(&(CONTEXT(context)->src_ctx), md); - CONTEXT(context)->src = 1; - } - - if( *inlen == 0 ) - return 0; - - EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), *in, *inlen); - return 0; -} - -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *attr, void *in, size_t inlen, void **context) { - const EVP_MD *md; - - if(!context) - return 0; - - if(!CONTEXT(context)){ - *context = calloc(1,sizeof(struct _md5_context)); - OpenSSL_add_all_digests(); - } - - if( !CONTEXT(context)->dst ){ - md = EVP_get_digestbyname("md5"); - if( md == NULL ) return -1; - EVP_DigestInit(&(CONTEXT(context)->dst_ctx), md); - CONTEXT(context)->dst = 1; - } - - if( inlen == 0 ) - return 0; - - EVP_DigestUpdate(&(CONTEXT(context)->src_ctx), in, inlen); - return 0; -} - -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *attr, void **context) { - unsigned char md5str[EVP_MAX_MD_SIZE]; - char *str, *tmpstr; - unsigned int len; - - if(!CONTEXT(context)) - return 0; - - if( CONTEXT(context)->src ){ - EVP_MD_CTX *ctx = &CONTEXT(context)->src_ctx; - const EVP_MD *md = EVP_MD_CTX_md(ctx); - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/extracted-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); - } - free(tmpstr); - free(str); - } - - if( CONTEXT(context)->dst ){ - EVP_MD_CTX *ctx = &CONTEXT(context)->dst_ctx; - const EVP_MD *md = EVP_MD_CTX_md(ctx); - - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); - str = xar_format_md5(md5str); - asprintf(&tmpstr, "%s/archived-checksum", attr); - if( f ) { - xar_prop_set(f, tmpstr, str); - xar_attr_set(f, tmpstr, "style", "md5"); - } - free(tmpstr); - free(str); - } - - if(*context){ - free(*context); - *context = NULL; - } - - return 0; -} - -static char* xar_format_md5(const unsigned char* m) { - char* result = NULL; - asprintf(&result, - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x", - m[0], m[1], m[2], m[3], - m[4], m[5], m[6], m[7], - m[8], m[9], m[10], m[11], - m[12], m[13], m[14], m[15]); - return result; -} - -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *attr, void **context) { - const char *uncomp, *uncompstyle; - unsigned char md5str[EVP_MAX_MD_SIZE]; - unsigned int len; - char *tmpstr; - - if(!CONTEXT(context)) - return 0; - - if( !(CONTEXT(context)->dst || CONTEXT(context)->src) ){ - return 0; - } - - asprintf(&tmpstr, "%s/extracted-checksum", attr); - xar_prop_get(f, tmpstr, &uncomp); - uncompstyle = xar_attr_get(f, tmpstr, "style"); - free(tmpstr); - - if( uncomp && uncompstyle && CONTEXT(context)->dst ) { - char *str; - memset(md5str, 0, sizeof(md5str)); - EVP_DigestFinal(&(CONTEXT(context)->dst_ctx), md5str, &len); - str = xar_format_md5(md5str); - if(strcmp(uncomp, str) != 0) { - xar_err_new(x); - xar_err_set_file(x, f); - asprintf(&tmpstr, "extracted-checksum MD5's do not match"); - xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); - } - free(str); - } - - if( CONTEXT(context)->src ) - EVP_DigestFinal(&(CONTEXT(context)->src_ctx), md5str, &len); - - if(*context){ - free(*context); - *context = NULL; - } - - return 0; - -} diff -urN xar/lib/md5.h xar.hash/lib/md5.h --- xar/lib/md5.h 2006-03-19 20:58:13.000000000 -0800 +++ xar.hash/lib/md5.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2005 Rob Braun - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Rob Braun nor the names of his contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * 03-Apr-2005 - * DRI: Rob Braun - */ - -#ifndef _XAR_MD5_H_ -#define _XAR_MD5_H_ - -int32_t xar_md5_compressed(xar_t x, xar_file_t f, const char *, void *in, size_t inlen, void **context); -int32_t xar_md5_uncompressed(xar_t x, xar_file_t f, const char *, void **in, size_t *inlen, void **context); -int32_t xar_md5_done(xar_t x, xar_file_t f, const char *, void **context); -int32_t xar_md5out_done(xar_t x, xar_file_t f, const char *, void **context); - -#endif /* _XAR_MD5_H_ */ xar-xar-498/patches/noea.diff000066400000000000000000000013631446633275300162050ustar00rootroot00000000000000diff -urN xar/lib/darwinattr.c xar.patch/lib/darwinattr.c --- xar/lib/darwinattr.c 2006-03-16 11:45:21.000000000 -0800 +++ xar.patch/lib/darwinattr.c 2006-03-16 11:48:27.000000000 -0800 @@ -569,10 +569,6 @@ #if defined(__APPLE__) if( len ) return 0; -#if defined(HAVE_GETXATTR) - if( ea_archive(x, f, file, (void *)&context) == 0 ) - return 0; -#endif if( nonea_archive(x, f, file, (void *)&context) == 0 ) return 0; return underbar_archive(x, f, file, (void *)&context); @@ -589,11 +585,6 @@ #if defined(__APPLE__) if( len ) return 0; -#if defined(HAVE_GETXATTR) - if( ea_extract(x, f, file, (void *)&context) == 0 ) - return 0; -#endif - if( nonea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif /* __APPLE__ */ xar-xar-498/patches/static-lib.diff000066400000000000000000000024601446633275300173150ustar00rootroot00000000000000diff -urN xar/lib/Makefile.inc.in xar.change/lib/Makefile.inc.in --- xar/lib/Makefile.inc.in 2006-03-20 21:29:23.000000000 -0800 +++ xar.change/lib/Makefile.inc.in 2006-03-20 21:29:08.000000000 -0800 @@ -39,6 +39,12 @@ LIBXAR_SNAME := libxar.@LIB_REV@.dylib LIBXAR_LNAME := libxar.dylib LIBXAR_L := @objroot@lib/$(LIBXAR_LNAME) + +LIBXARSTATIC := libxar.a +LIBXARSTATIC_L := @objroot@lib/$(LIBXARSTATIC) + + + endif ifeq (aout, @abi@) LIBRXAR_SNAME := librxar.so.@LIB_REV@.0 @@ -64,11 +70,13 @@ lib_all : $(LIBRXAR_S) $(LIBXAR_S) -lib_install : $(LIBXAR_S) +lib_install : $(LIBXAR_S) $(LIBXARSTATIC) @INSTALL@ -d $(DESTDIR)$(INCLUDEDIR)/xar @INSTALL@ -m 0644 $(LIBXAR_INCS) $(DESTDIR)$(INCLUDEDIR)/xar @INSTALL@ -d $(DESTDIR)$(LIBDIR) @INSTALL@ -m 0444 $(LIBXAR_S) $(DESTDIR)$(LIBDIR) + @INSTALL@ -d $(DESTDIR)/usr/local/lib/ + @INSTALL@ -m 0444 $(LIBXARSTATIC) $(DESTDIR)/usr/local/lib/ ifneq ($(words "" $(LIBXAR_LNAME)), 1) rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_LNAME) ln -s $(LIBXAR_SNAME) $(DESTDIR)$(LIBDIR)/$(LIBXAR_LNAME) @@ -125,6 +133,7 @@ endif ifeq (macho, @abi@) $(CC) -dynamiclib -compatibility_version @LIB_REV@ -current_version @LIB_REV@ -install_name $(LIBDIR)/$(LIBXAR_SNAME) -o $@ $+ $(LDFLAGS) @LIBS@ + $(AR) cq $(LIBXARSTATIC) $+ endif ifeq (aout, @abi@) $(CC) -shared -o $@ $+ xar-xar-498/test_tools/000077500000000000000000000000001446633275300151765ustar00rootroot00000000000000xar-xar-498/test_tools/xar.tcl000066400000000000000000000043311446633275300164750ustar00rootroot00000000000000 big_endian requires 0 "78617221" ;# xar! ascii 4 "Signature" set headersize [uint16 "Header Size"] uint16 "Version" set compressed_length [uint64 "TOC Compressed Length"] uint64 "TOC Uncompressed Length" uint32 "Checksum" set compressed_data [bytes $compressed_length "TOC Data"] set xml [zlib_uncompress $compressed_data] #puts "${xml}" package require tdom set doc [dom parse $xml] set root [$doc documentElement] set hashes [$root selectNodes "//checksum"] set signatures [$root selectNodes "//signature"] section "Hashes" foreach hash $hashes { section [$hash getAttribute "style"] { set lengthString [[lindex [$hash getElementsByTagName "size"] 0] text] set offsetString [[lindex [$hash getElementsByTagName "offset"] 0] text] scan $lengthString "%d" length scan $offsetString "%d" heapoffset set offset [expr { $heapoffset + $headersize + $compressed_length}] entry "Checksum" "" $length $offset } } endsection section "Signatures" foreach signature $signatures { section [$signature getAttribute "style"] { set lengthString [[lindex [$signature getElementsByTagName "size"] 0] text] set offsetString [[lindex [$signature getElementsByTagName "offset"] 0] text] scan $lengthString "%d" length scan $offsetString "%d" heapoffset set offset [expr { $heapoffset + $headersize + $compressed_length}] entry "Signature Blob" "" $length $offset } } endsection set nodes [$root selectNodes "//file"] section "Files" { foreach node $nodes { section [[lindex [$node getElementsByTagName "name"] 0] text] { entry "ID" [$node getAttribute "id"] entry "Type" [[lindex [$node getElementsByTagName "type"] 0] text] set dataNode [lindex [$node getElementsByTagName "data"] 0] set compressedSizeString [[lindex [$dataNode getElementsByTagName "length"] 0] text] set offsetString [[lindex [$dataNode getElementsByTagName "offset"] 0] text] scan $compressedSizeString "%d" compressedSize scan $offsetString "%d" heapoffset set offset [expr { $heapoffset + $headersize + $compressed_length}] entry "Size" [[lindex [$dataNode getElementsByTagName "size"] 0] text] entry "Compressed Size" $compressedSizeString entry "Compressed Blob" "" $compressedSize $offset } } }xar-xar-498/xar.plist000066400000000000000000000014361446633275300146520ustar00rootroot00000000000000 OpenSourceLicense BSD OpenSourceLicenseFile xar.txt OpenSourceMD5 7f3976664a426911eab93cdf367894bc OpenSourceModifications 3397142 OpenSourceProject xar OpenSourceURL http://www.opendarwin.org/projects/xar/xar-1.4.tar.gz OpenSourceVersion 1.4 OpenSourceWebsiteURL http://www.opendarwin.org/projects/xar/ xar-xar-498/xar.txt000066400000000000000000000032251446633275300143340ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright (c) 2006 Apple Computer, Inc. */ xar-xar-498/xar.xcconfig000066400000000000000000000003201446633275300153060ustar00rootroot00000000000000// // xar.xcconfig // xar // // Created by Lucy Zhang on 1/30/19. // // Configuration settings file format documentation can be found at: // https://help.apple.com/xcode/#/dev745c5c974 IS_ZIPPERED = YES xar-xar-498/xar.xcodeproj/000077500000000000000000000000001446633275300155655ustar00rootroot00000000000000xar-xar-498/xar.xcodeproj/project.pbxproj000066400000000000000000001752771446633275300206640ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ B41FC04F09F6B76200006FAE /* configure */ = { isa = PBXAggregateTarget; buildConfigurationList = B41FC05109F6B77E00006FAE /* Build configuration list for PBXAggregateTarget "configure" */; buildPhases = ( B41FC04E09F6B76200006FAE /* ShellScript */, ); dependencies = ( ); name = configure; productName = configure; }; B41FC12109F6BEF900006FAE /* OpenSource */ = { isa = PBXAggregateTarget; buildConfigurationList = B41FC12709F6BF3300006FAE /* Build configuration list for PBXAggregateTarget "OpenSource" */; buildPhases = ( B41FC12009F6BEF900006FAE /* CopyFiles */, B41FC12209F6BF1600006FAE /* CopyFiles */, ); dependencies = ( ); name = OpenSource; productName = OpenSource; }; B41FC12F09F6BF5900006FAE /* All libraries */ = { isa = PBXAggregateTarget; buildConfigurationList = B41FC13709F6BF7900006FAE /* Build configuration list for PBXAggregateTarget "All libraries" */; buildPhases = ( ); dependencies = ( E9D7864E1D25A366006D5F7D /* PBXTargetDependency */, B41FC13109F6BF6300006FAE /* PBXTargetDependency */, B401A30309F6D71800B5C762 /* PBXTargetDependency */, ); name = "All libraries"; productName = All; }; E9D659A31486FD650089C4DA /* All tools */ = { isa = PBXAggregateTarget; buildConfigurationList = E9D659A41486FD650089C4DA /* Build configuration list for PBXAggregateTarget "All tools" */; buildPhases = ( ); dependencies = ( E91435421497E100001AA5EF /* PBXTargetDependency */, E9D659AA1486FD6D0089C4DA /* PBXTargetDependency */, E9D659A81486FD6A0089C4DA /* PBXTargetDependency */, ); name = "All tools"; productName = "All tools"; }; E9D659AB1486FFD10089C4DA /* All */ = { isa = PBXAggregateTarget; buildConfigurationList = E9D659AC1486FFD10089C4DA /* Build configuration list for PBXAggregateTarget "All" */; buildPhases = ( ); dependencies = ( E9D786501D25A4B1006D5F7D /* PBXTargetDependency */, E9D659B01486FFED0089C4DA /* PBXTargetDependency */, E9D659B21486FFED0089C4DA /* PBXTargetDependency */, E9D659B61486FFED0089C4DA /* PBXTargetDependency */, E9D659B81486FFED0089C4DA /* PBXTargetDependency */, ); name = All; productName = All; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 98665C6F0EA83E36008193F1 /* ea.c in Sources */ = {isa = PBXBuildFile; fileRef = 98665C6E0EA83E36008193F1 /* ea.c */; }; 98665C710EA83E44008193F1 /* lzmaxar.c in Sources */ = {isa = PBXBuildFile; fileRef = 98665C700EA83E44008193F1 /* lzmaxar.c */; }; B41FC09C09F6BC2C00006FAE /* archive.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07409F6BC2C00006FAE /* archive.c */; }; B41FC09E09F6BC2C00006FAE /* arcmod.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07609F6BC2C00006FAE /* arcmod.c */; }; B41FC0A109F6BC2C00006FAE /* b64.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07909F6BC2C00006FAE /* b64.c */; }; B41FC0A309F6BC2C00006FAE /* bzxar.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07B09F6BC2C00006FAE /* bzxar.c */; }; B41FC0A609F6BC2C00006FAE /* darwinattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07E09F6BC2C00006FAE /* darwinattr.c */; }; B41FC0A809F6BC2C00006FAE /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08009F6BC2C00006FAE /* data.c */; }; B41FC0AA09F6BC2C00006FAE /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08209F6BC2C00006FAE /* err.c */; }; B41FC0AB09F6BC2C00006FAE /* ext2.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08309F6BC2C00006FAE /* ext2.c */; }; B41FC0AD09F6BC2C00006FAE /* fbsdattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08509F6BC2C00006FAE /* fbsdattr.c */; }; B41FC0AF09F6BC2C00006FAE /* filetree.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08709F6BC2C00006FAE /* filetree.c */; }; B41FC0B109F6BC2C00006FAE /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08909F6BC2C00006FAE /* hash.c */; }; B41FC0B309F6BC2C00006FAE /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08B09F6BC2C00006FAE /* io.c */; }; B41FC0B509F6BC2C00006FAE /* linuxattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08D09F6BC2C00006FAE /* linuxattr.c */; }; B41FC0B909F6BC2C00006FAE /* script.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09109F6BC2C00006FAE /* script.c */; }; B41FC0BB09F6BC2C00006FAE /* stat.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09309F6BC2C00006FAE /* stat.c */; }; B41FC0BD09F6BC2C00006FAE /* subdoc.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09509F6BC2C00006FAE /* subdoc.c */; }; B41FC0BF09F6BC2C00006FAE /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09709F6BC2C00006FAE /* util.c */; }; B41FC0C109F6BC2C00006FAE /* zxar.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09909F6BC2C00006FAE /* zxar.c */; }; B41FC0C809F6BC7A00006FAE /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C409F6BC7A00006FAE /* libz.dylib */; }; B41FC0C909F6BC7A00006FAE /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C509F6BC7A00006FAE /* libbz2.dylib */; }; B41FC0CB09F6BC7A00006FAE /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C709F6BC7A00006FAE /* libxml2.dylib */; }; B41FC0E909F6BDAF00006FAE /* libxar.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC05F09F6B7C200006FAE /* libxar.1.dylib */; }; B41FC0EC09F6BDD900006FAE /* xar.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC0EB09F6BDD900006FAE /* xar.c */; }; B41FC0EF09F6BDF900006FAE /* xar.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B41FC0EA09F6BDD900006FAE /* xar.1 */; }; B41FC0F809F6BE9100006FAE /* archive.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07409F6BC2C00006FAE /* archive.c */; }; B41FC0F909F6BE9100006FAE /* arcmod.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07609F6BC2C00006FAE /* arcmod.c */; }; B41FC0FA09F6BE9100006FAE /* b64.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07909F6BC2C00006FAE /* b64.c */; }; B41FC0FB09F6BE9100006FAE /* bzxar.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07B09F6BC2C00006FAE /* bzxar.c */; }; B41FC0FC09F6BE9100006FAE /* darwinattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07E09F6BC2C00006FAE /* darwinattr.c */; }; B41FC0FD09F6BE9100006FAE /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08009F6BC2C00006FAE /* data.c */; }; B41FC0FE09F6BE9100006FAE /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08209F6BC2C00006FAE /* err.c */; }; B41FC0FF09F6BE9100006FAE /* ext2.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08309F6BC2C00006FAE /* ext2.c */; }; B41FC10009F6BE9100006FAE /* fbsdattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08509F6BC2C00006FAE /* fbsdattr.c */; }; B41FC10109F6BE9100006FAE /* filetree.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08709F6BC2C00006FAE /* filetree.c */; }; B41FC10209F6BE9100006FAE /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08909F6BC2C00006FAE /* hash.c */; }; B41FC10309F6BE9100006FAE /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08B09F6BC2C00006FAE /* io.c */; }; B41FC10409F6BE9100006FAE /* linuxattr.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC08D09F6BC2C00006FAE /* linuxattr.c */; }; B41FC10609F6BE9100006FAE /* script.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09109F6BC2C00006FAE /* script.c */; }; B41FC10709F6BE9100006FAE /* stat.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09309F6BC2C00006FAE /* stat.c */; }; B41FC10809F6BE9100006FAE /* subdoc.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09509F6BC2C00006FAE /* subdoc.c */; }; B41FC10909F6BE9100006FAE /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09709F6BC2C00006FAE /* util.c */; }; B41FC10A09F6BE9100006FAE /* zxar.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09909F6BC2C00006FAE /* zxar.c */; }; B41FC10B09F6BE9B00006FAE /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C409F6BC7A00006FAE /* libz.dylib */; }; B41FC10C09F6BE9B00006FAE /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C509F6BC7A00006FAE /* libbz2.dylib */; }; B41FC10E09F6BE9B00006FAE /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC0C709F6BC7A00006FAE /* libxml2.dylib */; }; B41FC12A09F6BF3700006FAE /* xar.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = B41FC12509F6BF3300006FAE /* xar.plist */; }; B41FC12B09F6BF3C00006FAE /* xar.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = B41FC12609F6BF3300006FAE /* xar.txt */; }; B476FACD0A49E68600BCD61F /* signature.c in Sources */ = {isa = PBXBuildFile; fileRef = B476FACC0A49E68600BCD61F /* signature.c */; }; B476FACF0A49E68600BCD61F /* signature.c in Sources */ = {isa = PBXBuildFile; fileRef = B476FACC0A49E68600BCD61F /* signature.c */; }; B4772CA30A003F7300E4205C /* xar.h in Copy Public Headers */ = {isa = PBXBuildFile; fileRef = B4772CA20A003F6E00E4205C /* xar.h */; }; C03E1E5225E72D3900AC0F53 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC09709F6BC2C00006FAE /* util.c */; }; C09ABF1D27157DE100542782 /* xar_internal.h in Copy Private Headers */ = {isa = PBXBuildFile; fileRef = C09ABF1A27157D1100542782 /* xar_internal.h */; }; E9C0E6741497DDAB00BF8F0F /* ea.h in Headers */ = {isa = PBXBuildFile; fileRef = E9C0E6731497DDAB00BF8F0F /* ea.h */; }; E9D786581D260606006D5F7D /* lzmaxar.c in Sources */ = {isa = PBXBuildFile; fileRef = 98665C700EA83E44008193F1 /* lzmaxar.c */; }; E9D7865D1D2606F9006D5F7D /* ea.c in Sources */ = {isa = PBXBuildFile; fileRef = 98665C6E0EA83E36008193F1 /* ea.c */; }; E9E06B8B219E252E004DB0CA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E9E06B8A219E252E004DB0CA /* main.m */; }; E9E06B90219E2542004DB0CA /* libxar.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC05F09F6B7C200006FAE /* libxar.1.dylib */; }; E9E06B91219E257D004DB0CA /* b64.c in Sources */ = {isa = PBXBuildFile; fileRef = B41FC07909F6BC2C00006FAE /* b64.c */; }; EEEFF3E60EFB700A00DBC955 /* xar-sig.c in Sources */ = {isa = PBXBuildFile; fileRef = EEEFF3DC0EFB6FC500DBC955 /* xar-sig.c */; }; EEEFF40E0EFB715100DBC955 /* libxar.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B41FC05F09F6B7C200006FAE /* libxar.1.dylib */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ B401A30209F6D71800B5C762 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC12109F6BEF900006FAE; remoteInfo = OpenSource; }; B41FC0D609F6BD0300006FAE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC04F09F6B76200006FAE; remoteInfo = configure; }; B41FC11E09F6BEDE00006FAE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC04F09F6B76200006FAE; remoteInfo = configure; }; B41FC13009F6BF6300006FAE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC05E09F6B7C200006FAE; remoteInfo = xarLib; }; E914353F1497E0F6001AA5EF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC04F09F6B76200006FAE; remoteInfo = configure; }; E91435411497E100001AA5EF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC04F09F6B76200006FAE; remoteInfo = configure; }; E9C0E6761497DE6000BF8F0F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC04F09F6B76200006FAE; remoteInfo = configure; }; E9D659A71486FD6A0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC0E109F6BD6800006FAE; remoteInfo = xarTool; }; E9D659A91486FD6D0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = EEEFF3DF0EFB6FD500DBC955; remoteInfo = xarsig; }; E9D659AF1486FFED0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC05E09F6B7C200006FAE; remoteInfo = xarLib; }; E9D659B11486FFED0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC0E109F6BD6800006FAE; remoteInfo = xarTool; }; E9D659B51486FFED0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC12109F6BEF900006FAE; remoteInfo = OpenSource; }; E9D659B71486FFED0089C4DA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = EEEFF3DF0EFB6FD500DBC955; remoteInfo = xarsig; }; E9D7864D1D25A366006D5F7D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC0F309F6BE2F00006FAE; remoteInfo = xarStatic; }; E9D7864F1D25A4B1006D5F7D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B41FC04109F6B74500006FAE /* Project object */; proxyType = 1; remoteGlobalIDString = B41FC0F309F6BE2F00006FAE; remoteInfo = xarStatic; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ B41FC0DC09F6BD2300006FAE /* Copy Public Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/include/xar; dstSubfolderSpec = 0; files = ( B4772CA30A003F7300E4205C /* xar.h in Copy Public Headers */, ); name = "Copy Public Headers"; runOnlyForDeploymentPostprocessing = 1; }; B41FC0ED09F6BDE400006FAE /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/share/man/man1; dstSubfolderSpec = 0; files = ( B41FC0EF09F6BDF900006FAE /* xar.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; B41FC12009F6BEF900006FAE /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/local/OpenSourceLicenses; dstSubfolderSpec = 0; files = ( B41FC12B09F6BF3C00006FAE /* xar.txt in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; B41FC12209F6BF1600006FAE /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/local/OpenSourceVersions; dstSubfolderSpec = 0; files = ( B41FC12A09F6BF3700006FAE /* xar.plist in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; C09ABF1C27157D9900542782 /* Copy Private Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/local/include/xar; dstSubfolderSpec = 0; files = ( C09ABF1D27157DE100542782 /* xar_internal.h in Copy Private Headers */, ); name = "Copy Private Headers"; runOnlyForDeploymentPostprocessing = 1; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 7C7F76CC2202351600155C33 /* xar.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = xar.xcconfig; sourceTree = ""; }; 98665C6E0EA83E36008193F1 /* ea.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ea.c; path = xar/lib/ea.c; sourceTree = ""; }; 98665C700EA83E44008193F1 /* lzmaxar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lzmaxar.c; path = xar/lib/lzmaxar.c; sourceTree = ""; }; B41FC05F09F6B7C200006FAE /* libxar.1.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libxar.1.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; B41FC07309F6BC2C00006FAE /* appledouble.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = appledouble.h; path = xar/lib/appledouble.h; sourceTree = ""; }; B41FC07409F6BC2C00006FAE /* archive.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = archive.c; path = xar/lib/archive.c; sourceTree = ""; }; B41FC07509F6BC2C00006FAE /* archive.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = archive.h; path = xar/lib/archive.h; sourceTree = ""; }; B41FC07609F6BC2C00006FAE /* arcmod.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = arcmod.c; path = xar/lib/arcmod.c; sourceTree = ""; }; B41FC07709F6BC2C00006FAE /* arcmod.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = arcmod.h; path = xar/lib/arcmod.h; sourceTree = ""; }; B41FC07809F6BC2C00006FAE /* asprintf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = asprintf.h; path = xar/lib/asprintf.h; sourceTree = ""; }; B41FC07909F6BC2C00006FAE /* b64.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = b64.c; path = xar/lib/b64.c; sourceTree = ""; }; B41FC07A09F6BC2C00006FAE /* b64.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = b64.h; path = xar/lib/b64.h; sourceTree = ""; }; B41FC07B09F6BC2C00006FAE /* bzxar.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bzxar.c; path = xar/lib/bzxar.c; sourceTree = ""; }; B41FC07C09F6BC2C00006FAE /* bzxar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = bzxar.h; path = xar/lib/bzxar.h; sourceTree = ""; }; B41FC07E09F6BC2C00006FAE /* darwinattr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = darwinattr.c; path = xar/lib/darwinattr.c; sourceTree = ""; }; B41FC07F09F6BC2C00006FAE /* darwinattr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = darwinattr.h; path = xar/lib/darwinattr.h; sourceTree = ""; }; B41FC08009F6BC2C00006FAE /* data.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = data.c; path = xar/lib/data.c; sourceTree = ""; }; B41FC08109F6BC2C00006FAE /* data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = data.h; path = xar/lib/data.h; sourceTree = ""; }; B41FC08209F6BC2C00006FAE /* err.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = err.c; path = xar/lib/err.c; sourceTree = ""; }; B41FC08309F6BC2C00006FAE /* ext2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ext2.c; path = xar/lib/ext2.c; sourceTree = ""; }; B41FC08409F6BC2C00006FAE /* ext2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ext2.h; path = xar/lib/ext2.h; sourceTree = ""; }; B41FC08509F6BC2C00006FAE /* fbsdattr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fbsdattr.c; path = xar/lib/fbsdattr.c; sourceTree = ""; }; B41FC08609F6BC2C00006FAE /* fbsdattr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fbsdattr.h; path = xar/lib/fbsdattr.h; sourceTree = ""; }; B41FC08709F6BC2C00006FAE /* filetree.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filetree.c; path = xar/lib/filetree.c; sourceTree = ""; }; B41FC08809F6BC2C00006FAE /* filetree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filetree.h; path = xar/lib/filetree.h; sourceTree = ""; }; B41FC08909F6BC2C00006FAE /* hash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hash.c; path = xar/lib/hash.c; sourceTree = ""; }; B41FC08A09F6BC2C00006FAE /* hash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hash.h; path = xar/lib/hash.h; sourceTree = ""; }; B41FC08B09F6BC2C00006FAE /* io.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = io.c; path = xar/lib/io.c; sourceTree = ""; }; B41FC08C09F6BC2C00006FAE /* io.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = io.h; path = xar/lib/io.h; sourceTree = ""; }; B41FC08D09F6BC2C00006FAE /* linuxattr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = linuxattr.c; path = xar/lib/linuxattr.c; sourceTree = ""; }; B41FC08E09F6BC2C00006FAE /* linuxattr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = linuxattr.h; path = xar/lib/linuxattr.h; sourceTree = ""; }; B41FC09109F6BC2C00006FAE /* script.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = script.c; path = xar/lib/script.c; sourceTree = ""; }; B41FC09209F6BC2C00006FAE /* script.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = script.h; path = xar/lib/script.h; sourceTree = ""; }; B41FC09309F6BC2C00006FAE /* stat.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stat.c; path = xar/lib/stat.c; sourceTree = ""; }; B41FC09409F6BC2C00006FAE /* stat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stat.h; path = xar/lib/stat.h; sourceTree = ""; }; B41FC09509F6BC2C00006FAE /* subdoc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = subdoc.c; path = xar/lib/subdoc.c; sourceTree = ""; }; B41FC09609F6BC2C00006FAE /* subdoc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = subdoc.h; path = xar/lib/subdoc.h; sourceTree = ""; }; B41FC09709F6BC2C00006FAE /* util.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = util.c; path = xar/lib/util.c; sourceTree = ""; }; B41FC09809F6BC2C00006FAE /* util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = util.h; path = xar/lib/util.h; sourceTree = ""; }; B41FC09909F6BC2C00006FAE /* zxar.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = zxar.c; path = xar/lib/zxar.c; sourceTree = ""; }; B41FC09A09F6BC2C00006FAE /* zxar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = zxar.h; path = xar/lib/zxar.h; sourceTree = ""; }; B41FC0C409F6BC7A00006FAE /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = ""; }; B41FC0C509F6BC7A00006FAE /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = /usr/lib/libbz2.dylib; sourceTree = ""; }; B41FC0C709F6BC7A00006FAE /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = /usr/lib/libxml2.dylib; sourceTree = ""; }; B41FC0E209F6BD6800006FAE /* xar */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xar; sourceTree = BUILT_PRODUCTS_DIR; }; B41FC0EA09F6BDD900006FAE /* xar.1 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.man; name = xar.1; path = xar/src/xar.1; sourceTree = ""; }; B41FC0EB09F6BDD900006FAE /* xar.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = xar.c; path = xar/src/xar.c; sourceTree = ""; }; B41FC0F409F6BE2F00006FAE /* libxarstatic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libxarstatic.a; sourceTree = BUILT_PRODUCTS_DIR; }; B41FC12409F6BF3300006FAE /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = ""; }; B41FC12509F6BF3300006FAE /* xar.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = xar.plist; sourceTree = ""; }; B41FC12609F6BF3300006FAE /* xar.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = xar.txt; sourceTree = ""; }; B41FC16309F6C56600006FAE /* config.h.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = config.h.in; path = xar/include/config.h.in; sourceTree = ""; }; B41FC16409F6C56600006FAE /* xar.h.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = xar.h.in; path = xar/include/xar.h.in; sourceTree = ""; }; B4657F1E0A49E6150074E45D /* signature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = signature.h; path = xar/lib/signature.h; sourceTree = ""; }; B476FACC0A49E68600BCD61F /* signature.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = signature.c; path = xar/lib/signature.c; sourceTree = ""; }; B4772CA20A003F6E00E4205C /* xar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = xar.h; path = include/xar.h; sourceTree = BUILT_PRODUCTS_DIR; }; C09ABF1A27157D1100542782 /* xar_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = xar_internal.h; path = xar/src/xar_internal.h; sourceTree = ""; }; E9C0E6731497DDAB00BF8F0F /* ea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ea.h; path = xar/lib/ea.h; sourceTree = ""; }; E9E06B88219E252E004DB0CA /* test_xar */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_xar; sourceTree = BUILT_PRODUCTS_DIR; }; E9E06B8A219E252E004DB0CA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; EEEFF3DC0EFB6FC500DBC955 /* xar-sig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "xar-sig.c"; path = "xarsig/xar-sig.c"; sourceTree = ""; }; EEEFF3E00EFB6FD500DBC955 /* xarsig */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xarsig; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ B41FC05D09F6B7C200006FAE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( B41FC0C809F6BC7A00006FAE /* libz.dylib in Frameworks */, B41FC0C909F6BC7A00006FAE /* libbz2.dylib in Frameworks */, B41FC0CB09F6BC7A00006FAE /* libxml2.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; B41FC0E009F6BD6800006FAE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( B41FC0E909F6BDAF00006FAE /* libxar.1.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; B41FC0F209F6BE2F00006FAE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( B41FC10B09F6BE9B00006FAE /* libz.dylib in Frameworks */, B41FC10C09F6BE9B00006FAE /* libbz2.dylib in Frameworks */, B41FC10E09F6BE9B00006FAE /* libxml2.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E9E06B85219E252E004DB0CA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E9E06B90219E2542004DB0CA /* libxar.1.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; EEEFF3DE0EFB6FD500DBC955 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( EEEFF40E0EFB715100DBC955 /* libxar.1.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ B41FC03F09F6B74500006FAE = { isa = PBXGroup; children = ( EEEFF3D60EFB6F5600DBC955 /* xarsig */, B41FC12409F6BF3300006FAE /* README */, B41FC12509F6BF3300006FAE /* xar.plist */, B41FC12609F6BF3300006FAE /* xar.txt */, B41FC07209F6BBD100006FAE /* tool */, B41FC07109F6BBBD00006FAE /* lib */, B41FC0C309F6BC6B00006FAE /* libraries */, B4772CA00A003F3B00E4205C /* derived */, E9E06B89219E252E004DB0CA /* test_xar */, B41FC06009F6B7C200006FAE /* Products */, E9E06B8F219E2542004DB0CA /* Frameworks */, ); sourceTree = ""; usesTabs = 1; }; B41FC06009F6B7C200006FAE /* Products */ = { isa = PBXGroup; children = ( B41FC05F09F6B7C200006FAE /* libxar.1.dylib */, B41FC0E209F6BD6800006FAE /* xar */, B41FC0F409F6BE2F00006FAE /* libxarstatic.a */, EEEFF3E00EFB6FD500DBC955 /* xarsig */, E9E06B88219E252E004DB0CA /* test_xar */, ); name = Products; sourceTree = ""; }; B41FC07109F6BBBD00006FAE /* lib */ = { isa = PBXGroup; children = ( E9C0E6731497DDAB00BF8F0F /* ea.h */, 98665C700EA83E44008193F1 /* lzmaxar.c */, 98665C6E0EA83E36008193F1 /* ea.c */, B41FC16309F6C56600006FAE /* config.h.in */, B41FC16409F6C56600006FAE /* xar.h.in */, B41FC07309F6BC2C00006FAE /* appledouble.h */, B41FC07409F6BC2C00006FAE /* archive.c */, B41FC07509F6BC2C00006FAE /* archive.h */, B41FC07609F6BC2C00006FAE /* arcmod.c */, B41FC07709F6BC2C00006FAE /* arcmod.h */, B41FC07809F6BC2C00006FAE /* asprintf.h */, B41FC07909F6BC2C00006FAE /* b64.c */, B41FC07A09F6BC2C00006FAE /* b64.h */, B41FC07B09F6BC2C00006FAE /* bzxar.c */, B41FC07C09F6BC2C00006FAE /* bzxar.h */, B41FC07E09F6BC2C00006FAE /* darwinattr.c */, B41FC07F09F6BC2C00006FAE /* darwinattr.h */, B41FC08009F6BC2C00006FAE /* data.c */, B41FC08109F6BC2C00006FAE /* data.h */, B41FC08209F6BC2C00006FAE /* err.c */, B41FC08309F6BC2C00006FAE /* ext2.c */, B41FC08409F6BC2C00006FAE /* ext2.h */, B41FC08509F6BC2C00006FAE /* fbsdattr.c */, B41FC08609F6BC2C00006FAE /* fbsdattr.h */, B41FC08709F6BC2C00006FAE /* filetree.c */, B41FC08809F6BC2C00006FAE /* filetree.h */, B41FC08909F6BC2C00006FAE /* hash.c */, B41FC08A09F6BC2C00006FAE /* hash.h */, B41FC08B09F6BC2C00006FAE /* io.c */, B41FC08C09F6BC2C00006FAE /* io.h */, B41FC08D09F6BC2C00006FAE /* linuxattr.c */, B41FC08E09F6BC2C00006FAE /* linuxattr.h */, B41FC09109F6BC2C00006FAE /* script.c */, B41FC09209F6BC2C00006FAE /* script.h */, B4657F1E0A49E6150074E45D /* signature.h */, B476FACC0A49E68600BCD61F /* signature.c */, B41FC09309F6BC2C00006FAE /* stat.c */, B41FC09409F6BC2C00006FAE /* stat.h */, B41FC09509F6BC2C00006FAE /* subdoc.c */, B41FC09609F6BC2C00006FAE /* subdoc.h */, B41FC09709F6BC2C00006FAE /* util.c */, B41FC09809F6BC2C00006FAE /* util.h */, B41FC09909F6BC2C00006FAE /* zxar.c */, B41FC09A09F6BC2C00006FAE /* zxar.h */, C09ABF1A27157D1100542782 /* xar_internal.h */, 7C7F76CC2202351600155C33 /* xar.xcconfig */, ); name = lib; sourceTree = ""; }; B41FC07209F6BBD100006FAE /* tool */ = { isa = PBXGroup; children = ( B41FC0EA09F6BDD900006FAE /* xar.1 */, B41FC0EB09F6BDD900006FAE /* xar.c */, ); name = tool; sourceTree = ""; }; B41FC0C309F6BC6B00006FAE /* libraries */ = { isa = PBXGroup; children = ( B41FC0C409F6BC7A00006FAE /* libz.dylib */, B41FC0C509F6BC7A00006FAE /* libbz2.dylib */, B41FC0C709F6BC7A00006FAE /* libxml2.dylib */, ); name = libraries; sourceTree = ""; }; B4772CA00A003F3B00E4205C /* derived */ = { isa = PBXGroup; children = ( B4772CA20A003F6E00E4205C /* xar.h */, ); name = derived; sourceTree = ""; }; E9E06B89219E252E004DB0CA /* test_xar */ = { isa = PBXGroup; children = ( E9E06B8A219E252E004DB0CA /* main.m */, ); path = test_xar; sourceTree = ""; }; E9E06B8F219E2542004DB0CA /* Frameworks */ = { isa = PBXGroup; children = ( ); name = Frameworks; sourceTree = ""; }; EEEFF3D60EFB6F5600DBC955 /* xarsig */ = { isa = PBXGroup; children = ( EEEFF3DC0EFB6FC500DBC955 /* xar-sig.c */, ); name = xarsig; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ B41FC05B09F6B7C200006FAE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E9C0E6741497DDAB00BF8F0F /* ea.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; B41FC0F009F6BE2F00006FAE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ B41FC05E09F6B7C200006FAE /* xarLib */ = { isa = PBXNativeTarget; buildConfigurationList = B41FC06109F6B7C300006FAE /* Build configuration list for PBXNativeTarget "xarLib" */; buildPhases = ( B41FC05B09F6B7C200006FAE /* Headers */, B41FC05C09F6B7C200006FAE /* Sources */, B41FC05D09F6B7C200006FAE /* Frameworks */, B41FC0DC09F6BD2300006FAE /* Copy Public Headers */, C09ABF1C27157D9900542782 /* Copy Private Headers */, B401A30509F6D73200B5C762 /* Link Built Dir */, ); buildRules = ( ); dependencies = ( B41FC0D709F6BD0300006FAE /* PBXTargetDependency */, ); name = xarLib; productName = xarLib; productReference = B41FC05F09F6B7C200006FAE /* libxar.1.dylib */; productType = "com.apple.product-type.library.dynamic"; }; B41FC0E109F6BD6800006FAE /* xarTool */ = { isa = PBXNativeTarget; buildConfigurationList = B41FC0E609F6BD8C00006FAE /* Build configuration list for PBXNativeTarget "xarTool" */; buildPhases = ( B41FC0DF09F6BD6800006FAE /* Sources */, B41FC0E009F6BD6800006FAE /* Frameworks */, B41FC0ED09F6BDE400006FAE /* CopyFiles */, ); buildRules = ( ); dependencies = ( E9C0E6771497DE6000BF8F0F /* PBXTargetDependency */, ); name = xarTool; productName = xarTool; productReference = B41FC0E209F6BD6800006FAE /* xar */; productType = "com.apple.product-type.tool"; }; B41FC0F309F6BE2F00006FAE /* xarStatic */ = { isa = PBXNativeTarget; buildConfigurationList = B41FC0F509F6BE7F00006FAE /* Build configuration list for PBXNativeTarget "xarStatic" */; buildPhases = ( B41FC0F009F6BE2F00006FAE /* Headers */, B41FC0F109F6BE2F00006FAE /* Sources */, B41FC0F209F6BE2F00006FAE /* Frameworks */, ); buildRules = ( ); dependencies = ( B41FC11F09F6BEDE00006FAE /* PBXTargetDependency */, ); name = xarStatic; productName = xarStatic; productReference = B41FC0F409F6BE2F00006FAE /* libxarstatic.a */; productType = "com.apple.product-type.library.static"; }; E9E06B87219E252E004DB0CA /* test_xar */ = { isa = PBXNativeTarget; buildConfigurationList = E9E06B8E219E252E004DB0CA /* Build configuration list for PBXNativeTarget "test_xar" */; buildPhases = ( E9E06B84219E252E004DB0CA /* Sources */, E9E06B85219E252E004DB0CA /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = test_xar; productName = test_xar; productReference = E9E06B88219E252E004DB0CA /* test_xar */; productType = "com.apple.product-type.tool"; }; EEEFF3DF0EFB6FD500DBC955 /* xarsig */ = { isa = PBXNativeTarget; buildConfigurationList = EEEFF3E50EFB6FDA00DBC955 /* Build configuration list for PBXNativeTarget "xarsig" */; buildPhases = ( EEEFF3DD0EFB6FD500DBC955 /* Sources */, EEEFF3DE0EFB6FD500DBC955 /* Frameworks */, ); buildRules = ( ); dependencies = ( E91435401497E0F6001AA5EF /* PBXTargetDependency */, ); name = xarsig; productName = xarsig; productReference = EEEFF3E00EFB6FD500DBC955 /* xarsig */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ B41FC04109F6B74500006FAE /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 1300; TargetAttributes = { E9E06B87219E252E004DB0CA = { CreatedOnToolsVersion = 11.0; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = B41FC04209F6B74500006FAE /* Build configuration list for PBXProject "xar" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = B41FC03F09F6B74500006FAE; productRefGroup = B41FC06009F6B7C200006FAE /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( E9D659AB1486FFD10089C4DA /* All */, E9D659A31486FD650089C4DA /* All tools */, B41FC12F09F6BF5900006FAE /* All libraries */, B41FC04F09F6B76200006FAE /* configure */, B41FC05E09F6B7C200006FAE /* xarLib */, B41FC0E109F6BD6800006FAE /* xarTool */, B41FC0F309F6BE2F00006FAE /* xarStatic */, B41FC12109F6BEF900006FAE /* OpenSource */, EEEFF3DF0EFB6FD500DBC955 /* xarsig */, E9E06B87219E252E004DB0CA /* test_xar */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ B401A30509F6D73200B5C762 /* Link Built Dir */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( ); inputPaths = ( ); name = "Link Built Dir"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; shellScript = "ln -s \"libxar.1.dylib\" \"$TARGET_BUILD_DIR/libxar.dylib\"\n"; }; B41FC04E09F6B76200006FAE /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/xar/include/config.h.in", "$(SRCROOT)/xar/include/xar.h.in", ); outputPaths = ( "$(TARGET_BUILD_DIR)/include/config.h", "$(TARGET_BUILD_DIR)/include/xar.h", "$(TARGET_BUILD_DIR)/cfghdrs.stamp", "$(TARGET_BUILD_DIR)/cfgoutputs.stamp", "$(TARGET_BUILD_DIR)/config.log", "$(TARGET_BUILD_DIR)/config.status", "$(TARGET_BUILD_DIR)/lib/Makefile.inc", "$(TARGET_BUILD_DIR)/Makefile", "$(TARGET_BUILD_DIR)/Makefile.inc", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "# shell script goes here\n\nif [ ! -e \"$BUILT_PRODUCTS_DIR\" ]; then\n\tmkdir -p \"$BUILT_PRODUCTS_DIR\"\nfi\n\ncd \"$BUILT_PRODUCTS_DIR\"\n\n$SRCROOT/xar/configure\n\n\nexit 0\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ B41FC05C09F6B7C200006FAE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( B41FC09C09F6BC2C00006FAE /* archive.c in Sources */, B41FC09E09F6BC2C00006FAE /* arcmod.c in Sources */, B41FC0A109F6BC2C00006FAE /* b64.c in Sources */, B41FC0A309F6BC2C00006FAE /* bzxar.c in Sources */, B41FC0A609F6BC2C00006FAE /* darwinattr.c in Sources */, B41FC0A809F6BC2C00006FAE /* data.c in Sources */, B41FC0AA09F6BC2C00006FAE /* err.c in Sources */, B41FC0AB09F6BC2C00006FAE /* ext2.c in Sources */, B41FC0AD09F6BC2C00006FAE /* fbsdattr.c in Sources */, B41FC0AF09F6BC2C00006FAE /* filetree.c in Sources */, B41FC0B109F6BC2C00006FAE /* hash.c in Sources */, B41FC0B309F6BC2C00006FAE /* io.c in Sources */, B41FC0B509F6BC2C00006FAE /* linuxattr.c in Sources */, B41FC0B909F6BC2C00006FAE /* script.c in Sources */, B41FC0BB09F6BC2C00006FAE /* stat.c in Sources */, B41FC0BD09F6BC2C00006FAE /* subdoc.c in Sources */, B41FC0BF09F6BC2C00006FAE /* util.c in Sources */, B41FC0C109F6BC2C00006FAE /* zxar.c in Sources */, B476FACD0A49E68600BCD61F /* signature.c in Sources */, 98665C6F0EA83E36008193F1 /* ea.c in Sources */, 98665C710EA83E44008193F1 /* lzmaxar.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; B41FC0DF09F6BD6800006FAE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( B41FC0EC09F6BDD900006FAE /* xar.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; B41FC0F109F6BE2F00006FAE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E9D7865D1D2606F9006D5F7D /* ea.c in Sources */, E9D786581D260606006D5F7D /* lzmaxar.c in Sources */, B41FC0F809F6BE9100006FAE /* archive.c in Sources */, B41FC0F909F6BE9100006FAE /* arcmod.c in Sources */, B41FC0FA09F6BE9100006FAE /* b64.c in Sources */, B41FC0FB09F6BE9100006FAE /* bzxar.c in Sources */, B41FC0FC09F6BE9100006FAE /* darwinattr.c in Sources */, B41FC0FD09F6BE9100006FAE /* data.c in Sources */, B41FC0FE09F6BE9100006FAE /* err.c in Sources */, B41FC0FF09F6BE9100006FAE /* ext2.c in Sources */, B41FC10009F6BE9100006FAE /* fbsdattr.c in Sources */, B41FC10109F6BE9100006FAE /* filetree.c in Sources */, B41FC10209F6BE9100006FAE /* hash.c in Sources */, B41FC10309F6BE9100006FAE /* io.c in Sources */, B41FC10409F6BE9100006FAE /* linuxattr.c in Sources */, B41FC10609F6BE9100006FAE /* script.c in Sources */, B41FC10709F6BE9100006FAE /* stat.c in Sources */, B41FC10809F6BE9100006FAE /* subdoc.c in Sources */, B41FC10909F6BE9100006FAE /* util.c in Sources */, B41FC10A09F6BE9100006FAE /* zxar.c in Sources */, B476FACF0A49E68600BCD61F /* signature.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E9E06B84219E252E004DB0CA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E9E06B91219E257D004DB0CA /* b64.c in Sources */, E9E06B8B219E252E004DB0CA /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; EEEFF3DD0EFB6FD500DBC955 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( EEEFF3E60EFB700A00DBC955 /* xar-sig.c in Sources */, C03E1E5225E72D3900AC0F53 /* util.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ B401A30309F6D71800B5C762 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC12109F6BEF900006FAE /* OpenSource */; targetProxy = B401A30209F6D71800B5C762 /* PBXContainerItemProxy */; }; B41FC0D709F6BD0300006FAE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC04F09F6B76200006FAE /* configure */; targetProxy = B41FC0D609F6BD0300006FAE /* PBXContainerItemProxy */; }; B41FC11F09F6BEDE00006FAE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC04F09F6B76200006FAE /* configure */; targetProxy = B41FC11E09F6BEDE00006FAE /* PBXContainerItemProxy */; }; B41FC13109F6BF6300006FAE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC05E09F6B7C200006FAE /* xarLib */; targetProxy = B41FC13009F6BF6300006FAE /* PBXContainerItemProxy */; }; E91435401497E0F6001AA5EF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC04F09F6B76200006FAE /* configure */; targetProxy = E914353F1497E0F6001AA5EF /* PBXContainerItemProxy */; }; E91435421497E100001AA5EF /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC04F09F6B76200006FAE /* configure */; targetProxy = E91435411497E100001AA5EF /* PBXContainerItemProxy */; }; E9C0E6771497DE6000BF8F0F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC04F09F6B76200006FAE /* configure */; targetProxy = E9C0E6761497DE6000BF8F0F /* PBXContainerItemProxy */; }; E9D659A81486FD6A0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC0E109F6BD6800006FAE /* xarTool */; targetProxy = E9D659A71486FD6A0089C4DA /* PBXContainerItemProxy */; }; E9D659AA1486FD6D0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EEEFF3DF0EFB6FD500DBC955 /* xarsig */; targetProxy = E9D659A91486FD6D0089C4DA /* PBXContainerItemProxy */; }; E9D659B01486FFED0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC05E09F6B7C200006FAE /* xarLib */; targetProxy = E9D659AF1486FFED0089C4DA /* PBXContainerItemProxy */; }; E9D659B21486FFED0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC0E109F6BD6800006FAE /* xarTool */; targetProxy = E9D659B11486FFED0089C4DA /* PBXContainerItemProxy */; }; E9D659B61486FFED0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC12109F6BEF900006FAE /* OpenSource */; targetProxy = E9D659B51486FFED0089C4DA /* PBXContainerItemProxy */; }; E9D659B81486FFED0089C4DA /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EEEFF3DF0EFB6FD500DBC955 /* xarsig */; targetProxy = E9D659B71486FFED0089C4DA /* PBXContainerItemProxy */; }; E9D7864E1D25A366006D5F7D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC0F309F6BE2F00006FAE /* xarStatic */; targetProxy = E9D7864D1D25A366006D5F7D /* PBXContainerItemProxy */; }; E9D786501D25A4B1006D5F7D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B41FC0F309F6BE2F00006FAE /* xarStatic */; targetProxy = E9D7864F1D25A4B1006D5F7D /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ B41FC04309F6B74500006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1.0; DYLIB_CURRENT_VERSION = 1.3; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx.internal; STRIP_STYLE = debugging; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; B41FC04409F6B74500006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)"; DYLIB_COMPATIBILITY_VERSION = 1.0; DYLIB_CURRENT_VERSION = 1.3; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; SDKROOT = macosx.internal; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; B41FC05209F6B77E00006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; PRODUCT_NAME = configure; }; name = Debug; }; B41FC05309F6B77E00006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; PRODUCT_NAME = configure; }; name = Release; }; B41FC06209F6B7C300006FAE /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7C7F76CC2202351600155C33 /* xar.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/lib; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = xar.1; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; B41FC06309F6B7C300006FAE /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7C7F76CC2202351600155C33 /* xar.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; EXECUTABLE_PREFIX = lib; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/lib; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", ); ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = xar.1; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; B41FC0E709F6BD8C00006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/bin; PRODUCT_NAME = xar; }; name = Debug; }; B41FC0E809F6BD8C00006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/bin; PRODUCT_NAME = xar; }; name = Release; }; B41FC0F609F6BE7F00006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = xarstatic; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; B41FC0F709F6BE7F00006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, "$(TARGET_BUILD_DIR)/include", ); INSTALL_PATH = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = xarstatic; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; B41FC12809F6BF3300006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; PRODUCT_NAME = OpenSource; }; name = Debug; }; B41FC12909F6BF3300006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; PRODUCT_NAME = OpenSource; ZERO_LINK = NO; }; name = Release; }; B41FC13809F6BF7900006FAE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; PRODUCT_NAME = All; }; name = Debug; }; B41FC13909F6BF7900006FAE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; PRODUCT_NAME = All; }; name = Release; }; E9D659A51486FD650089C4DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; E9D659A61486FD650089C4DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; E9D659AD1486FFD10089C4DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; E9D659AE1486FFD10089C4DA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; E9E06B8C219E252E004DB0CA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; name = Debug; }; E9E06B8D219E252E004DB0CA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; name = Release; }; EEEFF3E20EFB6FD600DBC955 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = /usr/include/libxml2; INSTALL_PATH = /usr/local/bin; OTHER_CFLAGS = "-DXARSIG_BUILDING_WITH_XAR"; PRODUCT_NAME = xarsig; }; name = Debug; }; EEEFF3E30EFB6FD600DBC955 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; HEADER_SEARCH_PATHS = /usr/include/libxml2; INSTALL_PATH = /usr/local/bin; OTHER_CFLAGS = "-DXARSIG_BUILDING_WITH_XAR"; PRODUCT_NAME = xarsig; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ B41FC04209F6B74500006FAE /* Build configuration list for PBXProject "xar" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC04309F6B74500006FAE /* Debug */, B41FC04409F6B74500006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC05109F6B77E00006FAE /* Build configuration list for PBXAggregateTarget "configure" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC05209F6B77E00006FAE /* Debug */, B41FC05309F6B77E00006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC06109F6B7C300006FAE /* Build configuration list for PBXNativeTarget "xarLib" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC06209F6B7C300006FAE /* Debug */, B41FC06309F6B7C300006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC0E609F6BD8C00006FAE /* Build configuration list for PBXNativeTarget "xarTool" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC0E709F6BD8C00006FAE /* Debug */, B41FC0E809F6BD8C00006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC0F509F6BE7F00006FAE /* Build configuration list for PBXNativeTarget "xarStatic" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC0F609F6BE7F00006FAE /* Debug */, B41FC0F709F6BE7F00006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC12709F6BF3300006FAE /* Build configuration list for PBXAggregateTarget "OpenSource" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC12809F6BF3300006FAE /* Debug */, B41FC12909F6BF3300006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; B41FC13709F6BF7900006FAE /* Build configuration list for PBXAggregateTarget "All libraries" */ = { isa = XCConfigurationList; buildConfigurations = ( B41FC13809F6BF7900006FAE /* Debug */, B41FC13909F6BF7900006FAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; E9D659A41486FD650089C4DA /* Build configuration list for PBXAggregateTarget "All tools" */ = { isa = XCConfigurationList; buildConfigurations = ( E9D659A51486FD650089C4DA /* Debug */, E9D659A61486FD650089C4DA /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; E9D659AC1486FFD10089C4DA /* Build configuration list for PBXAggregateTarget "All" */ = { isa = XCConfigurationList; buildConfigurations = ( E9D659AD1486FFD10089C4DA /* Debug */, E9D659AE1486FFD10089C4DA /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; E9E06B8E219E252E004DB0CA /* Build configuration list for PBXNativeTarget "test_xar" */ = { isa = XCConfigurationList; buildConfigurations = ( E9E06B8C219E252E004DB0CA /* Debug */, E9E06B8D219E252E004DB0CA /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; EEEFF3E50EFB6FDA00DBC955 /* Build configuration list for PBXNativeTarget "xarsig" */ = { isa = XCConfigurationList; buildConfigurations = ( EEEFF3E20EFB6FD600DBC955 /* Debug */, EEEFF3E30EFB6FD600DBC955 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = B41FC04109F6B74500006FAE /* Project object */; } xar-xar-498/xar.xcodeproj/project.xcworkspace/000077500000000000000000000000001446633275300215635ustar00rootroot00000000000000xar-xar-498/xar.xcodeproj/project.xcworkspace/contents.xcworkspacedata000066400000000000000000000002241446633275300265230ustar00rootroot00000000000000 xar-xar-498/xar/000077500000000000000000000000001446633275300135715ustar00rootroot00000000000000xar-xar-498/xar/.cvsignore000066400000000000000000000001321446633275300155650ustar00rootroot00000000000000Makefile autom4te.cache cfghdrs.stamp cfgoutputs.stamp configure config.log config.status xar-xar-498/xar/ChangeLog000066400000000000000000000135571446633275300153560ustar00rootroot00000000000000devel 2008-08-19 Rob Braun bbraun@synack.net * lib/lzmaxar.c: if lzma compression is specified but not compiled in, throw an error. * src/xar.c: When extracting, save directories until the end. This lets timestamps get set correctly on directories and addresses issue #58. 2008-08-17 Rob Braun bbraun@synack.net * lib/archive.c: Make sure the binary header and toc checksum types match. Contributed by Apple. 2008-08-15 Rob Braun bbraun@synack.net * lib/Makefile.inc.in: Add the $(LDFLAGS) variable when creating libxar * src/xar.c: Fix a typo in the usage statement. * lib/io.c: Fix seeking on a pipe 2008-08-14 Rob Braun bbraun@synack.net * lib/bzxar.c: if bzip2 compression is specified but not compiled in, throw an error. * src/xar.c src/xar.1: Add -C to chdir before extraction. * lib/script.c: Perform some input checking. * lib/b64.c lib/b64.h: xar_to_base64() was never used, so it is removed. * lib/lzmaxar.c: Update the use of the lzma API to match 4.42 alpha 6 of the lzma library from Anders F Björklund. 2007-12-14 Rob Braun bbraun@synack.net * configure.ac: Fix a broken configure check for sys/acl.h and acl_t 2007-12-09 Rob Braun bbraun@synack.net * include/xar.h.in lib/filetree.c lib/stat.c test/validate.c: Make sure xar_iter_new() takes no parameters. From rpm5. * lib/libxar.la.in.in: set the libxir to @LIBDIR@ from autoconf. From rpm5. * configure.ac: Allow specifying the path to lzma with --with-lzma=PATH * lib/lzmaxar.c: Use the global macro for compression level. 2007-11-11 Rob Braun bbraun@synack.net * lib/archive.c: Add a #define for a mising function in Mac OS X's old version of libxml2 from Anders F Björklund. * lib/Makefile.inc.in: Be a little more gnu libtool friendly from Anders F Björklund. 2007-11-11 Rob Braun bbraun@synack.net * lib/archive.c: Some memory leak cleanups from Anders F Björklund. 2007-11-1 Dave Leimbach leimy2k@gmail.com * lib/data.c: fixed a file descriptor leak by adding a close before return * src/xar.1: Added man page text for --extract-subdoc 2007-10-22 Rob Braun bbraun@synack.net * src/xar.c src/xar.1: Add -a as a synonym for --compression=lzma * lib/darwinattr.c lib/fbsdattr.c: Add --prop-exclude support for darwin and fbsd EAs. 2007-10-16 Rob Braun bbraun@synack.net * include/xar.h.in src/xar.c lib/io.c lib/lzmaxar.c lib/bzxar.c lib/archive.c lib/zxar.c: Added an option to pass arguments to the compression code. This to allow specifying compression levels to gzip, bzip2, and lzma. * lib/io.c: Issue 41, fixed a bug where rsize was being used uninitialized. * lib/io.c: Issue 42, log a warning and continue if archived-checksum doesn't appear when archiving a file. * lib/archive.c: Issue 43, free the buffer in xar_extract_tobuffersz() if there is an error extracting the file. 2007-10-02 Rob Braun bbraun@synack.net * test/compression test/data include/config.h.in include/xar.h.in src/xar.1 src/xar.c configure.ac lib/lzmaxar.c lib/lzmaxar.h lib/io.c lib/bzxar.c lib/Makefile.inc.in lib/zxar.c INSTALL: Incorporate a patch from anders.f.bjorklund for adding lzma compression support. 2007-10-02 Rob Braun bbraun@synack.net * include/xar.h.in lib/io.c lib/io.h lib/archive.c: Add a "streaming" API that allows for file data to be extracted incrementally, like the zlib decompression API, instead of requiring the entire file to fit in memory like xar_extract_tobuffer(). This is the inital commit of the API and may still change. This change is based on a patch from Charles Srstka. 2007-09-26 Rob Braun bbraun@synack.net * lib/io.c: Consolidate the lseek handling code into one function. Contributed by Charles Srstka as part of Issue 2. 2007-09-21 Rob Braun bbraun@synack.net * include/xar.h.in src/xar.c src/xar.1 lib/stat.c: Only extract setuid/setgid bits if the user/group are the same as the archived file (if -p/-P are specified on the command line) OR if the newly added --keep-setuid flag is specified. * configure.ac lib/stat.c: Fix the autoconf test for ino_t size, and switch the inode and device number printf's to use the autogenerated INO_STRING and DEV_STRING to get the correct formatting parameter. 2007-09-20 Rob Braun bbraun@synack.net * src/xar.c src/xar.1: Add -k as a synonym for --keep-existing for tar compatibility. 2007-09-20 Rob Braun bbraun@synack.net * src/xar.c src/xar.1: Add --keep-existing flag which prevents existing files from being extracted. 2007-09-20 Rob Braun bbraun@synack.net * lib/archive.c: Fix a bug in toc parsing where invalid tocs, particularly with mismatched closing tags, would still be processed. 2007-09-20 Rob Braun bbraun@synack.net * lib/filetree.c: Fix a minor memory leak with xar_iter_free() not freeing all memory associated with a xar_iter_t. 2007-09-20 Rob Braun bbraun@synack.net * ChangeLog: renamed from CHANGELOG. 2007-09-19 Dave Leimbach leimy2k@gmail.com * xar/xar.c xar/xar.1: Added support for -j and -z as shortcuts for --compression=bzip2 or --compression=zlib respectively. 2007-09-19 Rob Braun bbraun@synack.net * lib/zxar.c lib/bzxar.c: cleanup for more consistency between the two compression modules. Patch contributed by Anders Björklund from the rpm5 project. 2007-09-19 Rob Braun bbraun@synack.net * CHANGELOG: Added changelog * include/xar.h.in src/xar.c lib/util.c: moved helper functions for retrieving and formating file properties such as size, mode, mtime, etc. from src/xar.c to lib/util.c and exported them in xar.h. * lib/err.c lib/archive.h: Added the xar_t archive context to the error handler context to be able to retrieve archive level context within an error, such as archive level options, or being able to examine other files than the one the error occurred on. * lib/strmode.h lib/util.c config.h.in configure.ac: Import strmode(3) from freebsd to handle the formatting of file mode in xar_get_mode(), used for displaying file mode from xar -tvf. configure will automatically detect whether to use the OS strmode(3) or the included copy. xar-xar-498/xar/INSTALL000066400000000000000000000105531446633275300146260ustar00rootroot00000000000000################################################################################ # # Building and installation instructions for the Xar source distribution. # ################################################################################ Required: Xar's build system uses GNU make. Required: Xar depends on libxml2's XML functionality. For more information about libxml2, see: http://www.xmlsoft.org/ Required: Xar depends on OpenSSL (libcrypto in particular) for MD5 and SHA1 functionality. For more information about OpenSSL, see: http://www.openssl.org/ Required: Xar depends on zlib (libz) for data compression. For more information about zlib, see: http://www.zlib.net/ Optional: Xar can optionally use libbzip2 for data compression. For more information about libbzip2, see: http://www.bzip.org/ Optional: Xar can optionally use liblzma for data compression. For more information about liblzma, see: http://tukaani.org/lzma/ Optional: Regenerating the configure script requires GNU autoconf. Doing so is only necessary when making changes to the configuration system. ################################################################################ Building Xar is in many cases as simple as typing the following commands while in the root directory of the source tree: ./configure make To install, do the above, then type: make install Additional build targets of finer granularity include: src_all lib_all Additional install targets of finer granularity include: src_install lib_install Uninstall targets include: uninstall src_uninstall lib_uninstall Cleanup targets include: clean distclean relclean Note that if you are using a development version of xar, configure is not checked into the repository. You may replace the ./configure step above with ./autogen.sh. ################################################################################ The build system is capable of building in a different directory than the source, so that no files are written to the source tree. In order to use this feature, run 'configure' and 'make' while in the directory that you want to build the software in. Optionally, pass any of the following arguments to 'configure' (run 'configure' with the --help option for a full list): --prefix= Set the base directory in which to install. For example: ./configure --prefix=/usr/local will cause files to be installed into /usr/local/bin, /usr/local/man, /usr/local/include, /usr/local/lib, and /usr/local/share. --enable-autogen Include dependency rules in the build system to automatically regenerate files created by configure when their sources are newer. This is only of interest when making modifications to the source code. --with-xml2-config= If specified, use as the full path (including filename) to the xml2-config program. This is useful when there is more than one copy of xml2-config in your shell's path, or when you want to use a copy of xml2-config that is not in your shell's path at all. Optionally, define environment variables when invoking configure, including (not exclusively): CFLAGS="?" Pass these flags to the compiler. CPPFLAGS="?" Pass these flags to the C preprocessor. Note that CFLAGS is not passed to 'cpp' when 'configure' is looking for include files, so you must use CPPFLAGS instead if you need to help 'configure' find header files. LD_LIBRARY_PATH="?" 'ld' uses this colon-separated list to find libraries. LDFLAGS="?" Pass these flags when linking. PATH="?" 'configure' uses this to find programs. ################################################################################ Optionally, define make variables when invoking make, including (not exclusively): PREFIX="?" Use this as the installation prefix. BINDIR="?" Use this as the installation prefix for programs. DATADIR="?" Use this as the installation prefix for modules and documentation. LIBDIR="?" Use this as the installation prefix for libraries. INCLUDEDIR="?" Use this as the installation prefix for header files. MANDIR="?" Use this as the installation prefix for man pages. CC="?" Use this to specify the C compiler. CFLAGS="?" Pass these flags to the compiler. CPPFLAGS="?" Pass these flags to the C preprocessor. LDFLAGS="?" Pass these flags when linking. PATH="?" Use this to search for programs used during configuration and building. xar-xar-498/xar/LICENSE000066400000000000000000000031341446633275300145770ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ xar-xar-498/xar/Makefile.in000066400000000000000000000044151446633275300156420ustar00rootroot00000000000000# Clear out all vpaths, then set just one (default vpath) for the main build # directory. vpath vpath % . # Clear the default suffixes, so that built-in rules are not used. .SUFFIXES : # # Standard definitions. # SHELL := /bin/sh CC := @CC@ LD := @LD@ AR := @AR@ RANLIB := @RANLIB@ INSTALL := @INSTALL@ AUTOCONF := @AUTOCONF@ # # Build parameters. # CPPFLAGS := @CPPFLAGS@ CFLAGS := @CFLAGS@ A_CFLAGS := $(CFLAGS) S_CFLAGS := $(CFLAGS) -fPIC -DPIC ifeq (macho, @abi@) S_CFLAGS += -dynamic endif LDFLAGS := @LDFLAGS@ prefix := @PREFIX@ bindir := @BINDIR@ datadir := @DATADIR@ libdir := @LIBDIR@ includedir := @INCLUDEDIR@ mandir := @MANDIR@ PREFIX := $(prefix) BINDIR := $(bindir) DATADIR := $(datadir) LIBDIR := $(libdir) INCLUDEDIR := $(includedir) MANDIR := $(mandir) dir_names := lib src all : $(dir_names:%=%_all) install : $(dir_names:%=%_install) uninstall : $(dir_names:%=%_uninstall) clean : $(dir_names:%=%_clean) distclean : clean $(dir_names:%=%_distclean) rm -f @objroot@config.log rm -f @objroot@config.status rm -f @objroot@cfghdrs.stamp rm -f @objroot@cfgoutputs.stamp rm -f @objroot@configure.lineno rm -f @cfghdrs@ rm -f @cfgoutputs@ rm -rf @objroot@autom4te.cache relclean : distclean rm -f @objroot@configure # Include Makefile.inc files in subdirectories. include $(dir_names:%=%/Makefile.inc) # # Re-configuration rules. # ifeq (@enable_autogen@, 1) @srcroot@configure : @srcroot@configure.ac cd ./@srcroot@ && $(AUTOCONF) @objroot@config.status : @srcroot@configure ./@objroot@config.status --recheck # cfghdrs rules. @srcroot@cfghdrs.stamp.in : @srcroot@configure.ac echo stamp > @srcroot@cfghdrs.stamp.in $(patsubst %, @srcroot@%.in, @cfghdrs@) : @objroot@config.status @objroot@cfghdrs.stamp : $(patsubst %, @srcroot@%.in, @cfghdrs@) ./@objroot@config.status echo stamp > $@ $(filter-out @objroot@cfghdrs.stamp, @cfghdrs@) : @objroot@cfghdrs.stamp # cfgoutputs rules. @srcroot@cfgoutputs.stamp.in : @srcroot@configure.ac echo stamp > @srcroot@cfgoutputs.stamp.in $(patsubst %, @srcroot@%.in, @cfgoutputs@) : @objroot@config.status @objroot@cfgoutputs.stamp : $(patsubst %, @srcroot@%.in, @cfgoutputs@) ./@objroot@config.status $(filter-out \ @objroot@cfgoutputs.stamp, \ $(patsubst %, @objroot@%, @cfgoutputs@)) : @objroot@cfgoutputs.stamp endif xar-xar-498/xar/TODO000066400000000000000000000001411446633275300142550ustar00rootroot00000000000000The xar TODO exists primarily on the wiki site at: http://wiki.opendarwin.org/index.php/Xar:Todo xar-xar-498/xar/autogen.sh000077500000000000000000000004731446633275300155760ustar00rootroot00000000000000#!/bin/sh for i in autoconf; do echo "$i" $i if [ $? -ne 0 ]; then echo "Error $? in $i" exit 1 fi done if [ "$1" = "--noconfigure" ]; then exit 0; fi echo "./configure --enable-autogen $@" ./configure --enable-autogen $@ if [ $? -ne 0 ]; then echo "Error $? in ./configure" exit 1 fi xar-xar-498/xar/cfghdrs.stamp.in000066400000000000000000000000061446633275300166600ustar00rootroot00000000000000stamp xar-xar-498/xar/cfgoutputs.stamp.in000066400000000000000000000000061446633275300174430ustar00rootroot00000000000000stamp xar-xar-498/xar/config.guess000077500000000000000000001247531446633275300161250ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-08-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: xar-xar-498/xar/config.status000077500000000000000000000715001446633275300163110ustar00rootroot00000000000000#! /bin/sh # Generated by configure. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=${CONFIG_SHELL-/bin/sh} export SHELL ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Xar $as_me 1.8dev, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " # Files that config.status was made for. config_files=" cfgoutputs.stamp Makefile include/xar.h lib/Makefile.inc lib/libxar.la.in src/Makefile.inc xar.spec" config_headers=" cfghdrs.stamp include/config.h" ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." ac_cs_config="" ac_cs_version="\ Xar config.status 1.8dev configured by ./configure, generated by GNU Autoconf 2.69, with options \"$ac_cs_config\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='/Users/build/src/xar/xar' srcdir='.' INSTALL='/usr/bin/install -c' test -n "$AWK" || AWK=awk # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi if $ac_cs_recheck; then set X /bin/sh './configure' $ac_configure_extra_args --no-create --no-recursion shift $as_echo "running CONFIG_SHELL=/bin/sh $*" >&6 CONFIG_SHELL='/bin/sh' export CONFIG_SHELL exec "$@" fi exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "$cfghdrs") CONFIG_HEADERS="$CONFIG_HEADERS $cfghdrs" ;; "$cfgoutputs") CONFIG_FILES="$CONFIG_FILES $cfgoutputs" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && S["LTLIBOBJS"]="" S["LIBOBJS"]="" S["cfgoutputs"]="cfgoutputs.stamp Makefile include/xar.h lib/Makefile.inc lib/libxar.la.in src/Makefile.inc xar.spec" S["cfghdrs"]="cfghdrs.stamp include/config.h" S["XML2_CONFIG"]="/usr/bin/xml2-config" S["EGREP"]="/usr/bin/grep -E" S["GREP"]="/usr/bin/grep" S["enable_autogen"]="0" S["RPATH"]="" S["abi"]="macho" S["host_os"]="darwin16.0.0" S["host_vendor"]="apple" S["host_cpu"]="i686" S["host"]="i686-apple-darwin16.0.0" S["build_os"]="darwin16.0.0" S["build_vendor"]="apple" S["build_cpu"]="i686" S["build"]="i686-apple-darwin16.0.0" S["static"]="yes" S["shared"]="yes" S["AUTOCONF"]="" S["RANLIB"]="/usr/bin/ranlib" S["AR"]="/usr/bin/ar" S["LD"]="/usr/bin/ld" S["INSTALL_DATA"]="${INSTALL} -m 644" S["INSTALL_SCRIPT"]="${INSTALL}" S["INSTALL_PROGRAM"]="${INSTALL}" S["CPP"]="gcc -E" S["OBJEXT"]="o" S["EXEEXT"]="" S["ac_ct_CC"]="gcc" S["CPPFLAGS"]=" -I/usr/include/libxml2" S["LDFLAGS"]="" S["CFLAGS"]="-Wall -g" S["CC"]="gcc" S["MANDIR"]="/usr/local/share/man" S["INCLUDEDIR"]="/usr/local/include" S["LIBDIR"]="/usr/local/lib" S["DATADIR"]="/usr/local/share" S["BINDIR"]="/usr/local/bin" S["PREFIX"]="/usr/local" S["abs_objroot"]="/Users/build/src/xar/xar/" S["objroot"]="" S["abs_srcroot"]="/Users/build/src/xar/xar/" S["srcroot"]="" S["XAR_VERSION"]="1.8dev" S["XAR_MINOR_VERSION"]="8dev" S["XAR_MAJOR_VERSION"]="1" S["LIB_REV"]="1" S["target_alias"]="" S["host_alias"]="" S["build_alias"]="" S["LIBS"]="-lpthread -lbz2 -lz -lxml2 -lz -lpthr"\ "ead -licucore -lm" S["ECHO_T"]="" S["ECHO_N"]="" S["ECHO_C"]="\\c" S["DEFS"]="-DHAVE_CONFIG_H" S["mandir"]="${datarootdir}/man" S["localedir"]="${datarootdir}/locale" S["libdir"]="${exec_prefix}/lib" S["psdir"]="${docdir}" S["pdfdir"]="${docdir}" S["dvidir"]="${docdir}" S["htmldir"]="${docdir}" S["infodir"]="${datarootdir}/info" S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}" S["oldincludedir"]="/usr/include" S["includedir"]="${prefix}/include" S["localstatedir"]="${prefix}/var" S["sharedstatedir"]="${prefix}/com" S["sysconfdir"]="${prefix}/etc" S["datadir"]="${datarootdir}" S["datarootdir"]="${prefix}/share" S["libexecdir"]="${exec_prefix}/libexec" S["sbindir"]="${exec_prefix}/sbin" S["bindir"]="${exec_prefix}/bin" S["program_transform_name"]="s,x,x," S["prefix"]="/usr/local" S["exec_prefix"]="/usr/local" S["PACKAGE_URL"]="" S["PACKAGE_BUGREPORT"]="xar-devel@googlegroups.com" S["PACKAGE_STRING"]="Xar 1.8dev" S["PACKAGE_VERSION"]="1.8dev" S["PACKAGE_TARNAME"]="xar" S["PACKAGE_NAME"]="Xar" S["PATH_SEPARATOR"]=":" S["SHELL"]="/bin/sh" _ACAWK cat >>"$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { D["PACKAGE_NAME"]=" \"Xar\"" D["PACKAGE_TARNAME"]=" \"xar\"" D["PACKAGE_VERSION"]=" \"1.8dev\"" D["PACKAGE_STRING"]=" \"Xar 1.8dev\"" D["PACKAGE_BUGREPORT"]=" \"xar-devel@googlegroups.com\"" D["PACKAGE_URL"]=" \"\"" D["HAVE_SYS_ACL_H"]=" 1" D["STDC_HEADERS"]=" 1" D["HAVE_SYS_TYPES_H"]=" 1" D["HAVE_SYS_STAT_H"]=" 1" D["HAVE_STDLIB_H"]=" 1" D["HAVE_STRING_H"]=" 1" D["HAVE_MEMORY_H"]=" 1" D["HAVE_STRINGS_H"]=" 1" D["HAVE_INTTYPES_H"]=" 1" D["HAVE_STDINT_H"]=" 1" D["HAVE_UNISTD_H"]=" 1" D["HAVE_SYS_XATTR_H"]=" 1" D["HAVE_SYS_PARAM_H"]=" 1" D["HAVE_GETXATTR"]=" 1" D["HAVE_SETXATTR"]=" 1" D["HAVE_GETATTRLIST"]=" 1" D["HAVE_SETATTRLIST"]=" 1" D["HAVE_LCHMOD"]=" 1" D["HAVE_LCHOWN"]=" 1" D["HAVE_CHFLAGS"]=" 1" D["HAVE_STATVFS"]=" 1" D["HAVE_STATFS"]=" 1" D["HAVE_STRMODE"]=" 1" D["HAVE_STRUCT_STATFS_F_FSTYPENAME"]=" 1" D["HAVE_STRUCT_STAT_ST_FLAGS"]=" 1" D["SIZEOF_UID_T"]=" 4" D["UID_STRING"]=" RId32" D["UID_CAST"]=" (uint32_t)" D["SIZEOF_GID_T"]=" 4" D["GID_STRING"]=" PRId32" D["GID_CAST"]=" (uint32_t)" D["SIZEOF_INO_T"]=" 8" D["INO_STRING"]=" PRId64" D["INO_HEXSTRING"]=" PRIx64" D["INO_CAST"]=" (uint64_t)" D["SIZEOF_DEV_T"]=" 4" D["DEV_STRING"]=" PRId32" D["DEV_HEXSTRING"]=" PRIx32" D["DEV_CAST"]=" (uint32_t)" D["HAVE_ASPRINTF"]=" 1" D["HAVE_ZLIB_H"]=" 1" D["HAVE_LIBZ"]=" 1" D["HAVE_BZLIB_H"]=" 1" D["HAVE_LIBBZ2"]=" 1" D["HAVE_LIBBZ2"]=" 1" D["HAVE_PTHREAD_H"]=" 1" D["HAVE_LIBPTHREAD"]=" 1" D["HAVE_LIBPTHREAD"]=" 1" for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { line = $ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ac_datarootdir_hack=' s&@datadir@&${datarootdir}&g s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g s&@infodir@&${datarootdir}/info&g s&@localedir@&${datarootdir}/locale&g s&@mandir@&${datarootdir}/man&g s&\${datarootdir}&${prefix}/share&g' ;; esac ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// } :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 xar-xar-498/xar/config.sub000077500000000000000000000757771446633275300156030ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-07-08' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | ms1 \ | msp430 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m32c) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | ms1-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; m32c-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: xar-xar-498/xar/configure000077500000000000000000005375721446633275300155230ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Xar 1.8dev. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: xar-devel@googlegroups.com about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Xar' PACKAGE_TARNAME='xar' PACKAGE_VERSION='1.8dev' PACKAGE_STRING='Xar 1.8dev' PACKAGE_BUGREPORT='xar-devel@googlegroups.com' PACKAGE_URL='' ac_unique_file="LICENSE" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_default_prefix=/usr/local ac_subst_vars='LTLIBOBJS LIBOBJS cfgoutputs cfghdrs XML2_CONFIG EGREP GREP enable_autogen RPATH abi host_os host_vendor host_cpu host build_os build_vendor build_cpu build static shared AUTOCONF RANLIB AR LD INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MANDIR INCLUDEDIR LIBDIR DATADIR BINDIR PREFIX abs_objroot objroot abs_srcroot srcroot XAR_VERSION XAR_MINOR_VERSION XAR_MAJOR_VERSION LIB_REV target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_largefile enable_shared enable_static enable_autogen with_xml2_config ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Xar 1.8dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/xar] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Xar 1.8dev:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files --enable-shared build shared libraries [default=yes] --enable-static build static libraries [default=yes] --enable-autogen Automatically regenerate configure output Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-xml2-config libxml2 config program Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Xar configure 1.8dev generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------------------- ## ## Report this to xar-devel@googlegroups.com ## ## ----------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Xar $as_me 1.8dev, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIB_REV=1 XAR_MAJOR_VERSION="1" XAR_MINOR_VERSION="8dev" XAR_VERSION="${XAR_MAJOR_VERSION}.${XAR_MINOR_VERSION}" srcroot=$srcdir if test "x${srcroot}" = "x." ; then srcroot="" else srcroot="${srcroot}/" fi abs_srcroot="`cd "$srcdir"; pwd`/" objroot="" abs_objroot="`pwd`/" if test "x$prefix" = "xNONE" ; then prefix="/usr/local" fi if test "x$exec_prefix" = "xNONE" ; then exec_prefix=$prefix fi PREFIX=$prefix BINDIR=`eval echo $bindir` BINDIR=`eval echo $BINDIR` DATADIR=`eval echo $datadir` DATADIR=`eval echo $DATADIR` LIBDIR=`eval echo $libdir` LIBDIR=`eval echo $LIBDIR` INCLUDEDIR=`eval echo $includedir` INCLUDEDIR=`eval echo $INCLUDEDIR` MANDIR=`eval echo $mandir` MANDIR=`eval echo $MANDIR` cfgoutputs="cfgoutputs.stamp" cfgoutputs="${cfgoutputs} Makefile" cfgoutputs="${cfgoutputs} include/xar.h" cfgoutputs="${cfgoutputs} lib/Makefile.inc" cfgoutputs="${cfgoutputs} lib/libxar.la.in" cfgoutputs="${cfgoutputs} src/Makefile.inc" cfgoutputs="${cfgoutputs} xar.spec" cfghdrs="${objroot}cfghdrs.stamp" cfghdrs="${cfghdrs} ${objroot}include/config.h" CFLAGS=$CFLAGS ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi if test "x$CFLAGS" = "x" ; then no_CFLAGS="yes" fi if test "x$no_CFLAGS" = "xyes" -a "x$GCC" = "xyes" ; then CFLAGS="-Wall -g" fi if test "x$EXTRA_CFLAGS" != "x" ; then CFLAGS="$CFLAGS $EXTRA_CFLAGS" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ld", so it can be a program name with args. set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else case $LD in [\\/]* | ?:[\\/]*) ac_cv_path_LD="$LD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LD=$ac_cv_path_LD if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AR+:} false; then : $as_echo_n "(cached) " >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else case $RANLIB in [\\/]* | ?:[\\/]*) ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RANLIB=$ac_cv_path_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "autoconf", so it can be a program name with args. set dummy autoconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AUTOCONF+:} false; then : $as_echo_n "(cached) " >&6 else case $AUTOCONF in [\\/]* | ?:[\\/]*) ac_cv_path_AUTOCONF="$AUTOCONF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AUTOCONF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AUTOCONF=$ac_cv_path_AUTOCONF if test -n "$AUTOCONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOCONF" >&5 $as_echo "$AUTOCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi #AC_ENABLE_SHARED { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; shared=$enableval else shared=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $shared" >&5 $as_echo "$shared" >&6; } #AC_ENABLE_STATIC { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; static=$enableval else static=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $static" >&5 $as_echo "$static" >&6; } # Make sure either enable_shared or enable_static is yes. test "$shared" = "yes" || test "$static" = "yes" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case "${host}" in *-*-darwin*) abi="macho" RPATH="" ;; *-*-freebsd*) CFLAGS="$CFLAGS" abi="elf" RPATH="-Wl,-rpath," ;; *-*-linux*) CFLAGS="$CFLAGS" abi="elf" CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" RPATH="-Wl,-rpath," ;; *-*-netbsd*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking ABI" >&5 $as_echo_n "checking ABI... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __ELF__ /* ELF */ #else #error aout #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : CFLAGS="$CFLAGS"; abi="elf" else abi="aout" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $abi" >&5 $as_echo "$abi" >&6; } RPATH="-Wl,-rpath," ;; *-*-solaris2*) CFLAGS="$CFLAGS" abi="elf" RPATH="-Wl,-R," ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Unsupported operating system: ${host}" >&5 $as_echo "Unsupported operating system: ${host}" >&6; } abi="elf" RPATH="-Wl,-rpath," ;; esac # Check whether --enable-autogen was given. if test "${enable_autogen+set}" = set; then : enableval=$enable_autogen; if test "x$enable_autogen" = "xno" ; then enable_autogen="0" else enable_autogen="1" fi else enable_autogen="0" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { acl_t a ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_SYS_ACL_H 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in ext2fs/ext2_fs.h sys/statfs.h sys/xattr.h sys/param.h sys/extattr.h libutil.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in lgetxattr do : ac_fn_c_check_func "$LINENO" "lgetxattr" "ac_cv_func_lgetxattr" if test "x$ac_cv_func_lgetxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LGETXATTR 1 _ACEOF fi done for ac_func in lsetxattr do : ac_fn_c_check_func "$LINENO" "lsetxattr" "ac_cv_func_lsetxattr" if test "x$ac_cv_func_lsetxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LSETXATTR 1 _ACEOF fi done for ac_func in getxattr do : ac_fn_c_check_func "$LINENO" "getxattr" "ac_cv_func_getxattr" if test "x$ac_cv_func_getxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETXATTR 1 _ACEOF fi done for ac_func in setxattr do : ac_fn_c_check_func "$LINENO" "setxattr" "ac_cv_func_setxattr" if test "x$ac_cv_func_setxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETXATTR 1 _ACEOF fi done for ac_func in getattrlist do : ac_fn_c_check_func "$LINENO" "getattrlist" "ac_cv_func_getattrlist" if test "x$ac_cv_func_getattrlist" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETATTRLIST 1 _ACEOF fi done for ac_func in setattrlist do : ac_fn_c_check_func "$LINENO" "setattrlist" "ac_cv_func_setattrlist" if test "x$ac_cv_func_setattrlist" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETATTRLIST 1 _ACEOF fi done for ac_func in lchmod do : ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod" if test "x$ac_cv_func_lchmod" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LCHMOD 1 _ACEOF fi done for ac_func in lchown do : ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" if test "x$ac_cv_func_lchown" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LCHOWN 1 _ACEOF fi done for ac_func in chflags do : ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" if test "x$ac_cv_func_chflags" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CHFLAGS 1 _ACEOF fi done for ac_func in statvfs do : ac_fn_c_check_func "$LINENO" "statvfs" "ac_cv_func_statvfs" if test "x$ac_cv_func_statvfs" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STATVFS 1 _ACEOF fi done for ac_func in statfs do : ac_fn_c_check_func "$LINENO" "statfs" "ac_cv_func_statfs" if test "x$ac_cv_func_statfs" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STATFS 1 _ACEOF fi done for ac_func in strmode do : ac_fn_c_check_func "$LINENO" "strmode" "ac_cv_func_strmode" if test "x$ac_cv_func_strmode" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRMODE 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct statfs" "f_fstypename" "ac_cv_member_struct_statfs_f_fstypename" "#include #include #include " if test "x$ac_cv_member_struct_statfs_f_fstypename" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STATFS_F_FSTYPENAME 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct statvfs" "f_fstypename" "ac_cv_member_struct_statvfs_f_fstypename" "#include " if test "x$ac_cv_member_struct_statvfs_f_fstypename" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STATVFS_F_FSTYPENAME 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_flags" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_FLAGS 1 _ACEOF fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uid_t" >&5 $as_echo_n "checking size of uid_t... " >&6; } if ${ac_cv_sizeof_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uid_t))" "ac_cv_sizeof_uid_t" "$ac_includes_default"; then : else if test "$ac_cv_type_uid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (uid_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_uid_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uid_t" >&5 $as_echo "$ac_cv_sizeof_uid_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UID_T $ac_cv_sizeof_uid_t _ACEOF if test $ac_cv_sizeof_uid_t = "4"; then $as_echo "#define UID_STRING RId32" >>confdefs.h $as_echo "#define UID_CAST (uint32_t)" >>confdefs.h elif test $ac_cv_sizeof_uid_t = "8"; then $as_echo "#define UID_STRING PRId64" >>confdefs.h $as_echo "#define UID_CAST (uint64_t)" >>confdefs.h else as_fn_error $? "can not detect the size of your system's uid_t type" "$LINENO" 5 fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of gid_t" >&5 $as_echo_n "checking size of gid_t... " >&6; } if ${ac_cv_sizeof_gid_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (gid_t))" "ac_cv_sizeof_gid_t" "$ac_includes_default"; then : else if test "$ac_cv_type_gid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (gid_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_gid_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_gid_t" >&5 $as_echo "$ac_cv_sizeof_gid_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_GID_T $ac_cv_sizeof_gid_t _ACEOF if test $ac_cv_sizeof_gid_t = "4"; then $as_echo "#define GID_STRING PRId32" >>confdefs.h $as_echo "#define GID_CAST (uint32_t)" >>confdefs.h elif test $ac_cv_sizeof_gid_t = "8"; then $as_echo "#define GID_STRING PRId64" >>confdefs.h $as_echo "#define GID_CAST (uint64_t)" >>confdefs.h else as_fn_error $? "can not detect the size of your system's gid_t type" "$LINENO" 5 fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino_t" >&5 $as_echo_n "checking size of ino_t... " >&6; } if ${ac_cv_sizeof_ino_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino_t))" "ac_cv_sizeof_ino_t" "$ac_includes_default"; then : else if test "$ac_cv_type_ino_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (ino_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_ino_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino_t" >&5 $as_echo "$ac_cv_sizeof_ino_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INO_T $ac_cv_sizeof_ino_t _ACEOF if test $ac_cv_sizeof_ino_t = "4"; then $as_echo "#define INO_STRING PRId32" >>confdefs.h $as_echo "#define INO_HEXSTRING PRIx32" >>confdefs.h $as_echo "#define INO_CAST (uint32_t)" >>confdefs.h elif test $ac_cv_sizeof_ino_t = "8"; then $as_echo "#define INO_STRING PRId64" >>confdefs.h $as_echo "#define INO_HEXSTRING PRIx64" >>confdefs.h $as_echo "#define INO_CAST (uint64_t)" >>confdefs.h else as_fn_error $? "can not detect the size of your system's ino_t type" "$LINENO" 5 fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of dev_t" >&5 $as_echo_n "checking size of dev_t... " >&6; } if ${ac_cv_sizeof_dev_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (dev_t))" "ac_cv_sizeof_dev_t" "$ac_includes_default"; then : else if test "$ac_cv_type_dev_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (dev_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_dev_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_dev_t" >&5 $as_echo "$ac_cv_sizeof_dev_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_DEV_T $ac_cv_sizeof_dev_t _ACEOF if test $ac_cv_sizeof_dev_t = "4"; then $as_echo "#define DEV_STRING PRId32" >>confdefs.h $as_echo "#define DEV_HEXSTRING PRIx32" >>confdefs.h $as_echo "#define DEV_CAST (uint32_t)" >>confdefs.h elif test $ac_cv_sizeof_dev_t = "8"; then $as_echo "#define DEV_STRING PRId64" >>confdefs.h $as_echo "#define DEV_HEXSTRING PRIx64" >>confdefs.h $as_echo "#define DEV_CAST (uint64_t)" >>confdefs.h else as_fn_error $? "can not detect the size of your system's dev_t type" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5 $as_echo_n "checking for acl_get_file in -lacl... " >&6; } if ${ac_cv_lib_acl_acl_get_file+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lacl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acl_get_file (); int main () { return acl_get_file (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_acl_acl_get_file=yes else ac_cv_lib_acl_acl_get_file=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5 $as_echo "$ac_cv_lib_acl_acl_get_file" >&6; } if test "x$ac_cv_lib_acl_acl_get_file" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBACL 1 _ACEOF LIBS="-lacl $LIBS" fi ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes; then : $as_echo "#define HAVE_ASPRINTF 1" >>confdefs.h fi LIBXML2_VERSION_MIN=2.6.11 have_libxml2="1" # Check whether --with-xml2-config was given. if test "${with_xml2_config+set}" = set; then : withval=$with_xml2_config; if test "x${with_xml2_config}" = "xno" ; then XML2_CONFIG= else XML2_CONFIG="${with_xml2_config}" fi else XML2_CONFIG= fi if test "x${XML2_CONFIG}" != "x" ; then if test ! -x "${XML2_CONFIG}" ; then as_fn_error $? "Unusable or missing xml2-config: ${XML2_CONFIG}" "$LINENO" 5 fi else # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XML2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $XML2_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in ${PATH} do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XML2_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XML2_CONFIG=$ac_cv_path_XML2_CONFIG if test -n "$XML2_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5 $as_echo "$XML2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x${XML2_CONFIG}" = "x" ; then as_fn_error $? "Cannot configure without xml2-config" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml >= ${LIBXML2_VERSION_MIN}" >&5 $as_echo_n "checking for libxml >= ${LIBXML2_VERSION_MIN}... " >&6; } LIBXML2_FOUND=`2>&1 ${XML2_CONFIG} --version` LIBXML2_MAJOR=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $1}'` LIBXML2_MINOR=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $2}' | tr a-z " " |awk '{print $1}'` LIBXML2_BRANCH=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $3}' | tr a-z " " |awk '{print $1}'` if test "x${LIBXML2_BRANCH}" = "x" ; then LIBXML2_BRANCH=0 fi LIBXML2_MAJOR_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $1}'` LIBXML2_MINOR_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $2}'` LIBXML2_BRANCH_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $3}'` if test ${LIBXML2_MAJOR} -gt ${LIBXML2_MAJOR_MIN} \ -o ${LIBXML2_MAJOR} -eq ${LIBXML2_MAJOR_MIN} \ -a ${LIBXML2_MINOR} -gt ${LIBXML2_MINOR_MIN} \ -o ${LIBXML2_MAJOR} -eq ${LIBXML2_MAJOR_MIN} \ -a ${LIBXML2_MINOR} -eq ${LIBXML2_MINOR_MIN} \ -a ${LIBXML2_BRANCH} -ge $LIBXML2_BRANCH_MIN ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBXML2_MAJOR}.${LIBXML2_MINOR}.${LIBXML2_BRANCH}" >&5 $as_echo "${LIBXML2_MAJOR}.${LIBXML2_MINOR}.${LIBXML2_BRANCH}" >&6; } have_libxml2="1" CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`" LIBS="${LIBS} `${XML2_CONFIG} --libs`" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_libxml2="0" fi if test "x${have_libxml2}" = "x1" ; then ac_fn_c_check_header_mongrel "$LINENO" "libxml/xmlwriter.h" "ac_cv_header_libxml_xmlwriter_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_xmlwriter_h" = xyes; then : else have_libxml2="0" fi fi if test "x${have_libxml2}" = "x0" ; then as_fn_error $? "Cannot build without libxml2" "$LINENO" 5 fi have_libz="1" for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF else have_libz="0" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5 $as_echo_n "checking for deflate in -lz... " >&6; } if ${ac_cv_lib_z_deflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char deflate (); int main () { return deflate (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_deflate=yes else ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5 $as_echo "$ac_cv_lib_z_deflate" >&6; } if test "x$ac_cv_lib_z_deflate" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else have_libz="0" fi if test "x${have_libz}" = "x0" ; then as_fn_error $? "Cannot build without libz" "$LINENO" 5 fi have_libbz2="1" for ac_header in bzlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" if test "x$ac_cv_header_bzlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BZLIB_H 1 _ACEOF else have_libbz2="0" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 $as_echo_n "checking for BZ2_bzCompress in -lbz2... " >&6; } if ${ac_cv_lib_bz2_BZ2_bzCompress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbz2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char BZ2_bzCompress (); int main () { return BZ2_bzCompress (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bz2_BZ2_bzCompress=yes else ac_cv_lib_bz2_BZ2_bzCompress=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 $as_echo "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBBZ2 1 _ACEOF LIBS="-lbz2 $LIBS" else have_libbz2="0" fi if test "x${have_libbz2}" = "x1" ; then $as_echo "#define HAVE_LIBBZ2 1" >>confdefs.h fi have_libpthread="1" for ac_header in pthread.h do : ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTHREAD_H 1 _ACEOF else have_libpthread="0" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_lock in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_lock in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_lock+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_lock (); int main () { return pthread_mutex_lock (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_lock=yes else ac_cv_lib_pthread_pthread_mutex_lock=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_lock" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_lock" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_lock" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else have_libpthread="0" fi if test "x${have_libpthread}" = "x1" ; then $as_echo "#define HAVE_LIBPTHREAD 1" >>confdefs.h fi ac_config_headers="$ac_config_headers $cfghdrs" ac_config_files="$ac_config_files $cfgoutputs" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Xar $as_me 1.8dev, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Xar config.status 1.8dev configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "$cfghdrs") CONFIG_HEADERS="$CONFIG_HEADERS $cfghdrs" ;; "$cfgoutputs") CONFIG_FILES="$CONFIG_FILES $cfgoutputs" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi xar-xar-498/xar/configure.ac000066400000000000000000000232201446633275300160560ustar00rootroot00000000000000AC_PREREQ(2.59) AC_INIT([Xar], [1.8dev], [xar-devel@googlegroups.com], [xar]) AC_CONFIG_SRCDIR([LICENSE]) dnl Revision number for libxar. LIB_REV=1 AC_SUBST([LIB_REV]) dnl xar version variables. XAR_MAJOR_VERSION="1" XAR_MINOR_VERSION="8dev" XAR_VERSION="${XAR_MAJOR_VERSION}.${XAR_MINOR_VERSION}" AC_SUBST([XAR_MAJOR_VERSION]) AC_SUBST([XAR_MINOR_VERSION]) AC_SUBST([XAR_VERSION]) dnl dnl Various paths. dnl srcroot=$srcdir if test "x${srcroot}" = "x." ; then srcroot="" else srcroot="${srcroot}/" fi AC_SUBST([srcroot]) abs_srcroot="`cd "$srcdir"; pwd`/" AC_SUBST([abs_srcroot]) objroot="" AC_SUBST([objroot]) abs_objroot="`pwd`/" AC_SUBST([abs_objroot]) dnl Set install paths. if test "x$prefix" = "xNONE" ; then prefix="/usr/local" fi if test "x$exec_prefix" = "xNONE" ; then exec_prefix=$prefix fi PREFIX=$prefix AC_SUBST([PREFIX]) BINDIR=`eval echo $bindir` BINDIR=`eval echo $BINDIR` AC_SUBST([BINDIR]) DATADIR=`eval echo $datadir` DATADIR=`eval echo $DATADIR` AC_SUBST([DATADIR]) LIBDIR=`eval echo $libdir` LIBDIR=`eval echo $LIBDIR` AC_SUBST([LIBDIR]) INCLUDEDIR=`eval echo $includedir` INCLUDEDIR=`eval echo $INCLUDEDIR` AC_SUBST([INCLUDEDIR]) MANDIR=`eval echo $mandir` MANDIR=`eval echo $MANDIR` AC_SUBST([MANDIR]) cfgoutputs="cfgoutputs.stamp" cfgoutputs="${cfgoutputs} Makefile" cfgoutputs="${cfgoutputs} include/xar.h" cfgoutputs="${cfgoutputs} lib/Makefile.inc" cfgoutputs="${cfgoutputs} lib/libxar.la.in" cfgoutputs="${cfgoutputs} src/Makefile.inc" cfgoutputs="${cfgoutputs} xar.spec" cfghdrs="${objroot}cfghdrs.stamp" cfghdrs="${cfghdrs} ${objroot}include/config.h" dnl If CFLAGS isn't defined and using gcc, set CFLAGS to something reasonable. dnl Otherwise, just prevent autoconf from molesting CFLAGS. CFLAGS=$CFLAGS AC_PROG_CC AC_SYS_LARGEFILE if test "x$CFLAGS" = "x" ; then no_CFLAGS="yes" fi if test "x$no_CFLAGS" = "xyes" -a "x$GCC" = "xyes" ; then CFLAGS="-Wall -g" fi dnl Append EXTRA_CFLAGS to CFLAGS, if defined. if test "x$EXTRA_CFLAGS" != "x" ; then CFLAGS="$CFLAGS $EXTRA_CFLAGS" fi AC_PROG_CPP AC_PROG_INSTALL AC_PATH_PROG([LD], [ld], , [$PATH]) AC_PATH_PROG([AR], [ar], , [$PATH]) AC_PATH_PROG([RANLIB], [ranlib], , [$PATH]) AC_PATH_PROG([AUTOCONF], [autoconf], , [$PATH]) dnl Some libtool envy #AC_ENABLE_SHARED AC_MSG_CHECKING([whether to build shared libraries]) AC_ARG_ENABLE([shared], [AC_HELP_STRING([--enable-shared], [build shared libraries @<:@default=yes@:>@])], [shared=$enableval],[shared=yes]) AC_MSG_RESULT($shared) AC_SUBST([shared]) #AC_ENABLE_STATIC AC_MSG_CHECKING([whether to build static libraries]) AC_ARG_ENABLE([static], [AC_HELP_STRING([--enable-static], [build static libraries @<:@default=yes@:>@])], [static=$enableval],[static=yes]) AC_MSG_RESULT($static) AC_SUBST([static]) # Make sure either enable_shared or enable_static is yes. test "$shared" = "yes" || test "$static" = "yes" dnl Platform-specific settings. abi and RPATH can probably be determined dnl programmatically, but doing so is error-prone, which makes it generally dnl not worth the trouble. dnl dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the dnl definitions need to be seen before and headers are included, which is a pain dnl to make happen otherwise. AC_CANONICAL_HOST case "${host}" in *-*-darwin*) abi="macho" RPATH="" ;; *-*-freebsd*) CFLAGS="$CFLAGS" abi="elf" RPATH="-Wl,-rpath," ;; *-*-linux*) CFLAGS="$CFLAGS" abi="elf" dnl Linux needs this for things like asprintf() and poll() flags. CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" RPATH="-Wl,-rpath," ;; *-*-netbsd*) AC_MSG_CHECKING([ABI]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[#ifdef __ELF__ /* ELF */ #else #error aout #endif ]])], [CFLAGS="$CFLAGS"; abi="elf"], [abi="aout"]) AC_MSG_RESULT([$abi]) RPATH="-Wl,-rpath," ;; *-*-solaris2*) CFLAGS="$CFLAGS" abi="elf" RPATH="-Wl,-R," dnl XXX Remove the following if it ends up not being useful. dnl Solaris needs this for sigwait(). dnl CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" dnl LIBS="$LIBS -lposix4 -lsocket -lnsl" ;; *) AC_MSG_RESULT([Unsupported operating system: ${host}]) abi="elf" RPATH="-Wl,-rpath," ;; esac AC_SUBST([abi]) AC_SUBST([RPATH]) dnl Disable rules that do automatic regeneration of configure output by default. AC_ARG_ENABLE([autogen], [ --enable-autogen Automatically regenerate configure output], [if test "x$enable_autogen" = "xno" ; then enable_autogen="0" else enable_autogen="1" fi ], [enable_autogen="0"] ) AC_SUBST([enable_autogen]) AC_TRY_COMPILE([#include #include ], [acl_t a], [AC_DEFINE([HAVE_SYS_ACL_H],[1], [define if you have sys/acl.h and it has a working acl_t type])]) AC_CHECK_HEADERS(ext2fs/ext2_fs.h sys/statfs.h sys/xattr.h sys/param.h sys/extattr.h libutil.h) AC_CHECK_FUNCS(lgetxattr) AC_CHECK_FUNCS(lsetxattr) AC_CHECK_FUNCS(getxattr) AC_CHECK_FUNCS(setxattr) AC_CHECK_FUNCS(getattrlist) AC_CHECK_FUNCS(setattrlist) AC_CHECK_FUNCS(lchmod) AC_CHECK_FUNCS(lchown) AC_CHECK_FUNCS(chflags) AC_CHECK_FUNCS(statvfs) AC_CHECK_FUNCS(statfs) AC_CHECK_FUNCS(strmode) AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[#include #include #include ]) AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,,[#include ]) AC_CHECK_MEMBERS([struct stat.st_flags]) AC_CHECK_SIZEOF(uid_t) if test $ac_cv_sizeof_uid_t = "4"; then AC_DEFINE(UID_STRING, RId32) AC_DEFINE(UID_CAST, (uint32_t)) elif test $ac_cv_sizeof_uid_t = "8"; then AC_DEFINE(UID_STRING, PRId64) AC_DEFINE(UID_CAST, (uint64_t)) else AC_ERROR(can not detect the size of your system's uid_t type) fi AC_CHECK_SIZEOF(gid_t) if test $ac_cv_sizeof_gid_t = "4"; then AC_DEFINE(GID_STRING, PRId32) AC_DEFINE(GID_CAST, (uint32_t)) elif test $ac_cv_sizeof_gid_t = "8"; then AC_DEFINE(GID_STRING, PRId64) AC_DEFINE(GID_CAST, (uint64_t)) else AC_ERROR(can not detect the size of your system's gid_t type) fi AC_CHECK_SIZEOF(ino_t) if test $ac_cv_sizeof_ino_t = "4"; then AC_DEFINE(INO_STRING, PRId32) AC_DEFINE(INO_HEXSTRING, PRIx32) AC_DEFINE(INO_CAST, (uint32_t)) elif test $ac_cv_sizeof_ino_t = "8"; then AC_DEFINE(INO_STRING, PRId64) AC_DEFINE(INO_HEXSTRING, PRIx64) AC_DEFINE(INO_CAST, (uint64_t)) else AC_ERROR(can not detect the size of your system's ino_t type) fi AC_CHECK_SIZEOF(dev_t) if test $ac_cv_sizeof_dev_t = "4"; then AC_DEFINE(DEV_STRING, PRId32) AC_DEFINE(DEV_HEXSTRING, PRIx32) AC_DEFINE(DEV_CAST, (uint32_t)) elif test $ac_cv_sizeof_dev_t = "8"; then AC_DEFINE(DEV_STRING, PRId64) AC_DEFINE(DEV_HEXSTRING, PRIx64) AC_DEFINE(DEV_CAST, (uint64_t)) else AC_ERROR(can not detect the size of your system's dev_t type) fi AC_CHECK_LIB(acl, acl_get_file) dnl Check for paths AC_PREFIX_DEFAULT(/usr/local) AC_CHECK_FUNC([asprintf], AC_DEFINE([HAVE_ASPRINTF])) dnl dnl Configure libxml2. dnl LIBXML2_VERSION_MIN=2.6.11 have_libxml2="1" AC_ARG_WITH([xml2-config], [ --with-xml2-config libxml2 config program], if test "x${with_xml2_config}" = "xno" ; then XML2_CONFIG= else XML2_CONFIG="${with_xml2_config}" fi , XML2_CONFIG= ) if test "x${XML2_CONFIG}" != "x" ; then if test ! -x "${XML2_CONFIG}" ; then AC_MSG_ERROR([Unusable or missing xml2-config: ${XML2_CONFIG}]) fi else AC_PATH_PROG([XML2_CONFIG], [xml2-config], , [${PATH}]) if test "x${XML2_CONFIG}" = "x" ; then AC_MSG_ERROR([Cannot configure without xml2-config]) fi fi dnl Make sure the version of libxml2 found is sufficient. AC_MSG_CHECKING([for libxml >= ${LIBXML2_VERSION_MIN}]) LIBXML2_FOUND=`2>&1 ${XML2_CONFIG} --version` LIBXML2_MAJOR=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $1}'` LIBXML2_MINOR=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $2}' | tr a-z " " |awk '{print $1}'` LIBXML2_BRANCH=`echo ${LIBXML2_FOUND} | tr . " " | awk '{print $3}' | tr a-z " " |awk '{print $1}'` if test "x${LIBXML2_BRANCH}" = "x" ; then LIBXML2_BRANCH=0 fi LIBXML2_MAJOR_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $1}'` LIBXML2_MINOR_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $2}'` LIBXML2_BRANCH_MIN=`echo ${LIBXML2_VERSION_MIN} | tr . " " | awk '{print $3}'` if test ${LIBXML2_MAJOR} -gt ${LIBXML2_MAJOR_MIN} \ -o ${LIBXML2_MAJOR} -eq ${LIBXML2_MAJOR_MIN} \ -a ${LIBXML2_MINOR} -gt ${LIBXML2_MINOR_MIN} \ -o ${LIBXML2_MAJOR} -eq ${LIBXML2_MAJOR_MIN} \ -a ${LIBXML2_MINOR} -eq ${LIBXML2_MINOR_MIN} \ -a ${LIBXML2_BRANCH} -ge $LIBXML2_BRANCH_MIN ; then AC_MSG_RESULT([${LIBXML2_MAJOR}.${LIBXML2_MINOR}.${LIBXML2_BRANCH}]) have_libxml2="1" CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`" LIBS="${LIBS} `${XML2_CONFIG} --libs`" else AC_MSG_RESULT([no]) have_libxml2="0" fi if test "x${have_libxml2}" = "x1" ; then dnl Final sanity check, to make sure that xmlwriter is present. AC_CHECK_HEADER([libxml/xmlwriter.h], , [have_libxml2="0"]) fi if test "x${have_libxml2}" = "x0" ; then AC_MSG_ERROR([Cannot build without libxml2]) fi dnl dnl Configure libz. dnl have_libz="1" AC_CHECK_HEADERS([zlib.h], , [have_libz="0"]) AC_CHECK_LIB([z], [deflate], , [have_libz="0"]) if test "x${have_libz}" = "x0" ; then AC_MSG_ERROR([Cannot build without libz]) fi dnl dnl Configure libbz2. dnl have_libbz2="1" AC_CHECK_HEADERS([bzlib.h], , [have_libbz2="0"]) AC_CHECK_LIB([bz2], [BZ2_bzCompress], , [have_libbz2="0"]) if test "x${have_libbz2}" = "x1" ; then AC_DEFINE([HAVE_LIBBZ2]) fi dnl dnl Configure libpthread. dnl have_libpthread="1" AC_CHECK_HEADERS([pthread.h], , [have_pthread="0"]) AC_CHECK_LIB([pthread], [pthread_mutex_lock], , [have_pthread="0"]) if test "x${have_pthread}" = "x1" ; then AC_DEFINE([HAVE_PTHREAD]) fi dnl dnl Process .in files. dnl AC_SUBST([cfghdrs]) AC_CONFIG_HEADER([$cfghdrs]) AC_SUBST([cfgoutputs]) AC_CONFIG_FILES([$cfgoutputs]) AC_OUTPUT xar-xar-498/xar/include/000077500000000000000000000000001446633275300152145ustar00rootroot00000000000000xar-xar-498/xar/include/.cvsignore000066400000000000000000000000171446633275300172120ustar00rootroot00000000000000config.h xar.h xar-xar-498/xar/include/config.h.in000066400000000000000000000014341446633275300172410ustar00rootroot00000000000000#undef HAVE_SYS_STATFS_H #undef HAVE_SYS_XATTR_H #undef HAVE_SYS_EXTATTR_H #undef HAVE_SYS_PARAM_H #undef HAVE_LGETXATTR #undef HAVE_LSETXATTR #undef HAVE_GETXATTR #undef HAVE_SETXATTR #undef HAVE_GETATTRLIST #undef HAVE_SETATTRLIST #undef HAVE_CHFLAGS #undef HAVE_STATVFS #undef HAVE_STATFS #undef HAVE_EXT2FS_EXT2_FS_H #undef HAVE_STRUCT_STAT_ST_FLAGS #undef HAVE_STRUCT_STATVFS_F_FSTYPENAME #undef HAVE_STRUCT_STATFS_F_FSTYPENAME #undef HAVE_SYS_ACL_H #undef HAVE_LIBUTIL_H #undef HAVE_LIBPTHREAD #undef HAVE_ASPRINTF #undef HAVE_LIBBZ2 #undef HAVE_LIBLZMA #undef HAVE_LCHOWN #undef HAVE_LCHMOD #undef HAVE_STRMODE #undef UID_STRING #undef UID_CAST #undef GID_STRING #undef GID_CAST #undef INO_STRING #undef INO_HEXSTRING #undef INO_CAST #undef DEV_STRING #undef DEV_HEXSTRING #undef DEV_CAST xar-xar-498/xar/include/xar.h.in000066400000000000000000000265241446633275300165750ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_H_ #define _XAR_H_ #if __cplusplus extern "C" { #endif #define XAR_VERSION "@XAR_VERSION@" #include #include #include #ifdef __APPLE__ #import #else #define API_DEPRECATED(...) #endif #pragma pack(4) struct xar_header { uint32_t magic; uint16_t size; uint16_t version; uint64_t toc_length_compressed; uint64_t toc_length_uncompressed; uint32_t cksum_alg; }; #pragma pack() typedef struct xar_header xar_header_t; #define XAR_HEADER_MAGIC 0x78617221 #define XAR_EA_FORK "ea" /* NONE is not supported for security reasons, and may not be supported by all implementations */ #define XAR_CKSUM_NONE 0 #define XAR_CKSUM_SHA1 1 /* MD5 is not supported for security reasons, and may not be supported by all implementations */ #define XAR_CKSUM_MD5 2 #define XAR_CKSUM_SHA256 3 #define XAR_CKSUM_SHA512 4 typedef void *xar_errctx_t; typedef const struct __xar_file_t *xar_file_t; typedef const struct __xar_iter_t *xar_iter_t; typedef const struct __xar_t *xar_t; typedef const struct __xar_subdoc_t *xar_subdoc_t; typedef const struct __xar_signature_t *xar_signature_t; typedef struct { char *next_out; unsigned int avail_out; unsigned long long total_in; unsigned long long total_out; void *state; } xar_stream; typedef int32_t (*err_handler)(int32_t severit, int32_t instance, xar_errctx_t ctx, void *usrctx); /* the signed_data must be allocated durring the callback and will be released by the xar lib after the callback */ typedef int32_t (*xar_signer_callback)(xar_signature_t sig, void *context, uint8_t *data, uint32_t length, uint8_t **signed_data, uint32_t *signed_len); typedef void (*xar_progress_callback)(xar_t x, xar_file_t f, size_t sizeread); #define READ 0 #define WRITE 1 /* xar stream return codes */ #define XAR_STREAM_OK 0 #define XAR_STREAM_END 1 #define XAR_STREAM_ERR -1 /* Valid xar options & values */ #define XAR_OPT_OWNERSHIP "ownership" /* setting owner/group behavior */ #define XAR_OPT_VAL_SYMBOLIC "symbolic" /* set owner/group based on names */ #define XAR_OPT_VAL_NUMERIC "numeric" /* set owner/group based on uid/gid */ #define XAR_OPT_TOCCKSUM "toc-cksum" /* set the toc checksum algorithm */ #define XAR_OPT_FILECKSUM "file-chksum" /* set the file checksum algorithm */ #define XAR_OPT_VAL_NONE "none" #define XAR_OPT_VAL_SHA1 "sha1" #define XAR_OPT_VAL_SHA256 "sha256" #define XAR_OPT_VAL_SHA512 "sha512" /* MD5 is not recommended for security reasons, and may not be supported by all implementations */ #define XAR_OPT_VAL_MD5 "md5" #define XAR_OPT_COMPRESSION "compression" /* set the file compression type */ #define XAR_OPT_COMPRESSIONARG "compression-arg" /* set the compression opts */ #define XAR_OPT_VAL_GZIP "gzip" #define XAR_OPT_VAL_BZIP "bzip2" #define XAR_OPT_VAL_LZMA "lzma" #define XAR_OPT_RSIZE "rsize" /* Read io buffer size */ #define XAR_OPT_COALESCE "coalesce" /* Coalesce identical heap blocks */ #define XAR_OPT_LINKSAME "linksame" /* Hardlink identical files */ #define XAR_OPT_PROPINCLUDE "prop-include" /* File property to include */ #define XAR_OPT_PROPEXCLUDE "prop-exclude" /* File property to exclude */ #define XAR_OPT_SAVESUID "savesuid" /* Preserve setuid/setgid bits */ #define XAR_OPT_VAL_TRUE "true" #define XAR_OPT_VAL_FALSE "false" /* xar signing algorithms */ #define XAR_SIG_SHA1RSA 1 /* xar error handler macros */ #define XAR_SEVERITY_DEBUG 1 #define XAR_SEVERITY_INFO 2 #define XAR_SEVERITY_NORMAL 3 #define XAR_SEVERITY_WARNING 4 #define XAR_SEVERITY_NONFATAL 5 #define XAR_SEVERITY_FATAL 6 #define XAR_ERR_ARCHIVE_CREATION 1 #define XAR_ERR_ARCHIVE_EXTRACTION 2 xar_t xar_open(const char *file, int32_t flags) API_DEPRECATED("xar is a deprecated file format and should not be used.", macos(10.4,12.0)); xar_t xar_open_digest_verify(const char *file, int32_t flags, void *expected_toc_digest, size_t expected_toc_digest_len) API_DEPRECATED("xar is a deprecated file format and should not be used.", macos(10.14.4,12.0)); int xar_close(xar_t x); xar_header_t xar_header_get(xar_t x); xar_file_t xar_add(xar_t x, const char *path); xar_file_t xar_add_frombuffer(xar_t x, xar_file_t parent, const char *name, char *buffer, size_t length); xar_file_t xar_add_folder(xar_t x, xar_file_t f, const char *name, struct stat *info); xar_file_t xar_add_frompath(xar_t x, xar_file_t parent, const char *name, const char *realpath); xar_file_t xar_add_from_archive(xar_t x, xar_file_t parent, const char *name, xar_t sourcearchive, xar_file_t sourcefile); int32_t xar_extract(xar_t x, xar_file_t f); int32_t xar_extract_tofile(xar_t x, xar_file_t f, const char *path); int32_t xar_extract_tobuffer(xar_t x, xar_file_t f, char **buffer); int32_t xar_extract_tobuffersz(xar_t x, xar_file_t f, char **buffer, size_t *size); int32_t xar_extract_tostream_init(xar_t x, xar_file_t f, xar_stream *stream); int32_t xar_extract_tostream(xar_stream *stream); int32_t xar_extract_tostream_end(xar_stream *stream); int32_t xar_verify(xar_t x, xar_file_t f); int32_t xar_verify_progress(xar_t x, xar_file_t f, xar_progress_callback progress); /* To get the checksum of the table of contents use this function. * The function returns a alloced buffer that caller must free. */ void* xar_get_toc_checksum(xar_t x, size_t* buffer_size); /* Returns XAR_CKSUM_* that maps to the type of the checksum. */ int32_t xar_get_toc_checksum_type(xar_t x); const char *xar_opt_get(xar_t x, const char *option); int32_t xar_opt_set(xar_t x, const char *option, const char *value); int32_t xar_opt_unset(xar_t x, const char *option); int32_t xar_prop_set(xar_file_t f, const char *key, const char *value); int32_t xar_prop_create(xar_file_t f, const char *key, const char *value); int32_t xar_prop_get(xar_file_t f, const char *key, const char **value); int32_t xar_prop_get_expect_notnull(xar_file_t f, const char *key, const char **value); xar_iter_t xar_iter_new(void); void xar_iter_free(xar_iter_t i); const char *xar_prop_first(xar_file_t f, xar_iter_t i); const char *xar_prop_next(xar_iter_t i); void xar_prop_unset(xar_file_t f, const char *key); xar_file_t xar_file_first(xar_t x, xar_iter_t i); xar_file_t xar_file_next(xar_iter_t i); const char *xar_attr_get(xar_file_t f, const char *prop, const char *key); int32_t xar_attr_set(xar_file_t f, const char *prop, const char *key, const char *value); const char *xar_attr_first(xar_file_t f, const char *prop, xar_iter_t i); const char *xar_attr_next(xar_iter_t i); xar_subdoc_t xar_subdoc_new(xar_t x, const char *name); int32_t xar_subdoc_prop_set(xar_subdoc_t s, const char *key, const char *value); int32_t xar_subdoc_prop_get(xar_subdoc_t s, const char *key, const char **value); int32_t xar_subdoc_attr_set(xar_subdoc_t s, const char *prop, const char *key, const char *value); const char *xar_subdoc_attr_get(xar_subdoc_t s, const char *prop, const char *key); xar_subdoc_t xar_subdoc_first(xar_t x); xar_subdoc_t xar_subdoc_next(xar_subdoc_t s); const char *xar_subdoc_name(xar_subdoc_t s); int32_t xar_subdoc_copyout(xar_subdoc_t s, unsigned char **, unsigned int *); int32_t xar_subdoc_copyin(xar_subdoc_t s, const unsigned char *, unsigned int); void xar_subdoc_remove(xar_subdoc_t s); /* signature api for adding various signature types */ xar_signature_t xar_signature_new(xar_t x,const char *type, int32_t length, xar_signer_callback callback, void *callback_context); /* extended signatures are ignored by previous versions of xar */ xar_signature_t xar_signature_new_extended(xar_t x,const char *type, int32_t length, xar_signer_callback callback, void *callback_context); const char *xar_signature_type(xar_signature_t s); xar_signature_t xar_signature_first(xar_t x); xar_signature_t xar_signature_next(xar_signature_t s); int32_t xar_signature_add_x509certificate(xar_signature_t sig, const uint8_t *cert_data, uint32_t cert_len ); int32_t xar_signature_get_x509certificate_count(xar_signature_t sig); int32_t xar_signature_get_x509certificate_data(xar_signature_t sig, int32_t index, const uint8_t **cert_data, uint32_t *cert_len); uint8_t xar_signature_copy_signed_data(xar_signature_t sig, uint8_t **data, uint32_t *length, uint8_t **signed_data, uint32_t *signed_length, off_t *signed_offset); /* Helper functions - caller must free returned memory */ char *xar_get_size(xar_t x, xar_file_t f); char *xar_get_type(xar_t x, xar_file_t f); char *xar_get_mode(xar_t x, xar_file_t f); char *xar_get_owner(xar_t x, xar_file_t f); char *xar_get_group(xar_t x, xar_file_t f); char *xar_get_mtime(xar_t x, xar_file_t f); /* For helping calling apps harden against hacked archives that attempt to escape their extraction roots. */ int xar_path_issane(char* path); /* These are for xar modules and should never be needed from a calling app */ void xar_register_errhandler(xar_t x, err_handler callback, void *usrctx); xar_t xar_err_get_archive(xar_errctx_t ctx); xar_file_t xar_err_get_file(xar_errctx_t ctx); const char *xar_err_get_string(xar_errctx_t ctx); int xar_err_get_errno(xar_errctx_t ctx); void xar_err_set_file(xar_t x, xar_file_t f); void xar_err_set_formatted_string(xar_t x, const char *format, ...); void xar_err_set_string(xar_t x, const char *str); void xar_err_set_errno(xar_t x, int e); void xar_err_new(xar_t x); int32_t xar_err_callback(xar_t x, int32_t sev, int32_t err); void xar_serialize(xar_t x, const char *file); char *xar_get_path(xar_file_t f) API_DEPRECATED("Use xar_get_safe_path instead", macos(10.4,12.0)); char *xar_get_safe_path(xar_file_t f) API_AVAILABLE(macos(12.0)); off_t xar_get_heap_offset(xar_t x); uint64_t xar_ntoh64(uint64_t num); int xar_get_archive_fd(xar_t x); #if __cplusplus } #endif #endif /* _XAR_H_ */ xar-xar-498/xar/install-sh000077500000000000000000000127211446633275300156000ustar00rootroot00000000000000#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 xar-xar-498/xar/lib/000077500000000000000000000000001446633275300143375ustar00rootroot00000000000000xar-xar-498/xar/lib/.cvsignore000066400000000000000000000000441446633275300163350ustar00rootroot00000000000000Makefile.inc librxar.* libxar.* *.d xar-xar-498/xar/lib/Makefile.inc.in000066400000000000000000000130601446633275300171540ustar00rootroot00000000000000# # File lists. # # Internal headers. LIBXAR_IINCS := asprintf.h LIBXAR_IINCS := $(patsubst %, @srcroot@include/%, $(LIBXAR_IINCS)) LIBXAR_IINCS += @objroot@include/config.h # Headers. LIBXAR_INCS := LIBXAR_INCS := $(patsubst %, @srcroot@include/%, $(LIBXAR_INCS)) LIBXAR_INCS += @objroot@include/xar.h # Sources. LIBXAR_SRCS := archive.c arcmod.c b64.c bzxar.c darwinattr.c data.c ea.c err.c LIBXAR_SRCS += ext2.c fbsdattr.c filetree.c io.c lzmaxar.c linuxattr.c hash.c LIBXAR_SRCS += signature.c stat.c subdoc.c util.c zxar.c script.c macho.c LIBXAR_SRCS := $(patsubst %, @srcroot@lib/%, $(LIBXAR_SRCS)) # Libraries. librxar is created such that it's possible to run xar without # first installing libxar. LIBXAR_LANAME := libxar.la LIBXAR_ANAME := libxar.a ifeq (elf, @abi@) LIBRXAR_SNAME := librxar.so.@LIB_REV@ LIBRXAR_LNAME := librxar.so LIBRXAR_L := @objroot@lib/$(LIBRXAR_LNAME) LIBXAR_SNAME := libxar.so.@LIB_REV@ LIBXAR_LNAME := libxar.so LIBXAR_L := @objroot@lib/$(LIBXAR_LNAME) endif ifeq (macho, @abi@) LIBRXAR_SNAME := librxar.@LIB_REV@.dylib LIBRXAR_LNAME := librxar.dylib LIBRXAR_L := @objroot@lib/$(LIBRXAR_LNAME) LIBXAR_SNAME := libxar.@LIB_REV@.dylib LIBXAR_LNAME := libxar.dylib LIBXAR_L := @objroot@lib/$(LIBXAR_LNAME) endif ifeq (aout, @abi@) LIBRXAR_SNAME := librxar.so.@LIB_REV@.0 LIBRXAR_LNAME := LIBRXAR_L := LIBXAR_SNAME := libxar.so.@LIB_REV@.0 LIBXAR_LNAME := LIBXAR_L := endif LIBXAR_LA := @objroot@lib/$(LIBXAR_LANAME) LIBXAR_A := @objroot@lib/$(LIBXAR_ANAME) LIBRXAR_S := @objroot@lib/$(LIBRXAR_SNAME) LIBXAR_S := @objroot@lib/$(LIBXAR_SNAME) # # Include generated dependency files. # -include $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.d) LDFLAGS := -L@objroot@lib $(LDFLAGS) # # User make'ables. # lib_all : lib_shared lib_static $(LIBXAR_LA) ifeq (yes, @shared@) lib_shared : $(LIBRXAR_S) $(LIBXAR_S) else lib_shared : endif ifeq (yes, @static@) lib_static : $(LIBXAR_A) else lib_static : endif lib_install : lib_shared lib_static @INSTALL@ -d $(DESTDIR)$(INCLUDEDIR)/xar @INSTALL@ -m 0644 $(LIBXAR_INCS) $(DESTDIR)$(INCLUDEDIR)/xar @INSTALL@ -d $(DESTDIR)$(LIBDIR) ifeq (yes, @shared@) @INSTALL@ -m 0755 $(LIBXAR_S) $(DESTDIR)$(LIBDIR) ifneq ($(words "" $(LIBXAR_LNAME)), 1) rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_LNAME) ln -s $(LIBXAR_SNAME) $(DESTDIR)$(LIBDIR)/$(LIBXAR_LNAME) endif endif ifeq (yes, @static@) @INSTALL@ -m 0644 $(LIBXAR_A) $(DESTDIR)$(LIBDIR) endif @INSTALL@ -m 0644 $(LIBXAR_LA) $(DESTDIR)$(LIBDIR) lib_uninstall : rm -rf $(DESTDIR)$(INCLUDEDIR)/xar ifeq (yes, @shared@) rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_SNAME) ifneq ($(words "" $(LIBXAR_LNAME)), 1) rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_LNAME) endif endif ifeq (yes, @static@) rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_ANAME) endif rm -f $(DESTDIR)$(LIBDIR)/$(LIBXAR_LANAME) lib_clean : rm -f $(LIBRXAR_S) $(LIBRXAR_L) rm -f $(LIBXAR_S) $(LIBXAR_L) rm -f $(LIBXAR_A) $(LIBXAR_LA) @rm -f @objroot@lib/.libs/$(LIBXAR_LNAME) @rm -f @objroot@lib/.libs/$(LIBXAR_ANAME) @-rmdir @objroot@lib/.libs rm -f $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.o) rm -f $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.d) rm -f $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.static.o) rm -f $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.static.d) lib_distclean : # # Various flags. # CPPFLAGS := -I@objroot@include $(CPPFLAGS) CPPFLAGS := -I@srcroot@include $(CPPFLAGS) # # Build rules. # # librxar is a version of the xar library that is usable without first # installing libxar. $(LIBRXAR_S) : $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.o) @mkdir -p $(@D) ifeq (elf, @abi@) $(CC) -shared -Wl,-soname,$(LIBXAR_SNAME) -o $@ $+ $(LDFLAGS) @LIBS@ endif ifeq (macho, @abi@) $(CC) -dynamiclib -compatibility_version @LIB_REV@ -current_version @LIB_REV@ -install_name @abs_objroot@$(LIBRXAR_S) -o $@ $+ $(LDFLAGS) @LIBS@ endif ifeq (aout, @abi@) $(CC) -shared -o $@ $+ endif ifneq ($(words "" $(LIBRXAR_L)), 1) rm -f $(LIBRXAR_L) ln -s $(LIBRXAR_SNAME) $(LIBRXAR_L) endif $(LIBXAR_S) : $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.o) @mkdir -p $(@D) ifeq (elf, @abi@) $(CC) -shared -Wl,-soname,$(LIBXAR_SNAME) -o $@ $+ $(LDFLAGS) @LIBS@ endif ifeq (macho, @abi@) $(CC) -dynamiclib -compatibility_version @LIB_REV@ -current_version @LIB_REV@ -install_name $(LIBDIR)/$(LIBXAR_SNAME) -o $@ $+ $(LDFLAGS) @LIBS@ endif ifeq (aout, @abi@) $(CC) -shared -o $@ $+ endif ifneq ($(words "" $(LIBXAR_L)), 1) rm -f $(LIBXAR_L) ln -s $(LIBXAR_SNAME) $(LIBXAR_L) endif ifeq (yes, @shared@) LT_LIBXAR_SNAME := $(LIBXAR_SNAME) LT_LIBXAR_LNAME := $(LIBXAR_LNAME) else LT_LIBXAR_SNAME := LT_LIBXAR_LNAME := endif ifeq (yes, @static@) LT_LIBXAR_ANAME := $(LIBXAR_ANAME) else LT_LIBXAR_ANAME := endif $(LIBXAR_LA) : $(LIBXAR_LA).in @mkdir -p @objroot@lib/.libs ifeq (yes, @shared@) @ln -sf ../$(LIBXAR_LNAME) @objroot@lib/.libs/$(LIBXAR_LNAME) endif ifeq (yes, @static@) @ln -sf ../$(LIBXAR_ANAME) @objroot@lib/.libs/$(LIBXAR_ANAME) endif sed -e s/@LIBXAR_SNAME@/$(LT_LIBXAR_SNAME)/ -e s/@LIBXAR_LNAME@/$(LT_LIBXAR_LNAME)/ -e s/@LIBXAR_ANAME@/$(LT_LIBXAR_ANAME)/ < $< > $@ $(LIBXAR_A) : $(LIBXAR_SRCS:@srcroot@%.c=@objroot@%.static.o) @mkdir -p $(@D) $(AR) cvr $@ $+ $(RANLIB) $@ @objroot@lib/%.o : @srcroot@lib/%.c @mkdir -p $(@D) $(CC) $(S_CFLAGS) $(CPPFLAGS) -c $< -o $@ @$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)" @objroot@lib/%.static.o : @srcroot@lib/%.c @mkdir -p $(@D) $(CC) $(A_CFLAGS) $(CPPFLAGS) -c $< -o $@ @$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)" xar-xar-498/xar/lib/appledouble.h000066400000000000000000000065031446633275300170100ustar00rootroot00000000000000/* Information pulled from: * "AppleSingle/AppleDouble Formats for Foreign Files Developer's Note" * (c) Apple Computer 1990 * File assembled by Rob Braun (bbraun@synack.net) */ #ifndef __APPLEDOUBLE__ #define __APPLEDOUBLE__ #include #include /* Structure of an AppleSingle file: * ---------------------- * | AppleSingleHeader | * |--------------------| * | ASH.entries # of | * | AppleSingleEntry | * | Descriptors | * | 1 | * | . | * | . | * | n | * |--------------------| * | Datablock 1 | * |--------------------| * | Datablock 2 | * |--------------------| * | Datablock n | * ---------------------- */ struct AppleSingleHeader { uint32_t magic; /* Magic Number (0x00051600 for AS) */ uint32_t version; /* Version #. 0x00020000 */ char filler[16]; /* All zeros */ uint16_t entries; /* Number of entries in the file */ }; #define XAR_ASH_SIZE 26 /* sizeof(struct AppleSingleHeader) will be wrong * due to padding. */ #define APPLESINGLE_MAGIC 0x00051600 #define APPLEDOUBLE_MAGIC 0x00051607 #define APPLESINGLE_VERSION 0x00020000 #define APPLEDOUBLE_VERSION 0x00020000 struct AppleSingleEntry { uint32_t entry_id; /* What the entry is. See defines below */ uint32_t offset; /* offset of data, offset beginning of file */ uint32_t length; /* length of data. can be 0 */ }; /* Valid entry_id values */ /* Entries 1, 3, and 8 are typically created for all files. * Macintosh Icon entries are rare, since those are typically in the resource * fork. */ #define AS_ID_DATA 1 /* Data fork */ #define AS_ID_RESOURCE 2 /* Resource fork */ #define AS_ID_NAME 3 /* Name of the file */ #define AS_ID_COMMENT 4 /* Standard Macintosh comment */ #define AS_ID_BWICON 5 /* Standard Macintosh B&W icon */ #define AS_ID_COLORICON 6 /* Standard Macintosh Color icon */ /* There is no 7 */ #define AS_ID_DATES 8 /* File creation date, modification date, etc. */ #define AS_ID_FINDER 9 /* Finder Information */ #define AS_ID_MAC 10 /* Macintosh File information, attributes, etc. */ #define AS_ID_PRODOS 11 /* ProDOS file information */ #define AS_ID_MSDOS 12 /* MS-DOS file information */ #define AS_ID_SHORTNAME 13 /* AFP short name */ #define AS_ID_AFPINFO 14 /* AFP file information */ #define AS_ID_AFPDIR 15 /* AFP directory id */ /* 1-0x7FFFFFFF are reserved by Apple */ /* File Dates are stored as the # of seconds before or after * 12am Jan 1, 2000 GMT. The default value is 0x80000000. */ struct MacTimes { uint32_t creation; uint32_t modification; uint32_t backup; uint32_t access; }; /* Finder Information is two 16 byte quantities. * Newly created files have all 0's in both entries. */ /* Macintosh File Info entry (10) a 32 bit bitmask. */ /* Entries can be placed in any order, although Apple recommends: * Place the data block (1) last. * Finder Info, File Dates Info, and Macintosh File Info first. * Allocate resource for entries in 4K blocks. */ /* AppleDouble files are simply AppleSingle files without the data fork. * The magic number is different as a read optimization. */ #endif /* __APPLEDOUBLE__ */ xar-xar-498/xar/lib/archive.c000066400000000000000000001376431446633275300161420ustar00rootroot00000000000000/* * Copyright (c) 2005-2008 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include "config.h" #include #include #include #include #include #include #include #include #include #include /* for ntoh{l,s} */ #include /* for PRIu64 */ #include #include #include #include #ifdef HAVE_LIBPTHREAD #include #endif // HAVE_LIBPTHREAD #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "filetree.h" #include "archive.h" #include "signature.h" #include "arcmod.h" #include "io.h" #include "util.h" #include "subdoc.h" #include "darwinattr.h" #ifndef O_EXLOCK #define O_EXLOCK 0 #endif #ifndef O_SHLOCK #define O_SHLOCK 0 #endif #ifndef LONG_MAX #define LONG_MAX INT32_MAX #endif #ifndef LONG_MIN #define LONG_MIN INT32_MIN #endif #if LIBXML_VERSION < 20618 #define xmlDictCleanup() /* function doesn't exist in older API */ #endif static int32_t xar_unserialize(xar_t x); void xar_serialize(xar_t x, const char *file); #ifdef HAVE_LIBPTHREAD static pthread_mutex_t xar_new_mutex = PTHREAD_MUTEX_INITIALIZER; #endif // HAVE_LIBPTHREAD /* xar_new * Returns: newly allocated xar_t structure * Summary: just does basicallocation and initialization of * xar_t structure. */ static xar_t xar_new() { xar_t ret; ret = malloc(sizeof(struct __xar_t)); if(!ret) return NULL; memset(XAR(ret), 0, sizeof(struct __xar_t)); XAR(ret)->readbuf_len = 4096; XAR(ret)->readbuf = malloc(XAR(ret)->readbuf_len); if(!XAR(ret)->readbuf) { free((void *)ret); return NULL; } XAR(ret)->fd = -1; XAR(ret)->offset = 0; XAR(ret)->zs.zalloc = Z_NULL; XAR(ret)->zs.zfree = Z_NULL; XAR(ret)->zs.opaque = Z_NULL; // xmlHashCreate() calls libxml2's random number generator, which is not thread- // safe and can deadlock. Protecting this with a mutex permits multi-threaded use // of xar_open(). #ifdef HAVE_LIBPTHREAD pthread_mutex_lock(&xar_new_mutex); #else #warning libpthread unavailable. Potential for deadlock with multithreaded xar_open() use. #endif // HAVE_LIBPTHREAD XAR(ret)->ino_hash = xmlHashCreate(0); XAR(ret)->link_hash = xmlHashCreate(0); XAR(ret)->csum_hash = xmlHashCreate(0); #ifdef HAVE_LIBPTHREAD pthread_mutex_unlock(&xar_new_mutex); #endif // HAVE_LIBPTHREAD XAR(ret)->subdocs = NULL; XAR(ret)->attrcopy_to_heap = xar_attrcopy_to_heap; XAR(ret)->attrcopy_from_heap = xar_attrcopy_from_heap; XAR(ret)->heap_to_archive = xar_heap_to_archive; return ret; } /* xar_parse_header * x: archive to operate on. * Returns: 0 on success, -1 on failure * Summary: internal helper function to read in the xar header. */ static int32_t xar_parse_header(xar_t x) { ssize_t r; int off = 0; int sz2read = 0; /* read just the magic, verify it, read the header length, * then read in the size of the header according to the * recorded header length, or the length of the structure * we expect, whichever is smaller. Then seek forward * if the recorded header length is greater than the * expected header length. */ size_t size_to_read = sizeof(XAR(x)->header.magic)-off; r = xar_read_fd(XAR(x)->fd, (char *)&XAR(x)->header.magic+off, size_to_read); if ( r == -1 || size_to_read != r) return -1; /* Verify the header. If the header doesn't match, exit without * attempting to read any more. */ XAR(x)->header.magic = ntohl(XAR(x)->header.magic); if( XAR(x)->header.magic != XAR_HEADER_MAGIC ) { return -1; } size_to_read = sizeof(XAR(x)->header.size)-off; r = xar_read_fd(XAR(x)->fd, (char *)&XAR(x)->header.size+off, size_to_read); if ( r == -1 || size_to_read != r ) return r; XAR(x)->header.size = ntohs(XAR(x)->header.size); if( XAR(x)->header.size > sizeof(xar_header_t) ) sz2read = sizeof(xar_header_t); else sz2read = XAR(x)->header.size; off = sizeof(XAR(x)->header.magic) + sizeof(XAR(x)->header.size); size_to_read = sizeof(xar_header_t)-off; r = xar_read_fd(XAR(x)->fd, ((char *)&XAR(x)->header)+off, size_to_read); if ( r == -1 || size_to_read != r) return r; XAR(x)->header.version = ntohs(XAR(x)->header.version); XAR(x)->header.toc_length_compressed = xar_ntoh64(XAR(x)->header.toc_length_compressed); XAR(x)->header.toc_length_uncompressed = xar_ntoh64(XAR(x)->header.toc_length_uncompressed); XAR(x)->header.cksum_alg = ntohl(XAR(x)->header.cksum_alg); off = XAR(x)->header.size - sz2read; if( off > 0 ) r = lseek(XAR(x)->fd, (off_t)off, SEEK_CUR); if ( (r == -1) && (errno != ESPIPE) ) /* Some fatal error here perhaps? */ ; return 0; } xar_t xar_open(const char *file, int32_t flags) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability-new" return xar_open_digest_verify(file, flags, NULL, 0); #pragma clang diagnostic pop } /* xar_open * file: filename to open * flags: flags on how to open the file. 0 for readonly, !0 for read/write * expected_toc_digest: Requires that the xar being opened matches the digest specified. * expected_toc_digest_len: The length of the expected_toc_digest. * Returns: allocated and initialized xar structure with an open * file descriptor to the target xar file. If the xarchive is opened * for writing, the file is created, and a heap file is opened. */ xar_t xar_open_digest_verify(const char *file, int32_t flags, void *expected_toc_digest, size_t expected_toc_digest_len) { xar_t ret; ret = xar_new(); if( !ret ) return NULL; if( !file ) file = "-"; XAR(ret)->filename = strdup(file); if( flags ) { // writing char *tmp1, *tmp2, *tmp4; tmp1 = tmp2 = strdup(file); XAR(ret)->dirname = xar_safe_dirname(tmp2); /* Create the heap file in the directory which will contain * the target archive. /tmp or elsewhere may fill up. */ asprintf(&tmp4, "%s/xar.heap.XXXXXX", XAR(ret)->dirname); free(tmp1); if( strcmp(file, "-") == 0 ) XAR(ret)->fd = 1; else{ XAR(ret)->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_EXLOCK, 0644); if( (-1 == XAR(ret)->fd ) && (ENOTSUP == errno) ){ XAR(ret)->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC , 0644); } } XAR(ret)->heap_fd = mkstemp(tmp4); if( XAR(ret)->heap_fd < 0 ) { close(XAR(ret)->fd); free(XAR(ret)); return NULL; } unlink(tmp4); free(tmp4); deflateInit(&XAR(ret)->zs, Z_BEST_COMPRESSION); if( XAR(ret)->fd < 0 ) { xar_close(ret); return NULL; } /* default to using sha1, if nothing else is * specified. */ XAR(ret)->heap_offset += 20; XAR(ret)->heap_len += 20; xar_opt_set(ret, XAR_OPT_COMPRESSION, XAR_OPT_VAL_GZIP); xar_opt_set(ret, XAR_OPT_FILECKSUM, XAR_OPT_VAL_SHA1); xar_opt_set(ret, XAR_OPT_TOCCKSUM, XAR_OPT_VAL_SHA1); } else { if( strcmp(file, "-") == 0 ) XAR(ret)->fd = 0; else{ XAR(ret)->fd = open(file, O_RDONLY | O_SHLOCK); if( (-1 == XAR(ret)->fd ) && (ENOTSUP == errno) ){ XAR(ret)->fd = open(file, O_RDONLY); } } XAR(ret)->heap_fd = -1; inflateInit(&XAR(ret)->zs); if( XAR(ret)->fd < 0 ) { xar_close(ret); return NULL; } if( xar_parse_header(ret) != 0 ) { xar_close(ret); return NULL; } switch(XAR(ret)->header.cksum_alg) { case XAR_CKSUM_NONE: fprintf(stderr, "Archive uses no hashing algorithm, aborting\n"); xar_close(ret); return NULL; break; case XAR_CKSUM_SHA1: XAR(ret)->toc_hash_ctx = xar_hash_new("sha1", (void *)ret); break; case XAR_CKSUM_SHA256: XAR(ret)->toc_hash_ctx = xar_hash_new("sha256", (void *)ret); break; case XAR_CKSUM_SHA512: XAR(ret)->toc_hash_ctx = xar_hash_new("sha512", (void *)ret); break; case XAR_CKSUM_MD5: #ifdef XAR_SUPPORT_MD5 XAR(ret)->toc_hash_ctx = xar_hash_new("md5", (void *)ret); break; #else fprintf(stderr, "Archive uses unsafe hashing algorithm (MD5), aborting\n"); xar_close(ret); return NULL; #endif // XAR_SUPPORT_MD5 default: fprintf(stderr, "Unknown hashing algorithm, skipping\n"); break; }; // deserialize the TOC if( xar_unserialize(ret) != 0 ) { xar_close(ret); return NULL; } /* check for inconsistency between checksum style in header, * and the one described in the TOC; otherwise, you can flip * the header bit to XAR_CKSUM_NONE, and nothing will ever * verify that the TOC matches the checksum stored in the * heap, and the signature check will pass on a modified * file! */ int cksum_match = 0; const char* cksum_style = xar_attr_get(XAR_FILE(ret), "checksum", "style"); switch(XAR(ret)->header.cksum_alg) { case XAR_CKSUM_NONE: // Although we no longer support none, we are leaving this here to detect mismatches cksum_match = (cksum_style == NULL || strcmp(cksum_style, XAR_OPT_VAL_NONE) == 0); break; case XAR_CKSUM_SHA1: cksum_match = (cksum_style != NULL && strcmp(cksum_style, XAR_OPT_VAL_SHA1) == 0); break; case XAR_CKSUM_SHA256: cksum_match = (cksum_style != NULL && strcmp(cksum_style, XAR_OPT_VAL_SHA256) == 0); break; case XAR_CKSUM_SHA512: cksum_match = (cksum_style != NULL && strcmp(cksum_style, XAR_OPT_VAL_SHA512) == 0); break; case XAR_CKSUM_MD5: // This is left in place regardless of XAR_SUPPORT_MD5 setting so we can still detect mismatches cksum_match = (cksum_style != NULL && strcmp(cksum_style, XAR_OPT_VAL_MD5) == 0); break; default: cksum_match = 0; break; } if( !cksum_match ) { fprintf(stderr, "Checksum style mismatch!\n"); xar_close(ret); return NULL; } /* also check for consistency between the checksum style and * the existence (or not) of signatures: since the signature * is signing the checksum, we must have a checksum to verify * that the TOC has not been modified */ if( xar_signature_first(ret) != NULL && XAR(ret)->header.cksum_alg == XAR_CKSUM_NONE ) { fprintf(stderr, "Checksum/signature mismatch!\n"); xar_close(ret); return NULL; } /* If we aren't checksumming the TOC, we're done */ if( !XAR(ret)->toc_hash_ctx ) return ret; /* if TOC specifies a location for the checksum, make sure that * we read the checksum from there: this is required for an archive * with a signature, because the signature will be checked against * the checksum at the specified location */ const char *value; uint64_t offset = 0; uint64_t length = 0; if( xar_prop_get( XAR_FILE(ret) , "checksum/offset", &value) == 0 ) { if (value) { errno = 0; offset = strtoull( value, (char **)NULL, 10); if( errno != 0 ) { fprintf(stderr, "checksum/offset missing or invalid!\n"); xar_close(ret); return NULL; } } else { fprintf(stderr, "checksum/offset missing or invalid!\n"); xar_close(ret); return NULL; } } else if( xar_signature_first(ret) != NULL ) { // All archives that have a signature also specify the location // of the checksum. If the location isn't specified, error out. xar_close(ret); return NULL; } XAR(ret)->heap_offset = xar_get_heap_offset(ret) + offset; if( lseek(XAR(ret)->fd, XAR(ret)->heap_offset, SEEK_SET) == -1 ) { xar_close(ret); return NULL; } if( xar_prop_get( XAR_FILE(ret) , "checksum/size", &value) == 0 ) { if (value) { errno = 0; length = strtoull( value, (char **)NULL, 10); if( errno != 0 ) { fprintf(stderr, "checksum/size missing or invalid!\n"); xar_close(ret); return NULL; } } else { fprintf(stderr, "checksum/size missing or invalid!\n"); xar_close(ret); return NULL; } } else if( xar_signature_first(ret) != NULL ) { xar_close(ret); return NULL; } size_t tlen = 0; void *toccksum = xar_hash_finish(XAR(ret)->toc_hash_ctx, &tlen); XAR(ret)->toc_hash_ctx = NULL; if( length != tlen ) { free(toccksum); xar_close(ret); return NULL; } // Store our toc hash upon archive open, so callers can determine if it // has changed or been tampered with after archive open XAR(ret)->toc_hash = malloc(tlen); memcpy(XAR(ret)->toc_hash, toccksum, tlen); XAR(ret)->toc_hash_size = tlen; void *cval = calloc(1, tlen); if( ! cval ) { free(toccksum); xar_close(ret); return NULL; } ssize_t r = xar_read_fd(XAR(ret)->fd, cval, tlen); if (r < 0 || r != tlen) { free(toccksum); xar_close(ret); return NULL; } XAR(ret)->heap_offset += tlen; if( memcmp(cval, toccksum, tlen) != 0 ) { fprintf(stderr, "Checksums do not match!\n"); free(toccksum); free(cval); xar_close(ret); return NULL; } free(toccksum); free(cval); } if ( expected_toc_digest ) { if ( ! XAR(ret)->toc_hash ) { fprintf(stderr, "xar_open_digest_verify: xar lacks a toc_hash.\n"); xar_close(ret); return NULL; } if ( XAR(ret)->toc_hash_size != expected_toc_digest_len ) { fprintf(stderr, "xar_open_digest_verify: toc digest length does not match the expected digest length.\n"); xar_close(ret); return NULL; } if ( memcmp(XAR(ret)->toc_hash, expected_toc_digest, expected_toc_digest_len) != 0 ) { fprintf(stderr, "xar_open_digest_verify: toc digest does not match the expected.\n"); xar_close(ret); return NULL; } } return ret; } void* xar_get_toc_checksum(xar_t x, size_t* buffer_size) { // Required in, missing. if (!buffer_size) return NULL; // Sanity set values void* result = NULL; *buffer_size = 0; // If we have a hash, return it. if (XAR(x)->toc_hash) { *buffer_size = XAR(x)->toc_hash_size; result = calloc(*buffer_size, 1); // Malloc fail? if (!result) return NULL; memcpy(result, XAR(x)->toc_hash, XAR(x)->toc_hash_size); } return result; } int32_t xar_get_toc_checksum_type(xar_t x) { return XAR(x)->header.cksum_alg; } /* xar_close * x: the xar_t to close * Summary: closes all open file descriptors, frees all * file structures and options, deallocates the xar_t its self. * Returns 0 for success, -1 for failure. */ int xar_close(xar_t x) { xar_attr_t a; xar_file_t f; int ret, retval = 0; /* If we're creating an archive */ if( XAR(x)->heap_fd != -1 ) { char *tmpser; void *rbuf, *wbuf = NULL; int fd, r, off, wbytes, rbytes; size_t rsize, wsize; z_stream zs; uint64_t ungztoc, gztoc; int tocfd; char timestr[128]; struct tm tmptm; time_t t; tmpser = (char *)xar_opt_get(x, XAR_OPT_TOCCKSUM); /* If no checksum type is specified, default to sha1 */ if( !tmpser ) tmpser = XAR_OPT_VAL_SHA1; if( (strcmp(tmpser, XAR_OPT_VAL_NONE) != 0) ) { xar_prop_set(XAR_FILE(x), "checksum", NULL); if( strcmp(tmpser, XAR_OPT_VAL_SHA1) == 0 ) { XAR(x)->toc_hash_ctx = xar_hash_new("sha1", (void *)x); XAR(x)->header.cksum_alg = htonl(XAR_CKSUM_SHA1); xar_attr_set(XAR_FILE(x), "checksum", "style", XAR_OPT_VAL_SHA1); xar_prop_set(XAR_FILE(x), "checksum/size", "20"); } if( strcmp(tmpser, XAR_OPT_VAL_SHA256) == 0 ) { XAR(x)->toc_hash_ctx = xar_hash_new("sha256", (void *)x); XAR(x)->header.cksum_alg = htonl(XAR_CKSUM_SHA256); xar_attr_set(XAR_FILE(x), "checksum", "style", XAR_OPT_VAL_SHA256); xar_prop_set(XAR_FILE(x), "checksum/size", "32"); } if( strcmp(tmpser, XAR_OPT_VAL_SHA512) == 0 ) { XAR(x)->toc_hash_ctx = xar_hash_new("sha512", (void *)x); XAR(x)->header.cksum_alg = htonl(XAR_CKSUM_SHA512); xar_attr_set(XAR_FILE(x), "checksum", "style", XAR_OPT_VAL_SHA512); xar_prop_set(XAR_FILE(x), "checksum/size", "64"); } #ifdef XAR_SUPPORT_MD5 if( strcmp(tmpser, XAR_OPT_VAL_MD5) == 0 ) { XAR(x)->toc_hash_ctx = xar_hash_new("md5", (void *)x); XAR(x)->header.cksum_alg = htonl(XAR_CKSUM_MD5); xar_attr_set(XAR_FILE(x), "checksum", "style", XAR_OPT_VAL_MD5); xar_prop_set(XAR_FILE(x), "checksum/size", "16"); } #endif // XAR_SUPPORT_MD5 xar_prop_set(XAR_FILE(x), "checksum/offset", "0"); } else { XAR(x)->header.cksum_alg = XAR_CKSUM_NONE; } t = time(NULL); gmtime_r(&t, &tmptm); memset(timestr, 0, sizeof(timestr)); strftime(timestr, sizeof(timestr), "%FT%T", &tmptm); xar_prop_set(XAR_FILE(x), "creation-time", timestr); /* serialize the toc to a tmp file */ asprintf(&tmpser, "%s/xar.toc.XXXXXX", XAR(x)->dirname); fd = mkstemp(tmpser); xar_serialize(x, tmpser); unlink(tmpser); free(tmpser); asprintf(&tmpser, "%s/xar.toc.XXXXXX", XAR(x)->dirname); tocfd = mkstemp(tmpser); unlink(tmpser); free(tmpser); /* read the toc from the tmp file, compress it, and write it * out to the archive. */ rsize = wsize = xar_optimal_io_size_at_path(XAR(x)->dirname); const char * opt = xar_opt_get(x, XAR_OPT_RSIZE); if ( opt ) { rsize = strtol(opt, NULL, 0); if ( ((rsize == LONG_MAX) || (rsize == LONG_MIN)) && (errno == ERANGE) ) { rsize = wsize; } } rbuf = malloc(rsize); if( !rbuf ) { retval = -1; close(fd); close(tocfd); goto CLOSE_BAIL; } zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; deflateInit(&zs, Z_BEST_COMPRESSION); ungztoc = gztoc = 0; while(1) { r = read(fd, rbuf, rsize); if( (r < 0) && (errno == EINTR) ) continue; if( r == 0 ) break; ungztoc += r; zs.avail_in = r; zs.next_in = (void *)rbuf; zs.next_out = NULL; zs.avail_out = 0; wsize = rsize/2; off = 0; while( zs.avail_in != 0 ) { size_t newlen = wsize * 2; if (newlen > wsize) wsize = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ wbuf = realloc(wbuf, wsize); zs.next_out = ((unsigned char *)wbuf) + off; zs.avail_out = wsize - off; ret = deflate(&zs, Z_SYNC_FLUSH); off = wsize - zs.avail_out; } wbytes = off; off = 0; do { r = write(tocfd, ((char *)wbuf)+off, wbytes-off); if( (r < 0) && (errno == EINTR) ) continue; if( r < 0 ) { xar_err_new(x); xar_err_set_string(x, "Error closing xar archive"); retval = -1; goto CLOSEEND; } if( XAR(x)->toc_hash_ctx ) xar_hash_update(XAR(x)->toc_hash_ctx, ((char*)wbuf)+off, r); off += r; gztoc += r; } while( off < wbytes ); } zs.next_in = NULL; zs.avail_in = 0; zs.next_out = wbuf; zs.avail_out = wsize; deflate(&zs, Z_FINISH); r = write(tocfd, wbuf, wsize - zs.avail_out); gztoc += r; if( XAR(x)->toc_hash_ctx ) xar_hash_update(XAR(x)->toc_hash_ctx, wbuf, r); deflateEnd(&zs); /* populate the header and write it out */ XAR(x)->header.magic = htonl(XAR_HEADER_MAGIC); XAR(x)->header.size = ntohs(sizeof(xar_header_t)); XAR(x)->header.version = ntohs(1); XAR(x)->header.toc_length_uncompressed = xar_ntoh64(ungztoc); XAR(x)->header.toc_length_compressed = xar_ntoh64(gztoc); write(XAR(x)->fd, &XAR(x)->header, sizeof(xar_header_t)); /* Copy the temp compressed toc file into the file */ lseek(tocfd, (off_t)0, SEEK_SET); while(1) { r = read(tocfd, rbuf, rsize); if( (r < 0) && (errno == EINTR) ) continue; if( r == 0 ) break; wbytes = r; off = 0; do { r = write(XAR(x)->fd, ((char *)rbuf)+off, wbytes-off); if( (r < 0) && (errno == EINTR) ) continue; if( r < 0 ) { xar_err_new(x); xar_err_set_string(x, "Error closing xar archive"); retval = -1; goto CLOSEEND; } off += r; } while( off < wbytes ); } if( XAR(x)->toc_hash_ctx ) { size_t chklen = 0; void *chkstr = xar_hash_finish(XAR(x)->toc_hash_ctx, &chklen); XAR(x)->toc_hash_ctx = NULL; write(XAR(x)->fd, chkstr, chklen); /* If there are any signatures, get the signed data a sign it */ if( XAR(x)->signatures ) { xar_signature_t sig; uint32_t signed_len = 0; uint8_t *signed_data = NULL; /* Loop through the signatures */ for(sig = XAR(x)->signatures; sig; sig = XAR_SIGNATURE(sig)->next ){ signed_len = XAR_SIGNATURE(sig)->len; /* If callback returns something other then 0, bail */ if( 0 != sig->signer_callback( sig, sig->callback_context, chkstr, chklen, &signed_data, &signed_len ) ){ fprintf(stderr, "Error signing data.\n"); free(chkstr); retval = -1; close(fd); close(tocfd); goto CLOSE_BAIL; } if( signed_len != XAR_SIGNATURE(sig)->len ){ fprintf(stderr, "Signed data not the proper length. %i should be %i.\n",signed_len,XAR_SIGNATURE(sig)->len); free(chkstr); retval = -1; close(fd); close(tocfd); goto CLOSE_BAIL; } /* Write the signed data to the heap */ write(XAR(x)->fd, signed_data,XAR_SIGNATURE(sig)->len); free(signed_data); } free(chkstr); } xar_signature_remove( XAR(x)->signatures ); XAR(x)->signatures = NULL; } /* copy the heap from the temporary heap into the archive */ if( 0 > XAR(x)->heap_to_archive(x) ) { xar_err_new(x); xar_err_set_string(x, "Error while copying heap contents into archive"); xar_err_set_errno(x, errno); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); retval = -1; close(fd); close(tocfd); goto CLOSEEND; } CLOSEEND: close(fd); close(tocfd); free(rbuf); free(wbuf); deflateEnd(&XAR(x)->zs); } else { xar_signature_remove( XAR(x)->signatures ); XAR(x)->signatures = NULL; inflateEnd(&XAR(x)->zs); } CLOSE_BAIL: /* continue deallocating the archive and return */ while(XAR(x)->subdocs) { xar_subdoc_remove(XAR(x)->subdocs); } while(XAR(x)->attrs) { a = XAR(x)->attrs; XAR(x)->attrs = XAR_ATTR(a)->next; xar_attr_free(a); } while(XAR(x)->props) { xar_prop_t p; p = XAR(x)->props; XAR(x)->props = XAR_PROP(p)->next; xar_prop_free(p); } while(XAR(x)->files) { f = XAR(x)->files; XAR(x)->files = XAR_FILE(f)->next; xar_file_free(f); } xmlHashFree(XAR(x)->ino_hash, NULL); xmlHashFree(XAR(x)->link_hash, NULL); xmlHashFree(XAR(x)->csum_hash, NULL); close(XAR(x)->fd); if( XAR(x)->heap_fd >= 0 ) close(XAR(x)->heap_fd); free((char *)XAR(x)->filename); free((char *)XAR(x)->dirname); free(XAR(x)->readbuf); free(XAR(x)->toc_hash); if (XAR(x)->toc_hash_ctx) { size_t bytes = 0; char* buffer = xar_hash_finish(XAR(x)->toc_hash_ctx, &bytes); if (buffer) { free(buffer); } } free((void *)x); return retval; } xar_header_t xar_header_get(xar_t x) { return XAR(x)->header; } /* xar_opt_get * x: archive to get the option from * option: name of the option * Returns: a pointer to the value of the option * In the case of more than one option with the same name, this will * return the first match. */ const char *xar_opt_get(xar_t x, const char *option) { xar_attr_t i; for(i = XAR(x)->attrs; i && XAR_ATTR(i)->next; i = XAR_ATTR(i)->next) { if(strcmp(XAR_ATTR(i)->key, option)==0) return XAR_ATTR(i)->value; } if( i && (strcmp(XAR_ATTR(i)->key, option)==0) ) return XAR_ATTR(i)->value; return NULL; } /* xar_opt_set * x: the archive to set the option of * option: the name of the option to set the value of * value: the value to set the option to * Returns: 0 for sucess, -1 for failure */ int32_t xar_opt_set(xar_t x, const char *option, const char *value) { xar_attr_t currentAttr, a; if( (strcmp(option, XAR_OPT_TOCCKSUM) == 0) ) { XAR(x)->heap_offset = xar_io_get_toc_checksum_length_for_type(value); } /* This was an edit from xar-1.4 Looks like we would only allow one definition for a particular key in this list But xar_opt_unset is implemented to remove many pairs for the same key // if the attribute is already defined, find it and free its value, // replace and return for(currentAttr = XAR(x)->attrs; currentAttr ; currentAttr = XAR_ATTR(currentAttr)->next) { if(strcmp(XAR_ATTR(currentAttr)->key, option)==0) { free((char*)XAR_ATTR(currentAttr)->value); XAR_ATTR(currentAttr)->value = strdup(value); return 0; } } */ // otherwise create a new attribute a = xar_attr_new(); XAR_ATTR(a)->key = strdup(option); XAR_ATTR(a)->value = strdup(value); // and prepend it to the attrs list for the archive XAR_ATTR(a)->next = XAR(x)->attrs; XAR(x)->attrs = a; return 0; } /* xar_opt_unset * x: the archive to set the option of * option: the name of the option to delete * This will delete ALL instances of the option name */ int32_t xar_opt_unset(xar_t x, const char *option) { xar_attr_t currentAttr, previousAttr = NULL; for(currentAttr = XAR(x)->attrs; currentAttr ; previousAttr = currentAttr, currentAttr = XAR_ATTR(currentAttr)->next) { if(strcmp(XAR_ATTR(currentAttr)->key, option)==0) { // if this attribute match is the head of the attrs list // promote the next list item to the head if( previousAttr == NULL ) XAR(previousAttr)->attrs = XAR_ATTR(currentAttr)->next; // otherwise splice the list around this attr else XAR_ATTR(previousAttr)->next = XAR_ATTR(currentAttr)->next; xar_attr_free(currentAttr); // keep going to find other instances currentAttr = previousAttr; } } return 0; } /* xar_add_node * x: archive the file should belong to * f: parent node, possibly NULL * name: name of the node to add * realpath: real path to item, this is used if the item being archived is to be located at a different location in the tree * then it is on the real filesystem. * Returns: newly allocated and populated node * Summary: helper function which adds a child of f and populates * its properties. If f is NULL, the node will be added as a top * level node of the archive, x. */ static xar_file_t xar_add_node(xar_t x, xar_file_t f, const char *name, const char *prefix, const char *realpath, int srcpath) { xar_file_t ret; const char *path; char *tmp; char idstr[32]; if( !f ) { if( realpath ) asprintf(&tmp, "%s", realpath); else asprintf(&tmp, "%s%s%s", XAR(x)->path_prefix, prefix, name); if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; } ret = xar_file_new(name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->parent = NULL; XAR_FILE(ret)->fspath = tmp; if( XAR(x)->files == NULL ) XAR(x)->files = ret; else { XAR_FILE(ret)->next = XAR(x)->files; XAR(x)->files = ret; } } else { path = XAR_FILE(f)->fspath; if( strcmp(prefix, "../") == 0 ) { int len1, len2; len1 = strlen(path); len2 = strlen(name); if( (len1>=len2) && (strcmp(path+(len1-len2), name) == 0) ) { return f; } } if( realpath ){ asprintf(&tmp, "%s", realpath); }else asprintf(&tmp, "%s/%s%s", path, prefix, name); if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; } ret = xar_file_new_from_parent(f, name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->fspath = tmp; } if( xar_arcmod_archive(x, ret, XAR_FILE(ret)->fspath, NULL, 0) < 0 ) { xar_file_t i = NULL; if( f ) { if( ret == XAR_FILE(f)->children ) XAR_FILE(f)->children = XAR_FILE(ret)->next; else for( i = XAR_FILE(f)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } else { if( ret == XAR(x)->files ) XAR(x)->files = XAR_FILE(ret)->next; else for( i = XAR(x)->files; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } if( i ) XAR_FILE(i)->next = XAR_FILE(ret)->next; xar_file_free(ret); return NULL; } return ret; } /* xar_add_pseudodir * Summary: Adds a placeholder directory when archiving a file prior * to archiving its path. */ static xar_file_t xar_add_pseudodir(xar_t x, xar_file_t f, const char *name, const char *prefix, const char *realpath) { xar_file_t ret; const char *path; char *tmp; char idstr[32]; if( !f ) { if( realpath ) asprintf(&tmp, "%s", realpath); else asprintf(&tmp, "%s%s%s", XAR(x)->path_prefix, prefix, name); if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; } ret = xar_file_new(name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->parent = NULL; XAR_FILE(ret)->fspath = tmp; if( XAR(x)->files == NULL ) XAR(x)->files = ret; else { XAR_FILE(ret)->next = XAR(x)->files; XAR(x)->files = ret; } } else { path = XAR_FILE(f)->fspath; if( strcmp(prefix, "../") == 0 ) { int len1, len2; len1 = strlen(path); len2 = strlen(name); if( (len1>=len2) && (strcmp(path+(len1-len2), name) == 0) ) { return f; } } if( realpath ){ asprintf(&tmp, "%s", realpath); }else asprintf(&tmp, "%s/%s%s", path, prefix, name); if( lstat(tmp, &XAR(x)->sbcache) != 0 ) { free(tmp); return NULL; } ret = xar_file_new_from_parent(f, name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->fspath = tmp; } xar_prop_set(ret, "type", "directory"); return ret; } /* xar_add_r * Summary: a recursive helper function for adding a node to the * tree. This will search all children of node f, looking for * the path component. If found, will recurse into it. If not, * will add the path component to the tree, and recurse into it. * If f is NULL, will start with x->files. */ static xar_file_t xar_add_r(xar_t x, xar_file_t f, const char *path, const char *prefix) { xar_file_t i = NULL, ret, ret2, start = NULL; char *tmp1, *tmp2, *tmp3; if( path && (path[0] == '\0') ) { return f; } tmp1 = tmp2 = strdup(path); tmp3 = strsep(&tmp2, "/"); if( tmp3 && tmp2 && (tmp3[0] == '\0') ) { ret2 = xar_add_r(x, f, tmp2, ""); free(tmp1); return ret2; } if( strcmp(tmp3, "..") == 0 ) { char *prefixstr; if( !XAR(x)->skipwarn ) { xar_err_new(x); xar_err_set_string(x, "Skipping .. in path"); xar_err_callback(x, XAR_SEVERITY_WARNING, XAR_ERR_ARCHIVE_CREATION); XAR(x)->skipwarn = 1; } asprintf(&prefixstr, "%s../", prefix); ret2 = xar_add_r(x, f, tmp2, prefixstr); free(prefixstr); free(tmp1); return ret2; } if( strcmp(tmp3, ".") == 0 ) { if( tmp2 ) ret2 = xar_add_r(x, f, tmp2, prefix); else ret2 = NULL; free(tmp1); return ret2; } if( !f ) { start = XAR(x)->files; } else { start = XAR_FILE(f)->children; } /* Search all the siblings */ for( i = start; i; i = XAR_FILE(i)->next ) { const char *n; xar_prop_get(i, "name", &n); if(n && strcmp(n, tmp3) == 0 ) { if( !tmp2 ) { /* Node already exists, and it is i */ free(tmp1); return i; } ret2 = xar_add_r(x, i, tmp2, ""); free(tmp1); return ret2; } } /* tmp3 was not found in children of start, so we add it */ if( tmp2 ) { //ret = xar_add_node(x, f, tmp3, prefix, NULL, 1); ret = xar_add_pseudodir(x, f, tmp3, prefix, NULL); } else { ret = xar_add_node(x, f, tmp3, prefix, NULL, 0); } if( !ret ) { free(tmp1); return NULL; } if( !tmp2 ) { /* We've added the final piece, done, don't recurse */ free(tmp1); return ret; } /* still more to add, recurse */ ret2 = xar_add_r(x, ret, tmp2, ""); free(tmp1); return ret2; } /* xar_add * x: archive to add the file to * path: path to file * Returns: allocated an populated xar_file_t representing the * specified file. * Summary: if a full path "foo/bar/blah" is specified, then any * directories not already existing in the archive will be added * automagically. The returned xar_file_t represents the file * specified, not the parent of the directory tree. * For instance, if "foo/bar/blah" is specified, the xar_file_t * representing "blah" will be returned. */ xar_file_t xar_add(xar_t x, const char *path) { #ifdef __APPLE__ xar_file_t ret; if( (ret = xar_underbar_check(x, NULL, path)) ) return ret; #endif if( path[0] == '/' ) { XAR(x)->path_prefix = "/"; path++; } else XAR(x)->path_prefix = ""; return xar_add_r(x, NULL, path, ""); } /* xar_add_frombuffer * x: archive to add the file to * parent: parent node, possibly NULL * name: name of file * buffer: buffer for file contents * length: length of buffer * Returns: allocated an populated xar_file_t representing the * specified file. * Summary: Use this to add chunks of named data to a xar without * using the filesystem. */ xar_file_t xar_add_frombuffer(xar_t x, xar_file_t parent, const char *name, char *buffer, size_t length) { xar_file_t ret; char idstr[32]; if( !parent ) { ret = xar_file_new(name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->parent = NULL; if( XAR(x)->files == NULL ) XAR(x)->files = ret; else { XAR_FILE(ret)->next = XAR(x)->files; XAR(x)->files = ret; } } else { ret = xar_file_new_from_parent(parent, name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->fspath = NULL; } //int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) if( xar_arcmod_archive(x, ret, NULL , buffer , length) < 0 ) { xar_file_t i; if( parent ) { for( i = XAR_FILE(parent)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } else { for( i = XAR(x)->files; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } if( i ) XAR_FILE(i)->next = XAR_FILE(ret)->next; xar_file_free(ret); return NULL; } return ret; } xar_file_t xar_add_folder(xar_t x, xar_file_t f, const char *name, struct stat *info) { xar_file_t ret; char idstr[32]; if( info ) memcpy(&XAR(x)->sbcache,info,sizeof(struct stat)); ret = xar_file_new_from_parent(f, name); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->fspath = NULL; if( !f ) { XAR_FILE(ret)->parent = NULL; if( XAR(x)->files == NULL ) XAR(x)->files = ret; else { XAR_FILE(ret)->next = XAR(x)->files; XAR(x)->files = ret; } } if( xar_arcmod_archive(x, ret, XAR_FILE(ret)->fspath, NULL, 0) < 0 ) { xar_file_t i; if( f ) { for( i = XAR_FILE(f)->children; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } else { for( i = XAR(x)->files; i && (XAR_FILE(i)->next != ret); i = XAR_FILE(i)->next ); } if( i ) XAR_FILE(i)->next = XAR_FILE(ret)->next; xar_file_free(ret); return NULL; } return ret; } xar_file_t xar_add_frompath(xar_t x, xar_file_t parent, const char *name, const char *realpath) { return xar_add_node(x, parent, name , "" , realpath, 1); } xar_file_t xar_add_from_archive(xar_t x, xar_file_t parent, const char *name, xar_t sourcearchive, xar_file_t sourcefile) { xar_file_t ret; char idstr[32]; ret = xar_file_replicate(sourcefile, parent); if( !ret ) return NULL; memset(idstr, 0, sizeof(idstr)); snprintf(idstr, sizeof(idstr)-1, "%"PRIu64, ++XAR(x)->last_fileid); xar_attr_set(ret, NULL, "id", idstr); XAR_FILE(ret)->fspath = NULL; if( !parent ) { XAR_FILE(ret)->parent = NULL; if( XAR(x)->files == NULL ) XAR(x)->files = ret; else { XAR_FILE(ret)->next = XAR(x)->files; XAR(x)->files = ret; } } xar_prop_set(ret, "name", name); /* iterate through all the properties, see if any of them have an offset */ xar_prop_t p = xar_prop_pfirst(ret); do{ xar_prop_t tmpp; tmpp = xar_prop_pget(p, "offset"); if(tmpp) { if( 0 != xar_attrcopy_from_heap_to_heap(sourcearchive, sourcefile, p, x, ret)){ xar_file_free(ret); ret = NULL; break; } } }while( (p = xar_prop_pnext(p)) ); return ret; } /* xar_extract_tofile * x: archive to extract from * f: file associated with x * Returns 0 on success, -1 on failure * Summary: This actually does the file extraction. * No traversal is performed, it is assumed all directory paths * leading up to f already exist. */ int32_t xar_extract_tofile(xar_t x, xar_file_t f, const char *path) { return xar_arcmod_extract(x, f, path,NULL, 0); } /* xar_extract_tobuffer * x: archive to extract from * buffer: buffer to extract to * Returns 0 on success, -1 on failure. * Summary: This is the entry point for extraction to a buffer. * On success, a buffer is allocated with the contents of the file * specified. The caller is responsible for freeing the returend buffer. * Example: xar_extract_tobuffer(x, "foo/bar/blah",&buffer) */ int32_t xar_extract_tobuffer(xar_t x, xar_file_t f, char **buffer) { size_t size; return xar_extract_tobuffersz(x, f, buffer, &size); } /* xar_extract_tobuffer * x: archive to extract from * buffer: buffer to extract to * size: On return, this will contain the size of the memory pointed to by buffer * Returns 0 on success, -1 on failure. * Summary: This is the entry point for extraction to a buffer. * On success, a buffer is allocated with the contents of the file * specified. The caller is responsible for freeing the returend buffer. * Example: xar_extract_tobuffer(x, "foo/bar/blah",&buffer) */ int32_t xar_extract_tobuffersz(xar_t x, xar_file_t f, char **buffer, size_t *size) { const char *sizestring = NULL; int32_t ret; if(0 != xar_prop_get_expect_notnull(f,"data/size",&sizestring)){ if(0 != xar_prop_get_expect_notnull(f, "type", &sizestring)) return -1; if(strcmp(sizestring, "file") == 0) { *size = 0; return 0; } return -1; } *size = strtoull(sizestring, (char **)NULL, 10); *buffer = malloc(*size); if(!(*buffer)){ return -1; } ret = xar_arcmod_extract(x,f,NULL,*buffer,*size); if( ret ) { *size = 0; free(*buffer); *buffer = NULL; } return ret; } int32_t xar_extract_tostream_init(xar_t x, xar_file_t f, xar_stream *stream) { xar_prop_t tmpp; if( !xar_check_prop(x, "data") ) return XAR_STREAM_OK; tmpp = xar_prop_pfirst(f); if( tmpp ) tmpp = xar_prop_find(tmpp, "data"); if( !tmpp ) return XAR_STREAM_OK; return xar_attrcopy_from_heap_to_stream_init(x, f, tmpp, stream); } int32_t xar_extract_tostream(xar_stream *stream) { return xar_attrcopy_from_heap_to_stream(stream); } int32_t xar_extract_tostream_end(xar_stream *stream) { return xar_attrcopy_from_heap_to_stream_end(stream); } /* xar_extract * x: archive to extract from * path: path to file to extract * Returns 0 on success, -1 on failure. * Summary: This is the entry point for extraction. This will find * the file node described by path, extract any directories needed * to extract the node, and finally extract the file. * Example: xar_extract(x, "foo/bar/blah") * If foo does not exist, xar_extract will extract foo from the * archive, extract bar from the archive, and then extract blah. * Total extractions will be "foo", "foo/bar", and "foo/bar/blah". */ int32_t xar_extract(xar_t x, xar_file_t f) { struct stat sb; char *tmp1, *dname; xar_file_t tmpf; uint32_t result = -1; if( (strstr(XAR_FILE(f)->fspath, "/") != NULL) && (stat(XAR_FILE(f)->fspath, &sb)) && (XAR_FILE(f)->parent_extracted == 0) ) { tmp1 = strdup(XAR_FILE(f)->fspath); dname = xar_safe_dirname(tmp1); tmpf = xar_file_find(XAR(x)->files, dname); free(dname); free(tmp1); if( !tmpf ) { xar_err_set_string(x, "Unable to find file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } XAR_FILE(f)->parent_extracted++; result = xar_extract(x, tmpf); if (result < 0) return result; } char* safe_path = xar_get_safe_path(f); if (safe_path) { result = xar_extract_tofile(x, f, safe_path); free(safe_path); } return result; } int32_t xar_verify_progress(xar_t x, xar_file_t f, xar_progress_callback p) { return xar_arcmod_verify(x,f, p); } /* xar_verify * x: archive to extract from * f: file to verify * Returns 0 on success, -1 on failure. * Summary: This function allows for verification of * an entry without extraction. If there is no checksum * the verification will pass. */ int32_t xar_verify(xar_t x, xar_file_t f) { return xar_arcmod_verify(x,f, NULL); } /* toc_read_callback * context: context passed through from the reader * buffer: buffer to read into * len: size of buffer * Returns: number of bytes read or -1 in case of error * Summary: internal callback for xmlReaderForIO. */ static int toc_read_callback(void *context, char *buffer, int len) { xar_t x = (xar_t)context; int ret, off = 0; if ( ((!XAR(x)->offset) || (XAR(x)->offset == XAR(x)->readbuf_len)) && (XAR(x)->toc_count != XAR(x)->header.toc_length_compressed) ) { XAR(x)->offset = 0; size_t read_size = 0; if( (XAR(x)->readbuf_len - off) + XAR(x)->toc_count > XAR(x)->header.toc_length_compressed ) { read_size = XAR(x)->header.toc_length_compressed - XAR(x)->toc_count; ret = xar_read_fd(XAR(x)->fd, XAR(x)->readbuf, read_size); } else { read_size = XAR(x)->readbuf_len; ret = read(XAR(x)->fd, XAR(x)->readbuf, read_size); } if ( ret == -1 || read_size != ret) return ret; if ( XAR(x)->toc_hash_ctx ) xar_hash_update(XAR(x)->toc_hash_ctx, XAR(x)->readbuf, ret); XAR(x)->toc_count += ret; off += ret; } if( off && (off < XAR(x)->readbuf_len) ) XAR(x)->readbuf_len = off; XAR(x)->zs.next_in = ((unsigned char *)XAR(x)->readbuf) + XAR(x)->offset; XAR(x)->zs.avail_in = XAR(x)->readbuf_len - XAR(x)->offset; XAR(x)->zs.next_out = (void *)buffer; XAR(x)->zs.avail_out = len; ret = inflate(&XAR(x)->zs, Z_SYNC_FLUSH); if( ret < 0 ) return -1; XAR(x)->offset = XAR(x)->readbuf_len - XAR(x)->zs.avail_in; return len - XAR(x)->zs.avail_out; } /* close_callback * context: this will be a xar_t * Returns: 0 or -1 in case of error * Summary: this is the callback for xmlTextReaderForIO to close the IO */ static int close_callback(void *context) { return 0; } /* xar_serialize * x: xar to serialize * file: file to serialize to * Summary: serializes the archive out to xml. */ void xar_serialize(xar_t x, const char *file) { xmlTextWriterPtr writer; xar_subdoc_t i; writer = xmlNewTextWriterFilename(file, 0); xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); xmlTextWriterSetIndent(writer, 4); xmlTextWriterStartElement(writer, BAD_CAST("xar")); for( i = XAR(x)->subdocs; i; i = xar_subdoc_next(i) ) xar_subdoc_serialize(i, writer, 1); xmlTextWriterStartElement(writer, BAD_CAST("toc")); if( XAR(x)->props ) xar_prop_serialize(XAR(x)->props, writer); if( XAR(x)->signatures ) xar_signature_serialize(XAR(x)->signatures,writer); if( XAR(x)->files ) xar_file_serialize(XAR(x)->files, writer); xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); return; } /* xar_unserialize * x: xar archive to unserialize to. Must have been allocated with xar_open * file: the xml filename to unserialize from * Summary: Takes the TOC representation from file and creates the * corresponding in-memory representation. */ static int32_t xar_unserialize(xar_t x) { xmlTextReaderPtr reader; xar_file_t f = NULL; const xmlChar *name, *prefix, *uri; int type, noattr, ret; reader = xmlReaderForIO(toc_read_callback, close_callback, XAR(x), NULL, NULL, 0); if( !reader ) return -1; while( (ret = xmlTextReaderRead(reader)) == 1 ) { type = xmlTextReaderNodeType(reader); noattr = xmlTextReaderAttributeCount(reader); name = xmlTextReaderConstLocalName(reader); if( type != XML_READER_TYPE_ELEMENT ) continue; if(strcmp((const char*)name, "xar") != 0) continue; while( (ret = xmlTextReaderRead(reader)) == 1 ) { type = xmlTextReaderNodeType(reader); noattr = xmlTextReaderAttributeCount(reader); name = xmlTextReaderConstLocalName(reader); if( type == XML_READER_TYPE_ELEMENT ) { if(strcmp((const char*)name, "toc") == 0) { while( (ret = xmlTextReaderRead(reader)) == 1 ) { type = xmlTextReaderNodeType(reader); noattr = xmlTextReaderAttributeCount(reader); name = xmlTextReaderConstLocalName(reader); if( type == XML_READER_TYPE_ELEMENT ) { if(strcmp((const char*)name, "file") == 0) { f = xar_file_unserialize(x, NULL, reader); if (f == NULL) { xmlFreeTextReader(reader); return -1; } XAR_FILE(f)->next = XAR(x)->files; XAR(x)->files = f; } else if( strcmp((const char*)name, "signature") == 0 #ifdef __APPLE__ || strcmp((const char*)name, "x-signature") == 0 #endif ){ xar_signature_t sig = NULL; sig = xar_signature_unserialize(x, reader ); if( !sig ) { xmlFreeTextReader(reader); return -1; } if( XAR(x)->signatures ) XAR_SIGNATURE(XAR(x)->signatures)->next = XAR_SIGNATURE(sig); else XAR(x)->signatures = sig; } else { if (xar_prop_unserialize(XAR_FILE(x), NULL, reader) != 0) { xmlFreeTextReader(reader); return -1; } } } } if( ret == -1 ) { xmlFreeTextReader(reader); return -1; } } else { xar_subdoc_t s = NULL; xar_attr_t a = NULL; int i; prefix = xmlTextReaderPrefix(reader); uri = xmlTextReaderNamespaceUri(reader); i = xmlTextReaderAttributeCount(reader); if( i > 0 ) { for(i = xmlTextReaderMoveToFirstAttribute(reader); i == 1; i = xmlTextReaderMoveToNextAttribute(reader)) { const char *aname = (const char *)xmlTextReaderConstLocalName(reader); const char *avalue = (const char *)xmlTextReaderConstValue(reader); if( aname && (strcmp("subdoc_name", aname) == 0) ) { name = (const unsigned char *)avalue; } else { xar_attr_t next = a; a = xar_attr_new(); XAR_ATTR(a)->key = strdup(aname); XAR_ATTR(a)->value = strdup(avalue); XAR_ATTR(a)->next = next; } } } s = xar_subdoc_new(x, (const char *)name); if(s){ if(a){ XAR_SUBDOC(s)->attrs = XAR_ATTR(a); } if (xar_subdoc_unserialize(s, reader) != 0){ xmlFreeTextReader(reader); return -1; } }else{ xmlFreeTextReader(reader); return -1; } } } if( (type == XML_READER_TYPE_END_ELEMENT) && (strcmp((const char *)name, "toc")==0) ) { break; } } if( ret == -1 ) { xmlFreeTextReader(reader); return -1; } } if( ret == -1 ) { xmlFreeTextReader(reader); return -1; } xmlFreeTextReader(reader); return 0; } int xar_get_archive_fd(xar_t x) { return XAR(x)->fd; } xar-xar-498/xar/lib/archive.h000066400000000000000000000106111446633275300161300ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_ARCHIVE_H_ #define _XAR_ARCHIVE_H_ #include #include #ifdef __APPLE__ #include #include #else #include #endif #include #include #include "xar.h" #include "filetree.h" #include "hash.h" typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context); typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context); struct errctx { const char *str; int saved_errno; xar_file_t file; void *usrctx; xar_t x; }; struct __xar_t { xar_prop_t props; xar_attr_t attrs; /* archive options, such as rsize */ const char *prefix; const char *ns; const char *filler1; const char *filler2; xar_file_t files; /* file forest */ const char *filename; /* name of the archive we are operating on */ char *dirname; /* directory of the archive, used in creation */ int fd; /* open file descriptor for the archive */ int heap_fd; /* fd for tmp heap archive, used in creation */ off_t heap_offset; /* current offset within the heap */ off_t heap_len; /* current length of the heap */ xar_header_t header; /* header of the xar archive */ void *readbuf; /* buffer for reading/writing compressed toc */ size_t readbuf_len; /* length of readbuf */ size_t offset; /* offset into readbuf for keeping track * between callbacks. */ size_t toc_count; /* current bytes read of the toc */ z_stream zs; /* gz state for compressing/decompressing toc */ char *path_prefix; /* used for distinguishing absolute paths */ err_handler ercallback; /* callback for errors/warnings */ struct errctx errctx; /* error callback context */ xar_subdoc_t subdocs; /* linked list of subdocs */ xar_signature_t signatures; /* linked list of signatures */ int32_t (*attrcopy_to_heap)(xar_t, xar_file_t, xar_prop_t, read_callback, void *); int32_t (*attrcopy_from_heap)(xar_t, xar_file_t, xar_prop_t, write_callback, void *); int32_t (*heap_to_archive)(xar_t); uint64_t last_fileid; /* unique fileid's in the archive */ xmlHashTablePtr ino_hash; /* Hash for looking up hardlinked files (add)*/ xmlHashTablePtr link_hash; /* Hash for looking up hardlinked files (extract)*/ xmlHashTablePtr csum_hash; /* Hash for looking up checksums of files */ xar_hash_t toc_hash_ctx; int toc_hash_size; /* size of toc hash that was copied during archive open */ void *toc_hash; /* copy of the toc hash copied during archive open */ int skipwarn; struct stat sbcache; }; #define XAR(x) ((struct __xar_t *)(x)) #endif /* _XAR_ARCHIVE_H_ */ xar-xar-498/xar/lib/arcmod.c000066400000000000000000000110511446633275300157460ustar00rootroot00000000000000/* * Copyright (c) 2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "arcmod.h" #include "archive.h" #include "stat.h" #include "data.h" #include "linuxattr.h" #include "fbsdattr.h" #include "darwinattr.h" #include "ext2.h" #include "xar.h" #include struct arcmod xar_arcmods[] = { { xar_stat_archive, xar_stat_extract }, /* must be first */ { xar_linuxattr_archive, xar_linuxattr_extract }, { xar_fbsdattr_archive, xar_fbsdattr_extract }, { xar_darwinattr_archive, xar_darwinattr_extract }, { xar_ext2attr_archive, xar_ext2attr_extract }, { xar_data_archive, xar_data_extract }, /* Add new modules here */ { NULL, xar_set_perm }, { NULL, xar_flags_extract } }; /* xar_arcmod_archive * x: archive to add the file to * f: node representing the file * file: the filesystem path to the file * Returns: 0 on success * Summary: This is the entry point to actual file archival. */ int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { int i; int32_t ret; for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { if( xar_arcmods[i].archive ) { ret = xar_arcmods[i].archive(x, f, file, buffer, len); if( ret < 0 ) { return ret; } if( ret > 0 ) { return 0; } } } return 0; } /* xar_arcmod_extract * x: archive to extract the file from * f: node representing the file * file: the filesystem path to the target file * Returns: 0 on success * Summary: This is the entry point to actual file archival. */ int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { int i; int32_t ret; for(i = 0; i < (sizeof(xar_arcmods)/sizeof(struct arcmod)); i++) { if( xar_arcmods[i].extract ) { ret = xar_arcmods[i].extract(x, f, file, buffer, len); if( ret < 0 ) { // If the extract failed we have corrupt asset on disk, remove, well try. unlink(file); return ret; } if( ret > 0 ) { return 0; } } } return 0; } int32_t xar_arcmod_verify(xar_t x, xar_file_t f, xar_progress_callback p){ return xar_data_verify(x,f, p); } /* xar_check_prop * x: xar archive * name: name of property to check * Description: If XAR_OPT_PROPINCLUDE is set at all, only properties * specified for inclusion will be added. * If XAR_OPT_PROPINCLUDE is not set, and XAR_OPT_PROPEXCLUDE is set, * properies specified by XAR_OPT_PROPEXCLUDE will be omitted. * Returns: 0 for not to include, 1 for include. */ int32_t xar_check_prop(xar_t x, const char *name) { xar_attr_t i; char includeset = 0; for(i = XAR(x)->attrs; i; i = XAR_ATTR(i)->next) { if( strcmp(XAR_ATTR(i)->key, XAR_OPT_PROPINCLUDE) == 0 ) { if( strcmp(XAR_ATTR(i)->value, name) == 0 ) return 1; includeset = 1; } } if( includeset ) return 0; for(i = XAR(x)->attrs; i; i = XAR_ATTR(i)->next) { if( strcmp(XAR_ATTR(i)->key, XAR_OPT_PROPEXCLUDE) == 0 ) { if( strcmp(XAR_ATTR(i)->value, name) == 0 ) return 0; } } return 1; } xar-xar-498/xar/lib/arcmod.h000066400000000000000000000046131446633275300157610ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_ARCMOD_H_ #define _XAR_ARCMOD_H_ #include "xar.h" #include "filetree.h" typedef int32_t (*arcmod_archive)(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); typedef int32_t (*arcmod_extract)(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); struct arcmod { arcmod_archive archive; arcmod_extract extract; }; int32_t xar_arcmod_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); int32_t xar_arcmod_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); int32_t xar_arcmod_verify(xar_t x, xar_file_t f, xar_progress_callback p); int32_t xar_check_prop(xar_t x, const char *name); #endif /* _XAR_ARCMOD_H_ */ xar-xar-498/xar/lib/asprintf.h000066400000000000000000000053121446633275300163370ustar00rootroot00000000000000//============================================================================== // // Copyright (C) 2005 Jason Evans . All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice(s), // this list of conditions and the following disclaimer unmodified other than // the allowable addition of one or more copyright notices. // // 2. Redistributions in binary form must reproduce the above copyright // notice(s), this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) `AS IS' AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN // NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //============================================================================== // // Emulate vasprintf() and asprintf(). // //============================================================================== #include #include #include static inline int vasprintf(char **rResult, const char *aFormat, va_list aAp) { int rVal; char *result; va_list ap; #define XarAsprintfStartLen 16 result = (char *) malloc(XarAsprintfStartLen); if (result == NULL) { rVal = -1; goto RETURN; } va_copy(ap, aAp); rVal = vsnprintf(result, XarAsprintfStartLen, aFormat, ap); va_end(ap); if (rVal == -1) { goto RETURN; } else if (rVal >= XarAsprintfStartLen) { free(result); result = (char *) malloc(rVal + 1); if (result == NULL) { rVal = -1; goto RETURN; } va_copy(ap, aAp); rVal = vsnprintf(result, rVal + 1, aFormat, aAp); va_end(ap); } *rResult = result; RETURN: #undef XarAsprintfStartLen return rVal; } static int asprintf(char **rResult, const char *aFormat, ...) { int rVal; va_list ap; va_start(ap, aFormat); rVal = vasprintf(rResult, aFormat, ap); va_end(ap); return rVal; } xar-xar-498/xar/lib/b64.c000066400000000000000000000176461446633275300151140ustar00rootroot00000000000000/* * Copyright (c) 2004 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 1-Oct-2004 * DRI: Rob Braun */ #include #include #ifdef _BTEST_ int main(int argc, char* argv[]) { unsigned char* enc = benc(argv[1], strlen(argv[1])); printf("%s", enc); printf("%s\n", bdec(enc, strlen(enc))); } #endif /* * The code below derives from "Secure Programming Cookbook for C and * C++"* and adapted by Kogule, Ryo (kogule@opendarwin.org). * * *John Viega and Matt Messier, O'Reilly, 2003 * http://www.secureprogramming.com/ * * Readability improvements by Luke Bellandi, 2007 (luke@apple.com) */ typedef enum _B64CommandCodes { B64_NullTerminator = -3, B64_PaddingCharacter = -2, B64_IgnorableCharacter = -1 } B64CommandCodes; static char b64revtb[256] = { -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*0-15*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16-31*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /*32-47*/ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, /*48-63*/ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /*64-79*/ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /*80-95*/ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /*96-111*/ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /*112-127*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128-143*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*144-159*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*160-175*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*176-191*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*192-207*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*208-223*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*224-239*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /*240-255*/ }; typedef enum _B64CodecErrorCodes { B64_noError = 0, B64_decodeError = 1, B64_bufferOverrun = 2 } B64CodecErrorCodes; #define B64_INPUT_BLOCK_OFFSET ((inputIndex - 1 - ignorableCharacterCount) % 4) static unsigned int raw_base64_decode( const unsigned char *input, unsigned char *output, size_t inLengthToDecode, size_t *outputDecodedLength) { int currentBase64Value; unsigned int inputIndex = 0; unsigned int ignorableCharacterCount = 0; unsigned int i; unsigned char decodedBuffer[3]; unsigned char currentInputBlockPaddingCharacterCount = 0; size_t *decodedCharacterCount; size_t dummyValue; if (outputDecodedLength == NULL) { // do this so that if caller passes in NULL for outputDecodedLength // it can still be handled easily decodedCharacterCount = &dummyValue; } else { decodedCharacterCount = outputDecodedLength; } *decodedCharacterCount = 0; while ( (inputIndex <= inLengthToDecode) && (currentInputBlockPaddingCharacterCount == 0) ) { currentBase64Value = b64revtb[input[inputIndex]]; inputIndex++; switch (currentBase64Value) { // [1] Handle control characters case B64_NullTerminator: if (B64_INPUT_BLOCK_OFFSET != 0) return B64_decodeError; // copy remaining characters with padding if (currentInputBlockPaddingCharacterCount > 0) { for (i = 0; i < (3 - currentInputBlockPaddingCharacterCount); i++) { *output++ = decodedBuffer[i]; (*decodedCharacterCount)++; } } return B64_noError; case B64_PaddingCharacter: if (B64_INPUT_BLOCK_OFFSET < 2) { /* Invalid here -- only characters 3 and/or 4 of the input block can be padding */ return B64_decodeError; } else if (B64_INPUT_BLOCK_OFFSET == 2) { /* inputIndex points to the next byte in the input buffer. If this is the last byte the inputIndex is dangling past the end of the array. If it is, then by definition = is not the next char. Just throw overrun.*/ if (inputIndex > inLengthToDecode) { return B64_bufferOverrun; } /* Make sure there's appropriate padding */ if (input[inputIndex] != '=') return B64_decodeError; decodedBuffer[2] = 0; currentInputBlockPaddingCharacterCount = 2; break; } else { currentInputBlockPaddingCharacterCount = 1; break; } return B64_noError; case B64_IgnorableCharacter: ignorableCharacterCount++; break; default: // [2] Handle encoded data switch (B64_INPUT_BLOCK_OFFSET) { case 0: decodedBuffer[0] = currentBase64Value << 2; break; case 1: decodedBuffer[0] |= (currentBase64Value >> 4); decodedBuffer[1] = currentBase64Value << 4; break; case 2: decodedBuffer[1] |= (currentBase64Value >> 2); decodedBuffer[2] = currentBase64Value << 6; break; case 3: decodedBuffer[2] |= currentBase64Value; for (i = 0; i < (3 - currentInputBlockPaddingCharacterCount); i++) { *output++ = decodedBuffer[i]; (*decodedCharacterCount)++; } break; } break; } } if (inputIndex > inLengthToDecode) { return B64_bufferOverrun; } for (i = 0; i < (3 - currentInputBlockPaddingCharacterCount); i++) { *output++ = decodedBuffer[i]; (*decodedCharacterCount)++; } return B64_noError; } unsigned char* xar_from_base64(const unsigned char* input, size_t inputLength, size_t *outputLength) { int err; unsigned char *output; // N.B.: This is a conservative estimate of space needed. It is NOT // an exact value -- the exact length of the decoded data will be // calculated during the decode operation. output = calloc(1, 3 * (inputLength / 4 + 1)); if (output == NULL) return NULL; err = raw_base64_decode(input, output, inputLength, outputLength); if (err != B64_noError) { free(output); return NULL; } return output; } xar-xar-498/xar/lib/b64.h000066400000000000000000000004401446633275300151010ustar00rootroot00000000000000/* * Rob Braun * 1-Oct-2004 * Copyright (c) 2004 Rob Braun. All rights reserved. */ #ifndef _XAR_BASE64_H_ #define _XAR_BASE64_H_ unsigned char* xar_from_base64(const unsigned char* input, size_t inputLength, size_t *outputLength); #endif /* _XAR_BASE64_H_ */ xar-xar-498/xar/lib/bzxar.c000066400000000000000000000204441446633275300156350ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include #include #include #include #include #ifdef HAVE_LIBBZ2 #include #endif #include "xar.h" #include "filetree.h" #include "io.h" #ifdef HAVE_LIBBZ2 struct _bzip_context{ uint8_t bzipcompressed; bz_stream bz; }; #define BZIP2_CONTEXT(x) ((struct _bzip_context *)(*x)) #endif int xar_bzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { #ifdef HAVE_LIBBZ2 if( !context || !BZIP2_CONTEXT(context) ) return 0; if( BZIP2_CONTEXT(context)->bzipcompressed){ BZ2_bzDecompressEnd(&BZIP2_CONTEXT(context)->bz); } /* free the context */ free(BZIP2_CONTEXT(context)); *context = NULL; #endif /* HAVE_LIBBZ2 */ return 0; } int xar_bzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { const char *opt; xar_prop_t tmpp; #ifdef HAVE_LIBBZ2 void *out = NULL; size_t outlen, offset = 0; int r; /* on first run, we init the context and check the compression type */ if( !BZIP2_CONTEXT(context) ) { *context = calloc(1,sizeof(struct _bzip_context)); opt = NULL; tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) return 0; if( strcmp(opt, "application/x-bzip2") != 0 ) return 0; BZ2_bzDecompressInit(&BZIP2_CONTEXT(context)->bz, 0, 0); BZIP2_CONTEXT(context)->bzipcompressed = 1; if( *inlen == 0 ) return 0; }else if( !(BZIP2_CONTEXT(context)->bzipcompressed) ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen; BZIP2_CONTEXT(context)->bz.next_in = *in; BZIP2_CONTEXT(context)->bz.avail_in = *inlen; BZIP2_CONTEXT(context)->bz.next_out = out; BZIP2_CONTEXT(context)->bz.avail_out = 0; while( BZIP2_CONTEXT(context)->bz.avail_in != 0 ) { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); BZIP2_CONTEXT(context)->bz.next_out = ((char *)out) + offset; BZIP2_CONTEXT(context)->bz.avail_out = outlen - offset; r = BZ2_bzDecompress(&BZIP2_CONTEXT(context)->bz); if( (r != BZ_OK) && (r != BZ_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error decompressing file"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } offset += outlen - offset - BZIP2_CONTEXT(context)->bz.avail_out; if( (r == BZ_STREAM_END) && (offset == 0) ) break; } free(*in); *in = out; *inlen = offset; #else opt = NULL; tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) return 0; if( strcmp(opt, "application/x-bzip2") != 0 ) return 0; xar_err_new(x); xar_err_set_file(x, f); xar_err_set_errno(x, 0); xar_err_set_string(x, "bzip2 support not compiled in."); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); #endif /* HAVE_LIBBZ2 */ return 0; } int xar_bzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { #ifdef HAVE_LIBBZ2 xar_prop_t tmpp; if( BZIP2_CONTEXT(context)->bzipcompressed){ BZ2_bzCompressEnd(&BZIP2_CONTEXT(context)->bz); tmpp = xar_prop_pset(f, p, "encoding", NULL); if( tmpp ) xar_attr_pset(f, tmpp, "style", "application/x-bzip2"); } /* free the context */ free(BZIP2_CONTEXT(context)); *context = NULL; #endif /* HAVE_LIBBZ2 */ return 0; } int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { const char *opt; #ifdef HAVE_LIBBZ2 void *out = NULL; size_t outlen, offset = 0; int r; /* on first run, we init the context and check the compression type */ if( !BZIP2_CONTEXT(context) ) { int level = 9; *context = calloc(1,sizeof(struct _bzip_context)); opt = xar_opt_get(x, XAR_OPT_COMPRESSION); if( !opt ) return 0; if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; opt = xar_opt_get(x, XAR_OPT_COMPRESSIONARG); if( opt ) { int tmp; errno = 0; tmp = strtol(opt, NULL, 10); if( errno == 0 ) { if( (level >= 0) && (level <= 9) ) level = tmp; } } BZ2_bzCompressInit(&BZIP2_CONTEXT(context)->bz, level, 0, 30); BZIP2_CONTEXT(context)->bzipcompressed = 1; }else if( !BZIP2_CONTEXT(context)->bzipcompressed ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen/2; if(outlen == 0) outlen = 1024; BZIP2_CONTEXT(context)->bz.next_in = *in; BZIP2_CONTEXT(context)->bz.avail_in = *inlen; BZIP2_CONTEXT(context)->bz.next_out = out; BZIP2_CONTEXT(context)->bz.avail_out = 0; if( *inlen != 0 ) { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); BZIP2_CONTEXT(context)->bz.next_out = ((char *)out) + offset; BZIP2_CONTEXT(context)->bz.avail_out = outlen - offset; r = BZ2_bzCompress(&BZIP2_CONTEXT(context)->bz, BZ_RUN); offset = outlen - BZIP2_CONTEXT(context)->bz.avail_out; } while( r == BZ_RUN_OK && BZIP2_CONTEXT(context)->bz.avail_in != 0 ); } else { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); BZIP2_CONTEXT(context)->bz.next_out = ((char *)out) + offset; BZIP2_CONTEXT(context)->bz.avail_out = outlen - offset; r = BZ2_bzCompress(&BZIP2_CONTEXT(context)->bz, BZ_FINISH); offset = outlen - BZIP2_CONTEXT(context)->bz.avail_out; } while( (r == BZ_FINISH_OK) && (r != BZ_STREAM_END /* no-op */) ); } if( (r != BZ_RUN_OK && r != BZ_STREAM_END && r != BZ_SEQUENCE_ERROR) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error compressing file"); xar_err_set_errno(x, r); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } free(*in); *in = out; *inlen = offset; #else opt = xar_opt_get(x, XAR_OPT_COMPRESSION); if( !opt ) return 0; if( strcmp(opt, XAR_OPT_VAL_BZIP) != 0 ) return 0; xar_err_new(x); xar_err_set_file(x, f); xar_err_set_errno(x, 0); xar_err_set_string(x, "bzip2 support not compiled in."); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); #endif /* HAVE_LIBBZ2 */ return 0; } xar-xar-498/xar/lib/bzxar.h000066400000000000000000000041671446633275300156460ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_BZLIB_H_ #define _XAR_BZLIB_H_ int xar_bzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_bzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); int32_t xar_bzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_bzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _XAR_BZLIB_H_ */ xar-xar-498/xar/lib/darwinattr.c000066400000000000000000000523401446633275300166660ustar00rootroot00000000000000/* * Copyright (c) 2008 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 24-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #include #include #include #include #include #include #include #include "xar.h" #include "arcmod.h" #include "b64.h" #include #include #include "util.h" #include "linuxattr.h" #include "io.h" #include "appledouble.h" #include "stat.h" #include "archive.h" #if defined(HAVE_SYS_XATTR_H) #include #endif struct _darwinattr_context{ int fd; char *finfo; char *buf; int len; int off; }; #define DARWINATTR_CONTEXT(x) ((struct _darwinattr_context *)(x)) #if defined(__APPLE__) #ifdef HAVE_GETATTRLIST #include #include struct fi { uint32_t length; fsobj_type_t objtype; char finderinfo[32]; }; /* finfo_read * This is for archiving the finderinfo via the getattrlist method. * This function is used from the nonea_archive() function. */ static int32_t finfo_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( len < 32 ) return -1; if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; memcpy(buf, DARWINATTR_CONTEXT(context)->finfo, 32); DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } /* finfo_write * This is for extracting the finderinfo via the setattrlist method. * This function is used from the nonea_extract() function. */ static int32_t finfo_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { struct attrlist attrs; struct fi finfo; if( len < 32 ) return -1; if( DARWINATTR_CONTEXT(context)->finfo == NULL ) return 0; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; getattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, &finfo, sizeof(finfo), 0); attrs.commonattr = ATTR_CMN_FNDRINFO; if( setattrlist(DARWINATTR_CONTEXT(context)->finfo, &attrs, buf, 32, 0) != 0 ) return -1; DARWINATTR_CONTEXT(context)->finfo = NULL; return 32; } #endif /* HAVE_GETATTRLIST */ /* xar_rsrc_read * This is the read callback function for archiving the resource fork via * the ..namedfork method. This callback is used from nonea_archive() */ static int32_t xar_rsrc_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; while(1) { r = read(DARWINATTR_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; return r; } } #endif /* __APPLE__ */ /* xar_rsrc_write * This is the write callback function for writing the resource fork * back to the file via ..namedfork method. This is the callback used * in nonea_extract() and underbar_extract(). */ static int32_t xar_rsrc_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; do { r = write(DARWINATTR_CONTEXT(context)->fd, ((char *)buf)+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; } while( off < len ); return off; } #ifdef __APPLE__ #if defined(HAVE_GETXATTR) static int32_t xar_ea_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, siz); free(DARWINATTR_CONTEXT(context)->buf); DARWINATTR_CONTEXT(context)->buf = NULL; DARWINATTR_CONTEXT(context)->off = 0; DARWINATTR_CONTEXT(context)->len = 0; return siz; } memcpy(buf, DARWINATTR_CONTEXT(context)->buf+DARWINATTR_CONTEXT(context)->off, len); DARWINATTR_CONTEXT(context)->off += len; if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) { free(DARWINATTR_CONTEXT(context)->buf); DARWINATTR_CONTEXT(context)->buf = NULL; DARWINATTR_CONTEXT(context)->off = 0; DARWINATTR_CONTEXT(context)->len = 0; } return len; } static int32_t xar_ea_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( DARWINATTR_CONTEXT(context)->buf == NULL ) return 0; if( DARWINATTR_CONTEXT(context)->off == DARWINATTR_CONTEXT(context)->len ) return 0; if( ((DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off)) <= len ) { int siz = (DARWINATTR_CONTEXT(context)->len)-(DARWINATTR_CONTEXT(context)->off); memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, siz); return siz; } memcpy((DARWINATTR_CONTEXT(context)->buf)+(DARWINATTR_CONTEXT(context)->off), buf, len); DARWINATTR_CONTEXT(context)->off += len; return len; } static int32_t ea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char *buf, *i; int ret, bufsz, attrsz; int32_t retval = 0; if( file == NULL ) return 0; ret = listxattr(file, NULL, 0, XATTR_NOFOLLOW); if( ret < 0 ) return -1; if( ret == 0 ) return 0; bufsz = ret; TRYAGAIN: buf = malloc(bufsz); if( !buf ) goto TRYAGAIN; ret = listxattr(file, buf, bufsz, XATTR_NOFOLLOW); if( ret < 0 ) { switch(errno) { case ERANGE: bufsz = bufsz*2; free(buf); goto TRYAGAIN; case ENOTSUP: retval = 0; goto BAIL; default: retval = -1; goto BAIL; }; } if( ret == 0 ) { retval = 0; goto BAIL; } attrsz = ret; for( i = buf; (i-buf) < attrsz; i += strlen(i)+1 ) { xar_ea_t e; ret = getxattr(file, i, NULL, 0, 0, XATTR_NOFOLLOW); if( ret < 0 ) continue; DARWINATTR_CONTEXT(context)->len = ret; DARWINATTR_CONTEXT(context)->buf = malloc(DARWINATTR_CONTEXT(context)->len); if( !DARWINATTR_CONTEXT(context)->buf ) goto BAIL; ret = getxattr(file, i, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); if( ret < 0 ) { free(DARWINATTR_CONTEXT(context)->buf); DARWINATTR_CONTEXT(context)->buf = NULL; DARWINATTR_CONTEXT(context)->len = 0; continue; } e = xar_ea_new(f, i); if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_ea_read, context) < 0) { retval = -1; goto BAIL; } } BAIL: free(buf); return retval; } static int32_t ea_extract(xar_t x, xar_file_t f, const char* file, void *context) { xar_prop_t p; for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { const char *opt; const char *name = NULL; int len; xar_prop_t tmpp; name = xar_prop_getkey(p); if( strncmp(name, XAR_EA_FORK, strlen(XAR_EA_FORK)) ) continue; if( strlen(name) != strlen(XAR_EA_FORK) ) continue; opt = NULL; tmpp = xar_prop_pget(p, "size"); if( tmpp ) opt = xar_prop_getvalue(tmpp); if( !opt ) continue; len = strtol(opt, NULL, 10); DARWINATTR_CONTEXT(context)->buf = malloc(len); if( !DARWINATTR_CONTEXT(context)->buf ) return -1; DARWINATTR_CONTEXT(context)->len = len; if (XAR(x)->attrcopy_from_heap(x, f, p, xar_ea_write, context) < 0) return -1; name = NULL; tmpp = xar_prop_pget(p, "name"); if( tmpp ) name = xar_prop_getvalue(tmpp); if( !name ) continue; setxattr(file, name, DARWINATTR_CONTEXT(context)->buf, DARWINATTR_CONTEXT(context)->len, 0, XATTR_NOFOLLOW); free(DARWINATTR_CONTEXT(context)->buf); DARWINATTR_CONTEXT(context)->buf = NULL; DARWINATTR_CONTEXT(context)->len = 0; DARWINATTR_CONTEXT(context)->off = 0; } return 0; } #endif /* HAVE_GETXATTR */ /* nonea_archive * Archive the finderinfo and resource fork through getattrlist and * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ static int32_t nonea_archive(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; struct stat sb; xar_ea_t e; #ifdef HAVE_GETATTRLIST struct attrlist attrs; struct fi finfo; int ret; char z[32]; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; ret = getattrlist(file, &attrs, &finfo, sizeof(finfo), 0); if( ret != 0 ) return -1; memset(z, 0, sizeof(z)); if( memcmp(finfo.finderinfo, z, sizeof(finfo.finderinfo)) != 0 ) { e = xar_ea_new(f, "com.apple.FinderInfo"); DARWINATTR_CONTEXT(context)->finfo = finfo.finderinfo; if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), finfo_read, context) < 0) return -1; } #endif /* HAVE_GETATTRLIST */ memset(rsrcname, 0, sizeof(rsrcname)); snprintf(rsrcname, sizeof(rsrcname)-1, "%s/..namedfork/rsrc", file); if( lstat(rsrcname, &sb) != 0 ) return 0; if( sb.st_size == 0 ) return 0; DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDONLY, 0); if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; e = xar_ea_new(f, "com.apple.ResourceFork"); if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_rsrc_read, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } close(DARWINATTR_CONTEXT(context)->fd); return 0; } /* nonea_extract * Extract the finderinfo and resource fork through setattrlist and * ..namedfork methods rather than via EAs. This is mainly for 10.3 * and earlier support */ static int32_t nonea_extract(xar_t x, xar_file_t f, const char* file, void *context) { char rsrcname[4096]; xar_prop_t p; #ifdef HAVE_SETATTRLIST struct attrlist attrs; struct fi finfo; int ret; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO; ret = getattrlist(file, &attrs, &finfo, sizeof(finfo), 0); if( ret != 0 ) return -1; DARWINATTR_CONTEXT(context)->finfo = (char *)file; p = xar_ea_find(f, "com.apple.ResourceFork"); if( p ) { if (XAR(x)->attrcopy_from_heap(x, f, p, finfo_write, context) < 0) { return -1; } } #endif /* HAVE_SETATTRLIST */ memset(rsrcname, 0, sizeof(rsrcname)); snprintf(rsrcname, sizeof(rsrcname)-1, "%s/..namedfork/rsrc", file); DARWINATTR_CONTEXT(context)->fd = open(rsrcname, O_RDWR|O_TRUNC); if( DARWINATTR_CONTEXT(context)->fd < 0 ) return 0; p = xar_ea_find(f, "com.apple.ResourceFork"); if( p ) { if (XAR(x)->attrcopy_from_heap(x, f, p, xar_rsrc_write, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } } close(DARWINATTR_CONTEXT(context)->fd); return 0; } #endif /* __APPLE__ */ /* xar_underbar_check * Check to see if the file we're archiving is a ._ file. If so, * stop the archival process. */ xar_file_t xar_underbar_check(xar_t x, xar_file_t f, const char* file, void *context) { char *bname, *tmp; tmp = strdup(file); bname = basename(tmp); if(bname && (bname[0] == '.') && (bname[1] == '_')) { char *nonunderbar, *nupath, *tmp2, *dname; struct stat sb; nonunderbar = bname+2; tmp2 = strdup(file); dname = xar_safe_dirname(tmp2); asprintf(&nupath, "%s/%s", dname, nonunderbar); free(dname); free(tmp2); /* if there is no file that the ._ corresponds to, archive * it like a normal file. */ if( stat(nupath, &sb) ) { free(tmp); free(nupath); return NULL; } asprintf(&tmp2, "%s/..namedfork/rsrc", nupath); /* If there is a file that the ._ file corresponds to, and * there is no resource fork, assume the ._ file contains * the file's resource fork, and skip it (to be picked up * when the file is archived. */ if( stat(tmp2, &sb) ) { xar_file_t tmpf; tmpf = xar_file_find(XAR(x)->files, nupath); if( !tmpf ) { tmpf = xar_add(x, nupath); } free(nupath); free(tmp2); free(tmp); return tmpf; } /* otherwise, we have a corresponding file and it supports * resource forks, so we assume this is a detached ._ file * and archive it as a real file. */ free(nupath); free(tmp2); free(tmp); return NULL; } free(tmp); return NULL; } #ifdef __APPLE__ /* This only really makes sense on OSX */ static int32_t underbar_archive(xar_t x, xar_file_t f, const char* file, void *context) { struct stat sb; char underbarname[4096], z[32]; char *dname, *bname, *tmp, *tmp2; struct AppleSingleHeader ash; struct AppleSingleEntry ase; int num_entries = 0, i, r; off_t off; if( !file ) return 0; tmp = strdup(file); tmp2 = strdup(file); dname = xar_safe_dirname(tmp2); bname = basename(tmp); memset(underbarname, 0, sizeof(underbarname)); snprintf(underbarname, sizeof(underbarname)-1, "%s/._%s", dname, bname); free(tmp); free(tmp2); free(dname); if( stat(underbarname, &sb) != 0 ) return 0; DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDONLY); if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; memset(&ash, 0, sizeof(ash)); memset(&ase, 0, sizeof(ase)); r = read(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); if( r < XAR_ASH_SIZE ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } if( ntohl(ash.magic) != APPLEDOUBLE_MAGIC ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } if( ntohl(ash.version) != APPLEDOUBLE_VERSION ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } off = XAR_ASH_SIZE; num_entries = ntohs(ash.entries); for(i = 0; i < num_entries; i++) { off_t entoff; r = read(DARWINATTR_CONTEXT(context)->fd, &ase, sizeof(ase)); if( r < sizeof(ase) ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } off+=r; if( ntohl(ase.entry_id) == AS_ID_FINDER ) { xar_ea_t e; entoff = (off_t)ntohl(ase.offset); if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } r = read(DARWINATTR_CONTEXT(context)->fd, z, sizeof(z)); if( r < sizeof(z) ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } DARWINATTR_CONTEXT(context)->finfo = z; e = xar_ea_new(f, "com.apple.FinderInfo"); if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), finfo_read, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } } if( ntohl(ase.entry_id) == AS_ID_RESOURCE ) { xar_ea_t e; entoff = (off_t)ntohl(ase.offset); if( lseek(DARWINATTR_CONTEXT(context)->fd, entoff, SEEK_SET) == -1 ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } e = xar_ea_new(f, "com.apple.ResourceFork"); if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_rsrc_read, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } if( lseek(DARWINATTR_CONTEXT(context)->fd, (off_t)off, SEEK_SET) == -1 ) { close(DARWINATTR_CONTEXT(context)->fd); return -1; } } } close(DARWINATTR_CONTEXT(context)->fd); DARWINATTR_CONTEXT(context)->fd = 0; return 0; } #endif /* underbar_extract * Extract finderinfo and resource fork information to an appledouble * ._ file. */ static int32_t underbar_extract(xar_t x, xar_file_t f, const char* file, void *context) { char underbarname[4096]; char *dname, *bname, *tmp, *tmp2; const char *rsrclenstr; struct AppleSingleHeader ash; struct AppleSingleEntry ase; int num_entries = 0, rsrclen = 0, have_rsrc = 0, have_fi = 0; xar_prop_t p; xar_prop_t rfprop = NULL, fiprop = NULL; fiprop = xar_ea_find(f, "com.apple.FinderInfo"); if( fiprop ) { have_fi = 1; num_entries++; } rfprop = xar_ea_find(f, "com.apple.ResourceFork"); if( rfprop ) { have_rsrc = 1; num_entries++; } if( num_entries == 0 ) return 0; tmp = strdup(file); tmp2 = strdup(file); dname = xar_safe_dirname(tmp2); bname = basename(tmp); memset(underbarname, 0, sizeof(underbarname)); snprintf(underbarname, sizeof(underbarname)-1, "%s/._%s", dname, bname); free(tmp); free(tmp2); free(dname); DARWINATTR_CONTEXT(context)->fd = open(underbarname, O_RDWR | O_CREAT | O_TRUNC, 0); if( DARWINATTR_CONTEXT(context)->fd < 0 ) return -1; rsrclenstr = NULL; if( rfprop ) { p = xar_prop_pget(rfprop, "size"); if( p ) rsrclenstr = xar_prop_getvalue(p); if( rsrclenstr ) rsrclen = strtol(rsrclenstr, NULL, 10); } memset(&ash, 0, sizeof(ash)); memset(&ase, 0, sizeof(ase)); ash.magic = htonl(APPLEDOUBLE_MAGIC); ash.version = htonl(APPLEDOUBLE_VERSION); ash.entries = htons(num_entries); write(DARWINATTR_CONTEXT(context)->fd, &ash, XAR_ASH_SIZE); ase.offset = htonl(XAR_ASH_SIZE + ntohs(ash.entries)*12); if( have_fi ) { ase.entry_id = htonl(AS_ID_FINDER); ase.length = htonl(32); write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_rsrc ) { ase.entry_id = htonl(AS_ID_RESOURCE); ase.offset = htonl(ntohl(ase.offset) + ntohl(ase.length)); ase.length = htonl(rsrclen); write(DARWINATTR_CONTEXT(context)->fd, &ase, 12); } if( have_fi ) { if (XAR(x)->attrcopy_from_heap(x, f, fiprop, xar_rsrc_write, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); DARWINATTR_CONTEXT(context)->fd = 0; return -1; } } if( have_rsrc ) { if (XAR(x)->attrcopy_from_heap(x, f, rfprop, xar_rsrc_write, context) < 0) { close(DARWINATTR_CONTEXT(context)->fd); DARWINATTR_CONTEXT(context)->fd = 0; return -1; } } close(DARWINATTR_CONTEXT(context)->fd); DARWINATTR_CONTEXT(context)->fd = 0; xar_set_perm(x, f, underbarname, NULL, 0 ); return 0; } #if defined(__APPLE__) static int32_t stragglers_archive(xar_t x, xar_file_t f, const char* file, void *context) { #ifdef HAVE_GETATTRLIST struct fits { uint32_t length; struct timespec ts; }; struct fits fts; struct attrlist attrs; int ret; if( !xar_check_prop(x, "FinderCreateTime") ) return 0; memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_CRTIME; ret = getattrlist(file, &attrs, &fts, sizeof(fts), 0); if( ret == 0 ) { xar_prop_t tmpp; tmpp = xar_prop_new(f, NULL); if( tmpp ) { char tmpc[128]; struct tm tm; xar_prop_setkey(tmpp, "FinderCreateTime"); xar_prop_setvalue(tmpp, NULL); memset(tmpc, 0, sizeof(tmpc)); gmtime_r(&fts.ts.tv_sec, &tm); strftime(tmpc, sizeof(tmpc), "%FT%T", &tm); xar_prop_pset(f, tmpp, "time", tmpc); memset(tmpc, 0, sizeof(tmpc)); sprintf(tmpc, "%ld", fts.ts.tv_nsec); xar_prop_pset(f, tmpp, "nanoseconds", tmpc); } } #endif return 0; } static int32_t stragglers_extract(xar_t x, xar_file_t f, const char* file, void *context) { #ifdef HAVE_GETATTRLIST const char *tmpc = NULL; struct tm tm; struct timespec ts; struct attrlist attrs; xar_prop_get(f, "FinderCreateTime/time", &tmpc); if( tmpc ) { strptime(tmpc, "%FT%T", &tm); ts.tv_sec = timegm(&tm); xar_prop_get(f, "FinderCreateTime/nanoseconds", &tmpc); if( tmpc ) { ts.tv_nsec = strtol(tmpc, NULL, 10); memset(&attrs, 0, sizeof(attrs)); attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.commonattr = ATTR_CMN_CRTIME; setattrlist(file, &attrs, &ts, sizeof(ts), 0); } } #endif return 0; } #endif /* __APPLE__ */ int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { struct _darwinattr_context context; memset(&context,0,sizeof(struct _darwinattr_context)); #if defined(__APPLE__) if( len ) return 0; stragglers_archive(x, f, file, (void *)&context); /* From here on out, props are only EA's */ if( !xar_check_prop(x, "ea") ) return 0; #if defined(HAVE_GETXATTR) if( ea_archive(x, f, file, (void *)&context) == 0 ) return 0; #endif if( nonea_archive(x, f, file, (void *)&context) == 0 ) return 0; return underbar_archive(x, f, file, (void *)&context); #endif /* __APPLE__ */ return 0; } int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { struct _darwinattr_context context; memset(&context,0,sizeof(struct _darwinattr_context)); #if defined(__APPLE__) if( len ) return 0; stragglers_extract(x, f, file, (void *)&context); #if defined(HAVE_GETXATTR) if( ea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif if( nonea_extract(x, f, file, (void *)&context) == 0 ) return 0; #endif /* __APPLE__ */ return underbar_extract(x, f, file, (void *)&context); } xar-xar-498/xar/lib/darwinattr.h000066400000000000000000000040541446633275300166720ustar00rootroot00000000000000/* * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Rob Braun * 23-Apr-2005 * Copyright (c) 2004 Rob Braun. All rights reserved. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_DARWINATTR_H_ #define _XAR_DARWINATTR_H_ xar_file_t xar_underbar_check(xar_t x, xar_file_t f, const char* file); int32_t xar_darwinattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); int32_t xar_darwinattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_DARWINATTR_H_ */ xar-xar-498/xar/lib/data.c000066400000000000000000000164011446633275300154160ustar00rootroot00000000000000/* * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #include #include "xar.h" #include "filetree.h" #include "archive.h" #include "io.h" #include "arcmod.h" #include "data.h" #ifndef O_EXLOCK #define O_EXLOCK 0 #endif int32_t xar_data_read(xar_t x, xar_file_t f, void *inbuf, size_t bsize, void *context) { int32_t r; /* read from buffer, rather then fd,if available */ if(DATA_CONTEXT(context)->length){ char *readbuf = (char *)DATA_CONTEXT(context)->buffer; size_t sizetoread = DATA_CONTEXT(context)->length - DATA_CONTEXT(context)->offset; if( !sizetoread){ return 0; } if( sizetoread > bsize ){ sizetoread = bsize; } /* dont read passed the end of the buffer */ if((DATA_CONTEXT(context)->offset + sizetoread) > DATA_CONTEXT(context)->length){ return -1; //sizetoread = (DATA_CONTEXT(context)->offset + sizetoread) - DATA_CONTEXT(context)->length; } readbuf += DATA_CONTEXT(context)->offset; memcpy(inbuf,readbuf,sizetoread); DATA_CONTEXT(context)->total += sizetoread; DATA_CONTEXT(context)->offset += sizetoread; return sizetoread; } while(1) { r = read(DATA_CONTEXT(context)->fd, inbuf, bsize); if( (r < 0) && (errno == EINTR) ) continue; DATA_CONTEXT(context)->total += r; return r; } } int32_t xar_data_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { int32_t r; size_t off = 0; /* read from buffer, rather then fd,if available */ if(DATA_CONTEXT(context)->length){ char *writebuf = (char *)DATA_CONTEXT(context)->buffer; /* dont write passed the end of the buffer */ if((DATA_CONTEXT(context)->offset + len) > DATA_CONTEXT(context)->length){ return -1; } writebuf += DATA_CONTEXT(context)->offset; memcpy(writebuf,buf,len); DATA_CONTEXT(context)->offset += len; return len; } do { r = write(DATA_CONTEXT(context)->fd, ((char *)buf)+off, len-off); if( (r < 0) && (errno != EINTR) ) return r; off += r; } while( off < len ); return off; } /* xar_data_archive * This is the arcmod archival entry point for archiving the file's * data into the heap file. */ int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { const char *opt; int32_t retval = 0; struct _data_context context; xar_prop_t tmpp; memset(&context,0,sizeof(struct _data_context)); if( !xar_check_prop(x, "data") ) return 0; xar_prop_get(f, "type", &opt); if(!opt) return 0; if( strcmp(opt, "file") != 0 ) { if( strcmp(opt, "hardlink") == 0 ) { opt = xar_attr_get(f, "type", "link"); if( !opt ) return 0; if( strcmp(opt, "original") != 0 ) return 0; /* else, we're an original hardlink, so keep going */ } else return 0; } if( 0 == len ){ context.fd = open(file, O_RDONLY); if( context.fd < 0 ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "io: Could not open file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } }else{ context.buffer = (void *)buffer; context.length = len; context.offset = 0; } #ifdef F_NOCACHE fcntl(context.fd, F_NOCACHE, 1); #endif tmpp = xar_prop_pset(f, NULL, "data", NULL); retval = XAR(x)->attrcopy_to_heap(x, f, tmpp, xar_data_read,(void *)(&context)); if( context.total == 0 ) xar_prop_unset(f, "data"); if(context.fd > 0){ close(context.fd); context.fd = -1; } return retval; } int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; int32_t retval = 0; struct _data_context context; xar_prop_t tmpp; memset(&context,0,sizeof(struct _data_context)); /* Only regular files are copied in and out of the heap here */ xar_prop_get(f, "type", &opt); if( !opt ) return 0; if( strcmp(opt, "file") != 0 ) { if( strcmp(opt, "hardlink") == 0 ) { opt = xar_attr_get(f, "type", "link"); if( !opt ) return 0; if( strcmp(opt, "original") != 0 ) return 0; /* else, we're an original hardlink, so keep going */ } else return 0; } if ( len ){ context.length = len; context.buffer = buffer; context.offset = 0; }else{ /* mode 600 since other modules may need to operate on the file * prior to the real permissions being set. */ context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600); if( context.fd < 0 ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "io: Could not create file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } } tmpp = xar_prop_pfirst(f); if( tmpp ) tmpp = xar_prop_find(tmpp, "data"); if( !tmpp ) { close(context.fd); return 0; } retval = XAR(x)->attrcopy_from_heap(x, f, tmpp, xar_data_write, (void *)(&context)); if( context.fd > 0 ){ close(context.fd); context.fd = -1; } return retval; } int32_t xar_data_verify(xar_t x, xar_file_t f, xar_progress_callback p) { const char *opt; struct _data_context context; xar_prop_t tmpp; memset(&context,0,sizeof(struct _data_context)); context.progress = p; /* Only regular files are copied in and out of the heap here */ xar_prop_get(f, "type", &opt); if( !opt ) return 0; if( strcmp(opt, "directory") == 0 ) { return 0; } tmpp = xar_prop_pfirst(f); if( tmpp ) tmpp = xar_prop_find(tmpp, "data"); if (!tmpp) // It appears that xar can have truely empty files, aka, no data. We should just fail to verify these files. return 0; // After all, the checksum of blank is meaningless. So, failing to do so will cause a crash. return XAR(x)->attrcopy_from_heap(x, f, tmpp, NULL , (void *)(&context)); } xar-xar-498/xar/lib/data.h000066400000000000000000000043321446633275300154230ustar00rootroot00000000000000/* * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Rob Braun * 21-Apr-2004 * Copyright (c) 2004 Rob Braun. All rights reserved. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_DATA_H_ #define _XAR_DATA_H_ struct _data_context{ xar_progress_callback progress; int fd; void *buffer; size_t length; off_t offset; off_t total; }; #define DATA_CONTEXT(x) ((struct _data_context*)(x)) int32_t xar_data_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); int32_t xar_data_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); int32_t xar_data_verify(xar_t x, xar_file_t f, xar_progress_callback p); #endif /* _XAR_DATA_H_ */ xar-xar-498/xar/lib/ea.c000066400000000000000000000067761446633275300151100ustar00rootroot00000000000000/* * Copyright (c) 2008 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include #include #include #include #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "filetree.h" #include "archive.h" #include "b64.h" #include "ea.h" struct __xar_ea_t { const struct __xar_prop_t *prop; const struct __xar_ea_t *next; }; #define XAR_EA(x) ((struct __xar_ea_t *)(x)) xar_ea_t xar_ea_new(xar_file_t f, const char *name) { xar_ea_t ret; ret = calloc(sizeof(struct __xar_ea_t), 1); if( !ret ) return NULL; XAR_EA(ret)->prop = xar_prop_new(f, NULL); if( !XAR_EA(ret)->prop ) { free(ret); return NULL; } xar_prop_setkey(XAR_EA(ret)->prop, "ea"); xar_prop_setvalue(XAR_EA(ret)->prop, NULL); XAR_PROP(XAR_EA(ret)->prop)->attrs = xar_attr_new(); XAR_ATTR(XAR_PROP(XAR_EA(ret)->prop)->attrs)->key = strdup("id"); asprintf((char **)&XAR_ATTR(XAR_PROP(XAR_EA(ret)->prop)->attrs)->value, "%lld", XAR_FILE(f)->nexteaid++); xar_prop_pset(f, XAR_EA(ret)->prop, "name", name); return ret; } int32_t xar_ea_pset(xar_file_t f, xar_ea_t e, const char *key, const char *value){ if( xar_prop_pset(f, XAR_EA(e)->prop, key, value) ) return 0; return -1; } int32_t xar_ea_pget(xar_ea_t e, const char *key, const char **value) { xar_prop_t r = xar_prop_find(XAR_EA(e)->prop, key); if( !r ) { if( value ) *value = NULL; return -1; } if(value) *value = XAR_PROP(r)->value; return 0; } xar_prop_t xar_ea_root(xar_ea_t e) { return XAR_EA(e)->prop; } xar_prop_t xar_ea_find(xar_file_t f, const char *name) { xar_prop_t p; for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { const char *tmp; xar_prop_t tmpp; tmp = xar_prop_getkey(p); if( strncmp(tmp, XAR_EA_FORK, strlen(XAR_EA_FORK)) != 0 ) continue; if( strlen(tmp) != strlen(XAR_EA_FORK) ) continue; tmpp = xar_prop_pget(p, "name"); if( !tmpp ) continue; tmp = xar_prop_getvalue(tmpp); if( !tmp ) continue; if( strcmp(tmp, name) == 0 ) return p; } return NULL; } xar-xar-498/xar/lib/ea.h000066400000000000000000000006701446633275300151000ustar00rootroot00000000000000#ifndef _XAR_EA_H_ #define _XAR_EA_H_ #include "xar.h" #include "filetree.h" typedef struct __xar_ea_t *xar_ea_t; xar_ea_t xar_ea_new(xar_file_t f, const char *name); int32_t xar_ea_pset(xar_file_t f, xar_ea_t e, const char *key, const char *value); int32_t xar_ea_pget(xar_ea_t e, const char *key, const char **value); xar_prop_t xar_ea_root(xar_ea_t e); xar_prop_t xar_ea_find(xar_file_t f, const char *name); #endif /* _XAR_EA_H_ */ xar-xar-498/xar/lib/err.c000066400000000000000000000060601446633275300152750ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ #include #include #include #include "xar.h" #include "archive.h" #define ECTX(x) ((struct errctx *)(x)) void xar_register_errhandler(xar_t x, err_handler callback, void *usrctx) { ECTX(&XAR(x)->errctx)->x = x; ECTX(&XAR(x)->errctx)->usrctx = usrctx; XAR(x)->ercallback = callback; return; } xar_t xar_err_get_archive(xar_errctx_t ctx) { return ECTX(ctx)->x; } xar_file_t xar_err_get_file(xar_errctx_t ctx) { return ECTX(ctx)->file; } void xar_err_set_file(xar_t x, xar_file_t f) { XAR(x)->errctx.file = f; return; } const char *xar_err_get_string(xar_errctx_t ctx) { return ECTX(ctx)->str; } void xar_err_set_string(xar_t x, const char *str) { XAR(x)->errctx.str = strdup(str); // this leaks right now, but it's safer than the alternative return; } void xar_err_set_formatted_string(xar_t x, const char *format, ...) { va_list arg; char *msg; va_start(arg, format); vasprintf(&msg, format, arg); va_end(arg); xar_err_set_string(x, msg); free(msg); } int xar_err_get_errno(xar_errctx_t ctx) { return ECTX(ctx)->saved_errno; } void xar_err_set_errno(xar_t x, int e) { XAR(x)->errctx.saved_errno = e; return; } void xar_err_new(xar_t x) { memset(&XAR(x)->errctx, 0, sizeof(struct errctx)); XAR(x)->errctx.saved_errno = errno; return; } int32_t xar_err_callback(xar_t x, int32_t sev, int32_t err) { if( XAR(x)->ercallback ) return XAR(x)->ercallback(sev, err, &XAR(x)->errctx, ECTX(&XAR(x)->errctx)->usrctx); return 0; } xar-xar-498/xar/lib/ext2.c000066400000000000000000000166721446633275300154010ustar00rootroot00000000000000/* * Copyright (c) 2004 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 26-Oct-2004 * DRI: Rob Braun * Ported from xar-unsaxy 16-Apr-2005 */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include #include #include "xar.h" #include "arcmod.h" #include #include #include #include #include #include "ext2.h" #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else #if defined(HAVE_LINUX_EXT2_FS_H) typedef uint32_t u32; typedef uint8_t u8; #include #endif #endif #define XAR_EXT2_FORK "ext2" #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) static void x_addprop(xar_file_t f, const char *name) { char opt[1024]; memset(opt, 0, sizeof(opt)); snprintf(opt, sizeof(opt)-1, "%s/%s", XAR_ATTR_FORK, name); xar_prop_set(f, opt, NULL); xar_attr_set(f, opt, "fstype", "ext2"); return; } #endif int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { int ret = 0; /* if archiving from a buffer, then there is no place to get extattr */ if ( len ) return 0; #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) int fd, flags=0, version; char *vstr; const char *opt; xar_prop_get(f, "type", &opt); if(!opt) return 0; if( strcmp(opt, "file") != 0 ) { if( strcmp(opt, "hardlink") != 0 ) if( strcmp(opt, "directory") != 0 ) return 0; } fd = open(file, O_RDONLY); if( fd < 0 ) { return 0; } if( ioctl(fd, EXT2_IOC_GETVERSION, &version) < 0 ) { ret = 0; goto BAIL; } if( ioctl(fd, EXT2_IOC_GETFLAGS, &flags) < 0 ) { ret = 0; goto BAIL; } if( flags == 0 ) goto BAIL; xar_prop_set(f, XAR_EXT2_FORK, NULL); asprintf(&vstr, "%d", version); xar_attr_set(f, XAR_EXT2_FORK, "version", vstr); free(vstr); if(! (flags & ~EXT2_SECRM_FL) ) x_addprop(f, "SecureDeletion"); if(! (flags & ~EXT2_UNRM_FL) ) x_addprop(f, "Undelete"); if(! (flags & ~EXT2_COMPR_FL) ) x_addprop(f, "Compress"); if(! (flags & ~EXT2_SYNC_FL) ) x_addprop(f, "Synchronous"); if(! (flags & ~EXT2_IMMUTABLE_FL) ) x_addprop(f, "Immutable"); if(! (flags & ~EXT2_APPEND_FL) ) x_addprop(f, "AppendOnly"); if(! (flags & ~EXT2_NODUMP_FL) ) x_addprop(f, "NoDump"); if(! (flags & ~EXT2_NOATIME_FL) ) x_addprop(f, "NoAtime"); if(! (flags & ~EXT2_DIRTY_FL) ) x_addprop(f, "CompDirty"); if(! (flags & ~EXT2_COMPRBLK_FL) ) x_addprop(f, "CompBlock"); #ifdef EXT2_NOCOMPR_FL if(! (flags & ~EXT2_NOCOMPR_FL) ) x_addprop(f, "NoCompBlock"); #endif if(! (flags & ~EXT2_ECOMPR_FL) ) x_addprop(f, "CompError"); if(! (flags & ~EXT2_BTREE_FL) ) x_addprop(f, "BTree"); if(! (flags & ~EXT2_INDEX_FL) ) x_addprop(f, "HashIndexed"); if(! (flags & ~EXT2_IMAGIC_FL) ) x_addprop(f, "iMagic"); #ifdef EXT3_JOURNAL_DATA_FL if(! (flags & ~EXT3_JOURNAL_DATA_FL) ) x_addprop(f, "Journaled"); #endif if(! (flags & ~EXT2_NOTAIL_FL) ) x_addprop(f, "NoTail"); if(! (flags & ~EXT2_DIRSYNC_FL) ) x_addprop(f, "DirSync"); if(! (flags & ~EXT2_TOPDIR_FL) ) x_addprop(f, "TopDir"); if(! (flags & ~EXT2_RESERVED_FL) ) x_addprop(f, "Reserved"); BAIL: close(fd); #endif return ret; } #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) static int32_t e2prop_get(xar_file_t f, const char *name, char **value) { char v[1024]; memset(v, 0, sizeof(v)); snprintf(v, sizeof(v)-1, "%s/%s", XAR_ATTR_FORK, name); return xar_prop_get(f, v, (const char**)value); } #endif int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { /* if extracting to a buffer, then there is no place to write extattr */ if ( len ) return 0; #if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H) int fd = -1, version, flags = 0; char *tmp; if( xar_prop_get(f, XAR_EXT2_FORK, NULL) == 0 ) { const char *temp; temp = xar_attr_get(f, XAR_EXT2_FORK, "version"); version = strtol(temp, NULL, 10); fd = open(file, O_RDONLY); if( fd < 0 ) return 0; ioctl(fd, EXT2_IOC_SETVERSION, &version); } if( xar_prop_get(f, XAR_ATTR_FORK, NULL) ) { if( fd >= 0 ) close(fd); return 0; } if( e2prop_get(f, "SecureDeletion", (char **)&tmp) == 0 ) flags |= EXT2_SECRM_FL; if( e2prop_get(f, "Undelete", (char **)&tmp) == 0 ) flags |= EXT2_UNRM_FL ; if( e2prop_get(f, "Compress", (char **)&tmp) == 0 ) flags |= EXT2_COMPR_FL ; if( e2prop_get(f, "Synchronous", (char **)&tmp) == 0 ) flags |= EXT2_SYNC_FL ; if( e2prop_get(f, "SystemImmutable", (char **)&tmp) == 0 ) flags |= EXT2_IMMUTABLE_FL ; if( e2prop_get(f, "AppendOnly", (char **)&tmp) == 0 ) flags |= EXT2_APPEND_FL ; if( e2prop_get(f, "NoDump", (char **)&tmp) == 0 ) flags |= EXT2_NODUMP_FL ; if( e2prop_get(f, "NoAtime", (char **)&tmp) == 0 ) flags |= EXT2_NOATIME_FL ; if( e2prop_get(f, "CompDirty", (char **)&tmp) == 0 ) flags |= EXT2_DIRTY_FL ; if( e2prop_get(f, "CompBlock", (char **)&tmp) == 0 ) flags |= EXT2_COMPRBLK_FL ; #ifdef EXT2_NOCOMPR_FL if( e2prop_get(f, "NoCompBlock", (char **)&tmp) == 0 ) flags |= EXT2_NOCOMPR_FL ; #endif if( e2prop_get(f, "CompError", (char **)&tmp) == 0 ) flags |= EXT2_ECOMPR_FL ; if( e2prop_get(f, "BTree", (char **)&tmp) == 0 ) flags |= EXT2_BTREE_FL ; if( e2prop_get(f, "HashIndexed", (char **)&tmp) == 0 ) flags |= EXT2_INDEX_FL ; if( e2prop_get(f, "iMagic", (char **)&tmp) == 0 ) flags |= EXT2_IMAGIC_FL ; #ifdef EXT3_JOURNAL_DATA_FL if( e2prop_get(f, "Journaled", (char **)&tmp) == 0 ) flags |= EXT3_JOURNAL_DATA_FL ; #endif if( e2prop_get(f, "NoTail", (char **)&tmp) == 0 ) flags |= EXT2_NOTAIL_FL ; if( e2prop_get(f, "DirSync", (char **)&tmp) == 0 ) flags |= EXT2_DIRSYNC_FL ; if( e2prop_get(f, "TopDir", (char **)&tmp) == 0 ) flags |= EXT2_TOPDIR_FL ; if( fd < 0 ) { fd = open(file, O_RDONLY); if( fd < 0 ) return 0; } ioctl(fd, EXT2_IOC_SETFLAGS, &flags); close(fd); #endif return 0; } xar-xar-498/xar/lib/ext2.h000066400000000000000000000037441446633275300154020ustar00rootroot00000000000000/* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Rob Braun * 26-Oct-2004 * Copyright (c) 2004 Rob Braun. All rights reserved. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_EXT2_H_ #define _XAR_EXT2_H_ #define XAR_ATTR_FORK "attribute" int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_EXT2_H_ */ xar-xar-498/xar/lib/fbsdattr.c000066400000000000000000000233321446633275300163170ustar00rootroot00000000000000/* * Copyright (c) 2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 28-Oct-2004 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #include #include "xar.h" #include "arcmod.h" #include "b64.h" #include "io.h" #include "archive.h" #include #include #include /* FreeBSD Extended Attribute Headers */ #ifdef HAVE_SYS_EXTATTR_H #include #endif #ifdef HAVE_LIBUTIL_H #include #endif #ifdef HAVE_SYS_EXTATTR_H #include #include #include #endif #ifdef HAVE_SYS_EXTATTR_H struct _fbsdattr_context{ const char *file; const char *attrname; void *buf; int off; int bufsz; int ns; }; #define FBSDATTR_CONTEXT(x) ((struct _fbsdattr_context *)(x)) int32_t xar_fbsdattr_read(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { if( !FBSDATTR_CONTEXT(context)->buf ) { FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attrname, NULL, 0); if( FBSDATTR_CONTEXT(context)->bufsz < 0 ) return -1; FBSDATTR_CONTEXT(context)->buf = malloc(FBSDATTR_CONTEXT(context)->bufsz); if( !FBSDATTR_CONTEXT(context)->buf ) return -1; FBSDATTR_CONTEXT(context)->bufsz = extattr_get_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attrname, FBSDATTR_CONTEXT(context)->buf, FBSDATTR_CONTEXT(context)->bufsz); } if( (FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off) <= len ) { int32_t ret; ret = FBSDATTR_CONTEXT(context)->bufsz - FBSDATTR_CONTEXT(context)->off; memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, ret); FBSDATTR_CONTEXT(context)->off += ret; return(ret); } else { memcpy(buf, FBSDATTR_CONTEXT(context)->buf+FBSDATTR_CONTEXT(context)->off, len); FBSDATTR_CONTEXT(context)->buf += len; return(len); } } int32_t xar_fbsdattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { return extattr_set_link(FBSDATTR_CONTEXT(context)->file, FBSDATTR_CONTEXT(context)->ns, FBSDATTR_CONTEXT(context)->attrname, buf, len); } #endif int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { #ifdef HAVE_SYS_EXTATTR_H char *buf = NULL; int ret, retval=0, bufsz, i; #if defined(HAVE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) struct statvfs sfs; #else struct statfs sfs; #endif char *fsname = NULL; int namespace = EXTATTR_NAMESPACE_USER; struct _fbsdattr_context context; memset(&context,0,sizeof(struct _fbsdattr_context)); /* no fbsdattr attributes for data to a buffer */ if(len) return 0; if(file == NULL) return 0; if( !xar_check_prop(x, "ea") ) return 0; TRYAGAIN: /* extattr_list_link()'s man page does not define the return * value. The kernel source comments say 0 for success, -1 for * failure. However, the observed behavior is # of bytes * used, 0 if none, -1 on error. * Also, errno is not documented to be set to anything useful * if buf is too small. We are using an undocumented "feature" * that if the data argument is NULL, it will return the number * of bytes that would have been written (beware, return value * does not indicate success or failure on it's own. Need to * check the return value *and* the parameters. */ ret = extattr_list_link(file, namespace, NULL, 0); if( ret < 0 ) { if( namespace == EXTATTR_NAMESPACE_USER ) { namespace = EXTATTR_NAMESPACE_SYSTEM; goto TRYAGAIN; } else { /* If we get eperm on system namespace, don't * return error. This is expected for normal * users trying to archive the system namespace * on freebsd 6.2. On netbsd 3.1, they've decided * to return EOPNOTSUPP instead. */ if( errno == EPERM ) ret = 0; else if( errno == EOPNOTSUPP ) ret = 0; else { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error archiving EA"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); ret = 0; } goto BAIL; } } bufsz = ret; buf = malloc(bufsz); if( !buf ) { retval = -1; goto BAIL; } memset(buf, 0, bufsz); ret = extattr_list_link(file, namespace, buf, bufsz); if( ret < 0 ) { switch(errno) { case ENOTSUP: retval=0; goto BAIL; default: retval=-1; goto BAIL; }; } /* Even though 0 is a documented success, observed behavior * indicates 0 means all perms were satisfied, etc, but * no extattrs were found to list. */ if( ret == 0 ) { if( namespace == EXTATTR_NAMESPACE_USER ) { namespace = EXTATTR_NAMESPACE_SYSTEM; goto TRYAGAIN; } else { /* If we get eperm on system namespace, don't * return error. This is expected for normal * users trying to archive the system namespace * on freebsd 6.2. On netbsd 3.1, they've decided * to return EOPNOTSUPP instead. */ if( errno == EPERM ) ret = 0; else if( errno == EOPNOTSUPP ) ret = 0; else { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error archiving EA"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); ret = 0; } goto BAIL; } } #if defined(HAVE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) statvfs(file, &sfs); #else statfs(file, &sfs); #endif fsname = sfs.f_fstypename; /* extattr_list_link() does not return the series of keys NUL * separated, as documented in the man page. Instead, it * returns things DNS style, with a 1 byte length followed by * the key, repeated for as many keys as there are. */ for( i=0; i < ret; i++ ) { char key[256]; char *ns; char tempnam[1024]; xar_ea_t e; memset(key, 0, sizeof(key)); memcpy(key, buf+i+1, buf[i]); i += buf[i] ; extattr_namespace_to_string(namespace, &ns); memset(tempnam, 0, sizeof(tempnam)); snprintf(tempnam, sizeof(tempnam)-1, "%s.%s", ns, key); FBSDATTR_CONTEXT(&context)->ns = namespace; FBSDATTR_CONTEXT(&context)->file = file; FBSDATTR_CONTEXT(&context)->attrname = key; e = xar_ea_new(f, tempnam); xar_ea_pset(f, e, "fstype", fsname); if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_fbsdattr_read, &context) < 0) { ret = -1; goto BAIL; } free(FBSDATTR_CONTEXT(&context)->buf); FBSDATTR_CONTEXT(&context)->buf = NULL; FBSDATTR_CONTEXT(&context)->off = 0; } if( namespace == EXTATTR_NAMESPACE_USER ) { namespace = EXTATTR_NAMESPACE_SYSTEM; free(buf); buf = NULL; goto TRYAGAIN; } BAIL: free(buf); return ret; #else return 0; #endif } int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #ifdef HAVE_SYS_EXTATTR_H char *fsname = "bogus"; xar_prop_t p; #if defined(HAVE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) struct statvfs sfs; #else struct statfs sfs; #endif int eaopt = 0; struct _fbsdattr_context context; memset(&context,0,sizeof(struct _fbsdattr_context)); /* no fbsdattr attributes for data to a buffer */ if(len){ return 0; } #if defined(HAVE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) statvfs(file, &sfs); #else statfs(file, &sfs); #endif fsname = sfs.f_fstypename; for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { const char *fs = NULL; const char *prop; const char *eaname = NULL; xar_prop_t tmpp; prop = xar_prop_getkey(p); if( strncmp(prop, XAR_EA_FORK, strlen(XAR_EA_FORK) != 0 ) ) continue; if( strlen(prop) != strlen(XAR_EA_FORK) ) continue; tmpp = xar_prop_pget(p, "fstype"); if( tmpp ) fs = xar_prop_getvalue(tmpp); if( !eaopt && fs && strcmp(fs, fsname) != 0 ) { continue; } tmpp = xar_prop_pget(p, "name"); if( tmpp ) eaname = xar_prop_getvalue(tmpp); if( !eaname ) continue; if( strncmp(eaname, "user.", 5) == 0 ) { FBSDATTR_CONTEXT(&context)->ns = EXTATTR_NAMESPACE_USER; FBSDATTR_CONTEXT(&context)->attrname = eaname + 5; } else if( strncmp(eaname, "system.", 7) == 0 ) { FBSDATTR_CONTEXT(&context)->ns = EXTATTR_NAMESPACE_SYSTEM; FBSDATTR_CONTEXT(&context)->attrname = eaname + 7; } else { continue; } FBSDATTR_CONTEXT(&context)->file = file; if (XAR(x)->attrcopy_from_heap(x, f, p, xar_fbsdattr_write, &context) < 0) return -1; } #endif return 0; } xar-xar-498/xar/lib/fbsdattr.h000066400000000000000000000037261446633275300163310ustar00rootroot00000000000000/* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Rob Braun * 26-Oct-2004 * Copyright (c) 2004 Rob Braun. All rights reserved. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_FBSDATTR_H_ #define _XAR_FBSDATTR_H_ int32_t xar_fbsdattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); int32_t xar_fbsdattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_FBSDATTR_H_ */ xar-xar-498/xar/lib/filetree.c000066400000000000000000001237561446633275300163200ustar00rootroot00000000000000/* * Copyright (c) 2005-2008 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include "config.h" #include #include #include #include #include #include #include #include #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "filetree.h" #include "archive.h" #include "util.h" #include "b64.h" #include "ea.h" /* xar_attr_prop * Returns: a newly allocated and initialized property attribute. * It is the caller's responsibility to associate the attribute * with either a file or a property. */ xar_attr_t xar_attr_new(void) { xar_attr_t ret; ret = malloc(sizeof(struct __xar_attr_t)); if(!ret) return NULL; XAR_ATTR(ret)->key = NULL; XAR_ATTR(ret)->value = NULL; XAR_ATTR(ret)->next = NULL; XAR_ATTR(ret)->ns = NULL; return ret; } int32_t xar_attr_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value) { xar_attr_t a, i; if( !p ) { a = XAR_FILE(f)->attrs; } else { a = XAR_PROP(p)->attrs; } if( !a ) { a = xar_attr_new(); if(!p) XAR_FILE(f)->attrs = a; else XAR_PROP(p)->attrs = a; XAR_ATTR(a)->key = strdup(key); XAR_ATTR(a)->value = strdup(value); return 0; } for(i = a; i && XAR_ATTR(i)->next; i = XAR_ATTR(i)->next) { if(strcmp(XAR_ATTR(i)->key, key)==0) { free((char*)XAR_ATTR(i)->value); XAR_ATTR(i)->value = strdup(value); return 0; } } a = xar_attr_new(); if(!p) { XAR_ATTR(a)->next = XAR_ATTR(XAR_FILE(f)->attrs); XAR_FILE(f)->attrs = a; } else { XAR_ATTR(a)->next = XAR_ATTR(XAR_PROP(p)->attrs); XAR_PROP(p)->attrs = a; } XAR_ATTR(a)->key = strdup(key); XAR_ATTR(a)->value = strdup(value); return 0; } /* xar_attr_set * f: the file the attribute is associated with * prop: The property key the attribute is associated with. This can * be NULL to signify the attribute should be set for the file, * rather than the property. * key: The name of the attribute to set. * value: The value of the attribute. * Returns: 0 on success, -1 on failure. * Summary: Basically, sets an attribute. The only tricky part is * it can set an attribute on a property or a file. */ int32_t xar_attr_set(xar_file_t f, const char *prop, const char *key, const char *value) { if( !prop ) { return xar_attr_pset(f, NULL, key, value); } else { xar_prop_t p = NULL; p = xar_prop_find(XAR_FILE(f)->props, prop); if( !p ) return -1; return xar_attr_pset(f, p, key, value); } } const char *xar_attr_pget(xar_file_t f, xar_prop_t p, const char *key) { xar_attr_t a, i; if( !p ) a = XAR_FILE(f)->attrs; else a = XAR_PROP(p)->attrs; if( !a ) return NULL; for(i = a; i && XAR_ATTR(i)->next; i = XAR_ATTR(i)->next) { if(strcmp(XAR_ATTR(i)->key, key)==0) { return XAR_ATTR(i)->value; } } if( i && (strcmp(XAR_ATTR(i)->key, key)==0)) return XAR_ATTR(i)->value; return NULL; } /* xar_attr_get * f: file to find the associated attribute in * prop: name of the property the attribute is of. May be NULL to specify * the file's attributes. * key: name of the attribute to search for. * Returns: a reference to the value of the attribute. */ const char *xar_attr_get(xar_file_t f, const char *prop, const char *key) { if( !prop ) return xar_attr_pget(f, NULL, key); else { xar_prop_t p = NULL; p = xar_prop_find(XAR_FILE(f)->props, prop); if( !p ) return NULL; return xar_attr_pget(f, p, key); } } int xar_attr_equals_attr(xar_attr_t a1, xar_attr_t a2) { return xar_attr_equals_attr_ignoring_keys(a1, a2, 0, NULL); } int xar_attr_equals_attr_ignoring_keys(xar_attr_t a1, xar_attr_t a2, uint64_t key_count, char** keys_to_ignore) { int result = 0; xar_attr_t iter1 = a1; xar_attr_t iter2 = a2; if (a1 == a2) { // These are pointers, if they're the same pointer, well, duh, they're the same. Short cut. result = 1; goto exit; } while (iter1 && iter2) { size_t key1_size = 0, key2_size = 0; size_t value1_size = 0, value2_size = 0; size_t ns1_size = 0, ns2_size = 0; int do_case_insenstive = (strcmp(iter1->key, "name") == 0) ? 1 : 0; int ignore_compare = 0; // Check the key key1_size = iter1->key ? strlen(iter1->key) : 0; key2_size = iter2->key ? strlen(iter2->key) : 0; if ((key1_size != key2_size) || (strncmp(iter1->key, iter2->key, key1_size) != 0)) { goto exit; } for (uint64_t index = 0; index < key_count; ++index) { size_t ignore_key_size = strlen(keys_to_ignore[index]); if (ignore_key_size == key1_size && strncmp(iter1->key, keys_to_ignore[index], ignore_key_size) == 0) { ignore_compare = 1; break; } } // If we're not ignoring the compare. if (!ignore_compare) { // Check the value vlaue value1_size = iter1->value ? strlen(iter1->value) : 0; value2_size = iter2->value ? strlen(iter2->value) : 0; if (!do_case_insenstive) { if ((value1_size != value2_size) || (strncmp(iter1->value, iter2->value, value1_size) != 0)) { goto exit; } } else { if ((value1_size != value2_size) || (strncasecmp(iter1->value, iter2->value, value1_size) != 0)) { goto exit; } } // Check prefix paths ns1_size = iter1->ns ? strlen(iter1->ns) : 0; ns2_size = iter2->ns ? strlen(iter2->ns) : 0; if ((ns1_size != ns2_size) || (strncasecmp(iter1->ns, iter2->ns, ns1_size) != 0)) { goto exit; } } iter1 = iter1->next; iter2 = iter2->next; } // Incomplete iteration is not a match. if (iter1 || iter2) { goto exit; } result = 1; exit: return result; } /* xar_attr_free * a: attribute to free * Summary: frees the attribute structure and everything inside it. * It is the caller's responsibility to ensure the linked list gets * updated. This will *not* do anything to ensure the consistency * of the attribute linked list. */ void xar_attr_free(xar_attr_t a) { if(!a) return; free((char*)XAR_ATTR(a)->key); free((char*)XAR_ATTR(a)->value); free(XAR_ATTR(a)); return; } /* xar_attr_first * f: file to associate the iterator with * prop: the name of the property within the file to associate the iterator with * i: an iterator as returned by xar_iter_new * Returns: a pointer to the value of the first attribute associated with the * property 'prop' associated with the file 'f' * Summary: This MUST be called prior to calling xar_attr_next, * to iterate over the attributes of property key 'prop'. */ const char *xar_attr_first(xar_file_t f, const char *prop, xar_iter_t i) { xar_prop_t p = NULL; xar_attr_t a; if( !prop ) a = XAR_FILE(f)->attrs; else { p = xar_prop_find(XAR_FILE(f)->props, prop); if( !p ) return NULL; a = XAR_PROP(p)->attrs; } if( !a ) return NULL; XAR_ITER(i)->iter = a; free(XAR_ITER(i)->node); XAR_ITER(i)->node = strdup(XAR_ATTR(a)->key); return XAR_ITER(i)->node; } /* xar_attr_next * i: iterator allocated by xar_iter_new, and initialized with xar_attr_first * Returns: a pointer to the key of the next attribute associated with * the iterator. NULL will be returned when there are no more attributes * to find. */ const char *xar_attr_next(xar_iter_t i) { xar_attr_t a = XAR_ITER(i)->iter; if( XAR_ATTR(a)->next == NULL ) return NULL; XAR_ITER(i)->iter = XAR_ATTR(a)->next; free(XAR_ITER(i)->node); XAR_ITER(i)->node = strdup(XAR_ATTR(XAR_ITER(i)->iter)->key); return XAR_ITER(i)->node; } /* xar_iter_new * Returns a newly allocated iterator for use on files, properties, or * attributes. */ xar_iter_t xar_iter_new(void) { xar_iter_t ret = malloc(sizeof(struct __xar_iter_t)); if(!ret) return NULL; XAR_ITER(ret)->iter = NULL; XAR_ITER(ret)->path = NULL; XAR_ITER(ret)->node = NULL; XAR_ITER(ret)->nochild = 0; return ret; } /* xar_iter_free * Frees memory associated with the specified iterator */ void xar_iter_free(xar_iter_t i) { free(XAR_ITER(i)->node); if( XAR_ITER(i)->path ) free(XAR_ITER(i)->path); free(XAR_ITER(i)); } const char *xar_prop_getkey(xar_prop_t p) { return XAR_PROP(p)->key; } const char *xar_prop_getvalue(xar_prop_t p) { return XAR_PROP(p)->value; } int32_t xar_prop_setkey(xar_prop_t p, const char *key) { free((char *)XAR_PROP(p)->key); if(key) XAR_PROP(p)->key = strdup(key); return 0; } int32_t xar_prop_setvalue(xar_prop_t p, const char *value) { free((char *)XAR_PROP(p)->value); if(value) XAR_PROP(p)->value = strdup(value); return 0; } /* xar_prop_pfirst * f: file to retrieve the first property from * Returns: a xar_prop_t corresponding to the first xar_prop_t associated with f * NULL if there are no properties associated with the file. */ xar_prop_t xar_prop_pfirst(xar_file_t f) { return XAR_FILE(f)->props; } /* xar_prop_pnext * p: previous property used to retrieve the next * Returns: a xar_prop_t if there is a next, NULL otherwise */ xar_prop_t xar_prop_pnext(xar_prop_t p) { return XAR_PROP(p)->next; } /* xar_prop_first * f: file to associate the iterator with * i: an iterator as returned by xar_iter_new * Returns: a pointer to the value of the first property associated with * the file 'f'. * Summary: This MUST be called first prior to calling xar_prop_next, * to iterate over properties of file 'f'. This has the side effect of * associating the iterator with the file's properties, which is needed * before xar_prop_next. */ const char *xar_prop_first(xar_file_t f, xar_iter_t i) { XAR_ITER(i)->iter = XAR_FILE(f)->props; free(XAR_ITER(i)->node); XAR_ITER(i)->node = strdup(XAR_PROP(XAR_ITER(i)->iter)->key); return XAR_ITER(i)->node; } /* xar_prop_next * i: iterator allocated by xar_iter_new, and initialized with xar_prop_first * Returns: a pointer to the value of the next property associated with * the iterator. NULL will be returned when there are no more properties * to find. If a property has a NULL value, the string "" will be returned. * This will recurse down child properties, flattening the namespace and * adding separators. For instance a1->b1->c1, a1 will first be returned, * the subsequent call will return "a1/b1", and the next call will return * "a1/b1/c1", etc. */ const char *xar_prop_next(xar_iter_t i) { xar_prop_t p = XAR_ITER(i)->iter; if( !(XAR_ITER(i)->nochild) && XAR_PROP(p)->children ) { char *tmp = XAR_ITER(i)->path; if( tmp ) { asprintf(&XAR_ITER(i)->path, "%s/%s", tmp, XAR_PROP(p)->key); free(tmp); } else XAR_ITER(i)->path = strdup(XAR_PROP(p)->key); XAR_ITER(i)->iter = p = XAR_PROP(p)->children; goto SUCCESS; } XAR_ITER(i)->nochild = 0; if( XAR_PROP(p)->next ) { XAR_ITER(i)->iter = p = XAR_PROP(p)->next; goto SUCCESS; } if( XAR_PROP(p)->parent ) { char *tmp1, *tmp2; if( strstr(XAR_ITER(i)->path, "/") ) { tmp1 = tmp2 = XAR_ITER(i)->path; XAR_ITER(i)->path = xar_safe_dirname(tmp2); free(tmp1); } else { free(XAR_ITER(i)->path); XAR_ITER(i)->path = NULL; } XAR_ITER(i)->iter = p = XAR_PROP(p)->parent; XAR_ITER(i)->nochild = 1; return xar_prop_next(i); } return NULL; SUCCESS: free(XAR_ITER(i)->node); if( XAR_ITER(i)->path ) asprintf((char **)&XAR_ITER(i)->node, "%s/%s", XAR_ITER(i)->path, XAR_PROP(p)->key); else { if(XAR_PROP(p)->key == NULL) XAR_ITER(i)->node = strdup(""); else XAR_ITER(i)->node = strdup(XAR_PROP(p)->key); } return XAR_ITER(i)->node; } /* xar_prop_new * f: file to associate the new file with. May not be NULL * parent: the parent property of the new property. May be NULL * Returns: a newly allocated and initialized property. * Summary: in addition to allocating the new property, it * will be inserted into the parent node's list of children, * and/or added to the file's list of properties, as appropriate. */ xar_prop_t xar_prop_new(xar_file_t f, xar_prop_t parent) { xar_prop_t p; p = malloc(sizeof(struct __xar_prop_t)); if( !p ) return NULL; XAR_PROP(p)->key = NULL; XAR_PROP(p)->value = NULL; XAR_PROP(p)->children = NULL; XAR_PROP(p)->next = NULL; XAR_PROP(p)->attrs = NULL; XAR_PROP(p)->parent = parent; XAR_PROP(p)->file = f; if (XAR_FILE(f)->prefix) { XAR_PROP(p)->prefix = strdup(XAR_FILE(f)->prefix); } else { XAR_PROP(p)->prefix = NULL; } XAR_PROP(p)->ns = NULL; if(parent) { if( !XAR_PROP(parent)->children ) { XAR_PROP(parent)->children = p; } else { XAR_PROP(p)->next = XAR_PROP(parent)->children; XAR_PROP(parent)->children = p; } } else { if( XAR_FILE(f)->props == NULL ) { XAR_FILE(f)->props = p; } else { XAR_PROP(p)->next = XAR_FILE(f)->props; XAR_FILE(f)->props = p; } } return p; } /* xar_prop_find * p: property to check * key: name of property to find. * Returns: reference to the property with the specified key * Summary: A node's name may be specified by a path, such as * "a1/b1/c1", and child nodes will be searched for each * "/" separator. */ xar_prop_t xar_prop_find(xar_prop_t p, const char *key) { xar_prop_t i, ret; char *tmp1, *tmp2, *tmp3; if( !p ) return NULL; tmp2 = tmp1 = strdup(key); tmp3 = strsep(&tmp2, "/"); i = p; do { if( strcmp(tmp3, XAR_PROP(i)->key) == 0 ) { if( tmp2 == NULL ) { free(tmp1); return i; } ret = xar_prop_find(XAR_PROP(i)->children, tmp2); free(tmp1); return ret; } i = XAR_PROP(i)->next; } while(i); free(tmp1); return NULL; } /* xar_prop_set_r * p: property to recurse down and set the property of * key: key of the property to set * value: desired value of the property * Returns: 0 on sucess, -1 on failure. * Summary: This is an internal helper function for xar_prop_set() which * does the recursion down the property tree. */ static xar_prop_t xar_prop_set_r(xar_file_t f, xar_prop_t p, const char *key, const char *value, int overwrite) { xar_prop_t i, ret, ret2, start; char *tmp1, *tmp2, *tmp3; tmp2 = tmp1 = strdup(key); tmp3 = strsep(&tmp2, "/"); if( !p ) { start = XAR_FILE(f)->props; } else { start = XAR_PROP(p)->children; } for( i = start; i; i = XAR_PROP(i)->next ) { if( strcmp(tmp3, XAR_PROP(i)->key) == 0 ) { if( !tmp2 ) { if( overwrite ) { xar_prop_setvalue(i, value); free(tmp1); return i; } else { ret = xar_prop_new(f, p); if( !ret ) { free(tmp1); return ret; } xar_prop_setvalue(ret, value); xar_prop_setkey(ret, tmp3); free(tmp1); return ret; } } ret2 = xar_prop_set_r(f, i, tmp2, value, overwrite); free(tmp1); return ret2; } } ret = xar_prop_new(f, p); if( !ret ) { free(tmp1); return ret; } if( !tmp2 ) { xar_prop_setvalue(ret, value); xar_prop_setkey(ret, tmp3); free(tmp1); return ret; } xar_prop_setkey(ret, tmp3); xar_prop_setvalue(ret, NULL); ret2 = xar_prop_set_r(f, ret, tmp2, value, overwrite); free(tmp1); return ret2; } /* xar_prop_set * f: file to set the property on * key: key of the property to set * value: desired value of the property * Returns: 0 on success, -1 on failure * Summary: If the property already exists, its value is overwritten * by 'value'. If the property does not exist, it is created. * Copies of key and value are kept in the tree. The caller may do * what they wish with these values after the call returns. * References to these copies will be returned by iterating over * the properties, or by calling xar_prop_get(). * These copies will be released when the property is released. * * Note that you *CANNOT* have a node with a value and children. * This implementation will let you, but the serialization to xml * will not be what you're hoping for. */ int32_t xar_prop_set(xar_file_t f, const char *key, const char *value) { if( xar_prop_set_r(f, NULL, key, value, 1) ) return 0; return -1; } /* xar_prop_pset * Same as xar_prop_set, except it takes a xar_prop_t which will be * treated as the root property. * Returns a xar_prop_t that was created or set. Returns NULL if error. */ xar_prop_t xar_prop_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value) { return xar_prop_set_r(f, p, key, value, 1); } /* xar_prop_create * Identical to xar_prop_set, except it will not overwrite an existing * property, it will create another one. */ int32_t xar_prop_create(xar_file_t f, const char *key, const char *value) { if( xar_prop_set_r(f, NULL, key, value, 0) ) return 0; return -1; } /* xar_prop_get * f: file to look for the property in * key: name of property to find. * value: on return, *value will point to the value of the property * value may be NULL, in which case, only the existence of the property * is tested. * Returns: 0 for success, -1 on failure * Summary: A node's name may be specified by a path, such as * "a1/b1/c1", and child nodes will be searched for each * "/" separator. */ int32_t xar_prop_get(xar_file_t f, const char *key, const char **value) { xar_prop_t r = xar_prop_find(XAR_FILE(f)->props, key); if( !r ) { if(value) *value = NULL; return -1; } if(value) *value = XAR_PROP(r)->value; return 0; } int32_t xar_prop_get_expect_notnull(xar_file_t f, const char *key, const char **value) { int result = xar_prop_get(f, key, value); // If we succeeded and the value is being returned and it's NULL. FAIL if (result == 0 && value && (*value == NULL)) { return -1; } return result; } xar_prop_t xar_prop_pget(xar_prop_t p, const char *key) { char *tmp; const char *k; xar_prop_t ret; k = XAR_PROP(p)->key; asprintf(&tmp, "%s/%s", k, key); ret = xar_prop_find(p, tmp); free(tmp); return ret; } /* xar_prop_replicate_r * f: file to attach property * p: property (list) to iterate and add * parent: parent property * Summary: Recursivley adds property list (p) to file (f) and parent (parent). */ void xar_prop_replicate_r(xar_file_t f, xar_prop_t p, xar_prop_t parent ) { xar_prop_t property = p; /* look through properties */ for( property = p; property; property = property->next ){ xar_prop_t newprop = xar_prop_new( f, parent ); /* copy the key value for the property */ XAR_PROP(newprop)->key = strdup(property->key); if(property->value) XAR_PROP(newprop)->value = strdup(property->value); /* loop through the attributes and copy them */ xar_attr_t a = NULL; xar_attr_t last = NULL; /* copy attributes for file */ for(a = property->attrs; a; a = a->next) { if( NULL == newprop->attrs ){ last = xar_attr_new(); XAR_PROP(newprop)->attrs = last; }else{ XAR_ATTR(last)->next = xar_attr_new(); last = XAR_ATTR(last)->next; } XAR_ATTR(last)->key = strdup(a->key); if(a->value) XAR_ATTR(last)->value = strdup(a->value); } /* loop through the children properties and recursively add them */ xar_prop_replicate_r(f, property->children, newprop ); } } /* * xar_file_equals_file * f1: a xar_file_t to compare to f2. * f2: a xar_file_t to compare to f1 * Returns 1 if f1 is the same as f2. */ int xar_file_equals_file(xar_file_t f1, xar_file_t f2) { int result = 0; const char *f1_name = NULL, *f2_name = NULL; size_t f1_name_size = 0, f2_name_size = 0; size_t prefix1_size = 0, prefix2_size = 0; size_t fspath1_size = 0, fspath2_size = 0; size_t ns1_size = 0, ns2_size = 0; const struct __xar_file_t * child1 = NULL, * child2 = NULL; const uint keys_to_ignore_count = 1; char * keys_to_ignore[keys_to_ignore_count] = { "id" }; // ID is allowed ot mismatch // If the two pointers match, call it the same. if (f1 == f2) { result = 1; goto exit; } // Check filename - this will get done in the prop equalizer, but it's a HUGE short circuit. xar_prop_get(f1, "name", &f1_name); xar_prop_get(f2, "name", &f2_name); f1_name_size = f1_name ? strlen(f1_name) : 0; f2_name_size = f2_name ? strlen(f2_name) : 0; if ((f1_name_size != f2_name_size) || (strncasecmp(f1_name, f2_name, f1_name_size) != 0)) { goto exit; } // Check prefix paths prefix1_size = f1->prefix ? strlen(f1->prefix) : 0; prefix2_size = f2->prefix ? strlen(f2->prefix) : 0; if ((prefix1_size != prefix2_size) || (strncasecmp(f1->prefix, f2->prefix, prefix1_size) != 0)) { goto exit; } // Check where we think they should go. fspath1_size = f1->fspath ? strlen(f1->fspath) : 0; fspath2_size = f2->fspath ? strlen(f2->fspath) : 0; if ((fspath1_size != fspath2_size) || (strncasecmp(f1->fspath, f2->fspath, fspath1_size) != 0)) { goto exit; } // Call prop compare if (xar_prop_equals_prop(f1->props, f2->props) != 0) { goto exit; } // Call compare attr if (xar_attr_equals_attr_ignoring_keys(f1->attrs, f2->attrs, keys_to_ignore_count, keys_to_ignore) == 0) { goto exit; } // Check namespace ns1_size = f1->ns ? strlen(f1->ns) : 0; ns2_size = f2->ns ? strlen(f2->ns) : 0; if ((ns1_size != ns2_size) || strncasecmp(f1->ns, f2->ns, ns1_size) != 0) { goto exit; } // Compare children. // If you were dumb enough to do this. I'm going to assume your FS enumerates the directory in the same order // I am NOT going to attempt to deal with children being out of order. child1 = f1->children; child2 = f2->children; while (child1 && child2) { if (xar_file_equals_file(child1, child2) != 0) { goto exit; } child1 = child1->next; child2 = child2->next; } // Incomplete iteration of children, that means they don't match, one is longer than the other. if (child1 || child2) { goto exit; } result = 1; exit: return result; } /* xar_prop_free * p: property to free * Summary: frees the specified property and all its children. * Stored copies of the key and value will be released, as will * all attributes. */ void xar_prop_free(xar_prop_t p) { xar_prop_t i; xar_attr_t a; while( XAR_PROP(p)->children ) { i = XAR_PROP(p)->children; XAR_PROP(p)->children = XAR_PROP(i)->next; xar_prop_free(i); } while(XAR_PROP(p)->attrs) { a = XAR_PROP(p)->attrs; XAR_PROP(p)->attrs = XAR_ATTR(a)->next; xar_attr_free(a); } if (XAR_PROP(p)->key) { free((char*)XAR_PROP(p)->key); } if (XAR_PROP(p)->value) { free((char*)XAR_PROP(p)->value); } if (XAR_PROP(p)->prefix) { free((char*)XAR_PROP(p)->prefix); } free(XAR_PROP(p)); } void xar_prop_punset(xar_file_t f, xar_prop_t p) { xar_prop_t i; if( !p ) { return; } if( XAR_PROP(p)->parent ) { i = XAR_PROP(p)->parent->children; if( i == p ) { XAR_PROP(XAR_PROP(p)->parent)->children = XAR_PROP(p)->next; xar_prop_free(p); return; } } else { i = XAR_FILE(f)->props; if( i == p ) { XAR_FILE(f)->props = XAR_PROP(p)->next; xar_prop_free(p); return; } } while( i && (XAR_PROP(i)->next != XAR_PROP(p)) ) { i = XAR_PROP(i)->next; } if( i && (XAR_PROP(i)->next == XAR_PROP(p)) ) { XAR_PROP(i)->next = XAR_PROP(p)->next; xar_prop_free(p); } return; } void xar_prop_unset(xar_file_t f, const char *key) { xar_prop_t r = xar_prop_find(XAR_FILE(f)->props, key); xar_prop_punset(f, r); return; } int xar_prop_equals_prop(xar_prop_t prop1, xar_prop_t prop2) { int result = 0; xar_prop_t iter1 = prop1; xar_prop_t iter2 = prop2; while (iter1 && iter2) { size_t key1_size = 0, key2_size = 0; size_t value1_size = 0, value2_size = 0; size_t prefix1_size = 0, prefix2_size = 0; size_t ns1_size = 0, ns2_size = 0; int do_case_insenstive = (strcmp(iter1->key, "name") == 0) ? 1 : 0; // Check the key key1_size = iter1->key ? strlen(iter1->key) : 0; key2_size = iter2->key ? strlen(iter2->key) : 0; if ((key1_size != key2_size) || (strncmp(iter1->key, iter2->key, key1_size) != 0)) { goto exit; } // Check the value vlaue value1_size = iter1->value ? strlen(iter1->value) : 0; value2_size = iter2->value ? strlen(iter2->value) : 0; if (!do_case_insenstive) { if ((value1_size != value2_size) || (strncmp(iter1->value, iter2->value, value1_size) != 0)) { goto exit; } } else { if ((value1_size != value2_size) || (strncasecmp(iter1->value, iter2->value, value1_size) != 0)) { goto exit; } } // Check prefix paths prefix1_size = iter1->prefix ? strlen(iter1->prefix) : 0; prefix2_size = iter2->prefix ? strlen(iter2->prefix) : 0; if ((prefix1_size != prefix2_size) || (strncasecmp(iter1->prefix, iter2->prefix, prefix1_size) != 0)) { goto exit; } // Check prefix paths ns1_size = iter1->ns ? strlen(iter1->ns) : 0; ns2_size = iter2->ns ? strlen(iter2->ns) : 0; if ((ns1_size != ns2_size) || (strncasecmp(iter1->ns, iter2->ns, ns1_size) != 0)) { goto exit; } // Check our attr. if (xar_attr_equals_attr(iter1->attrs, iter2->attrs)) { goto exit; } // Checkout children if (xar_prop_equals_prop(iter1->children, iter2->children) == 0) { goto exit; } iter1 = iter1->next; iter2 = iter2->next; } // Incompelete iteration, fail. if (iter1 || iter2) { goto exit; } result = 1; exit: return result; } int xar_file_name_cmp(xar_file_t f, const char *name) { int result = -1; char *lower_name = xar_lowercase_string(name); if (lower_name) { const char *cur_name = NULL; xar_prop_get(f, "name", &cur_name); if (cur_name) { char *lower_cur_name = xar_lowercase_string(cur_name); if (lower_cur_name) { result = strcmp(lower_name, lower_cur_name); free(lower_cur_name); } free(lower_name); } } return result; } /* xar_file_new * f: parent file of the file to be created. May be NULL * Returns: a newly allocated file structure. */ xar_file_t xar_file_new_from_parent(xar_file_t parent, const char *name) { xar_file_t ret; ret = calloc(1, sizeof(struct __xar_file_t)); if(!ret) return NULL; XAR_FILE(ret)->parent = parent; XAR_FILE(ret)->next = NULL; XAR_FILE(ret)->children = NULL; XAR_FILE(ret)->props = NULL; XAR_FILE(ret)->attrs = NULL; XAR_FILE(ret)->prefix = NULL; XAR_FILE(ret)->ns = NULL; XAR_FILE(ret)->fspath = NULL; XAR_FILE(ret)->eas = NULL; XAR_FILE(ret)->nexteaid = 0; // Add the name if (name) { xar_prop_set(ret, "name", name); } if( parent ) { if( !XAR_FILE(parent)->children ) { XAR_FILE(parent)->children = ret; } else { // i = current, p = previous xar_file_t i, p = NULL; // Iterate and set i to the end of the list, so we can insert our new file. for (i = XAR_FILE(parent)->children; i != NULL; p = i, i = XAR_FILE(i)->next) { // This code detects if we're about insert a duplicated name // A duplicated name is a case insensitive name that matches something already in the list // If a duplicate is found we remove the old node and its children. if (xar_file_name_cmp(i, name) == 0) { if (p) { // Pull it out by having i's next become p's next. XAR_FILE(p)->next = XAR_FILE(i)->next; xar_file_free(i); i = XAR_FILE(p); // Set i back to previous, it'll become (i = i->next) before the next for-loop iteration } else { // There is no previous node, we're first in the list // This means our new file is the root children node for the parent. // After becoming the root children node, we stitch i's next to be our // new file's next. XAR_FILE(parent)->children = ret; XAR_FILE(ret)->next = i->next; xar_file_free(i); return ret; } } } // The previous file we looked at is the last file in the list. // So let's add our new file at the end. XAR_FILE(p)->next = ret; } } return ret; } xar_file_t xar_file_new(const char *name) { return xar_file_new_from_parent(NULL, name); } xar_file_t xar_file_replicate(xar_file_t original, xar_file_t newparent) { const char *file_name = NULL; xar_prop_get(original, "name", &file_name); xar_file_t ret = xar_file_new_from_parent(newparent, file_name); xar_attr_t a; /* copy attributes for file */ for(a = XAR_FILE(original)->attrs; a; a = XAR_ATTR(a)->next) { /* skip the id attribute */ if( 0 == strcmp(a->key, "id" ) ) continue; xar_attr_set(ret, NULL , a->key, a->value ); } /* recursively copy properties */ xar_prop_replicate_r(ret, XAR_FILE(original)->props, NULL); return ret; } /* xar_file_free * f: file to free * Summary: frees the specified file and all children, * properties, and attributes associated with the file. */ void xar_file_free(xar_file_t f) { xar_file_t i; xar_prop_t n; xar_attr_t a; while(XAR_FILE(f)->children) { i = XAR_FILE(f)->children; XAR_FILE(f)->children = XAR_FILE(i)->next; xar_file_free(i); } while(XAR_FILE(f)->props) { n = XAR_FILE(f)->props; XAR_FILE(f)->props = XAR_PROP(n)->next; xar_prop_free(n); } while(XAR_FILE(f)->attrs) { a = XAR_FILE(f)->attrs; XAR_FILE(f)->attrs = XAR_ATTR(a)->next; xar_attr_free(a); } XAR_FILE(f)->next = NULL; if (XAR_FILE(f)->prefix) { free((char *)XAR_FILE(f)->prefix); } free((char *)XAR_FILE(f)->fspath); free(XAR_FILE(f)); } /* xar_file_first * x: archive to associate the iterator with * i: an iterator as returned by xar_iter_new * Returns: a pointer to the name of the first file associated with * the archive 'x'. * Summary: This MUST be called first prior to calling xar_file_next, * to iterate over files of archive 'x'. This has the side effect of * associating the iterator with the archive's files, which is needed * before xar_file_next. */ xar_file_t xar_file_first(xar_t x, xar_iter_t i) { XAR_ITER(i)->iter = XAR(x)->files; free(XAR_ITER(i)->node); return XAR_ITER(i)->iter; } /* xar_file_next * i: iterator allocated by xar_iter_new, and initialized with xar_file_first * Returns: a pointer to the name of the next file associated with * the iterator. NULL will be returned when there are no more files * to find. * This will recurse down child files (directories), flattening the * namespace and adding separators. For instance a1->b1->c1, a1 will * first be returned, the subsequent call will return "a1/b1", and the * next call will return "a1/b1/c1", etc. */ xar_file_t xar_file_next(xar_iter_t i) { xar_file_t f = XAR_ITER(i)->iter; const char *name; if( !(XAR_ITER(i)->nochild) && XAR_FILE(f)->children ) { char *tmp = XAR_ITER(i)->path; xar_prop_get(f, "name", &name); if( tmp ) { asprintf(&XAR_ITER(i)->path, "%s/%s", tmp, name); free(tmp); } else XAR_ITER(i)->path = strdup(name); XAR_ITER(i)->iter = f = XAR_FILE(f)->children; goto FSUCCESS; } XAR_ITER(i)->nochild = 0; if( XAR_FILE(f)->next ) { XAR_ITER(i)->iter = f = XAR_FILE(f)->next; goto FSUCCESS; } if( XAR_FILE(f)->parent ) { char *tmp1, *tmp2; if( strstr(XAR_ITER(i)->path, "/") ) { tmp1 = tmp2 = XAR_ITER(i)->path; XAR_ITER(i)->path = xar_safe_dirname(tmp2); free(tmp1); } else { free(XAR_ITER(i)->path); XAR_ITER(i)->path = NULL; } XAR_ITER(i)->iter = f = XAR_FILE(f)->parent; XAR_ITER(i)->nochild = 1; return xar_file_next(i); } return NULL; FSUCCESS: xar_prop_get(f, "name", &name); XAR_ITER(i)->iter = (void *)f; return XAR_ITER(i)->iter; } /* xar_file_find * f: file subtree to look under * path: path to file to find * Returns the file_t describing the file, or NULL if not found. */ xar_file_t xar_file_find(xar_file_t f, const char *path) { xar_file_t i, ret; char *tmp1, *tmp2, *tmp3; if( !f ) return NULL; tmp2 = tmp1 = strdup(path); tmp3 = strsep(&tmp2, "/"); i = f; do { const char *name; xar_prop_get(i, "name", &name); if( name == NULL ) continue; if( strcmp(tmp3, name) == 0 ) { if( tmp2 == NULL ) { free(tmp1); return i; } ret = xar_file_find(XAR_FILE(i)->children, tmp2); free(tmp1); return ret; } i = XAR_FILE(i)->next; } while(i); free(tmp1); return NULL; } int xar_prop_serializable(xar_prop_t p) { if( !p ) return -1; xar_prop_t i = p; do { // Verify that the filename is valid and not unsafe. // If it's unsafe we'll skip serializing this prop. if( XAR_PROP(i)->value ) { if( strcmp(XAR_PROP(i)->key, "name") == 0 ) { const char* unsafe_value = XAR_PROP(i)->value; char* value = NULL; if (xar_is_safe_filename(unsafe_value, &value) < 0) { fprintf(stderr, "xar_prop_serializable failed because %s is not a valid filename.\n", unsafe_value); free(value); return -1; } free(value); } } i = XAR_PROP(i)->next; } while(i); return 0; } /* xar_prop_serialize * p: property to serialize * writer: the xmlTextWriterPtr allocated by xmlNewTextWriter*() * Summary: recursively serializes the property passed to it, including * children, siblings, attributes, etc. */ void xar_prop_serialize(xar_prop_t p, xmlTextWriterPtr writer) { xar_prop_t i; xar_attr_t a; if( !p ) return; i = p; do { // Can only serialize these properties if it's safe to do so. if (xar_prop_serializable(i) != 0) { i = XAR_PROP(i)->next; continue; } if( XAR_PROP(i)->prefix || XAR_PROP(i)->ns ) xmlTextWriterStartElementNS(writer, BAD_CAST(XAR_PROP(i)->prefix), BAD_CAST(XAR_PROP(i)->key), NULL); else xmlTextWriterStartElement(writer, BAD_CAST(XAR_PROP(i)->key)); for(a = XAR_PROP(i)->attrs; a; a = XAR_ATTR(a)->next) { xmlTextWriterWriteAttributeNS(writer, BAD_CAST(XAR_ATTR(a)->ns), BAD_CAST(XAR_ATTR(a)->key), NULL, BAD_CAST(XAR_ATTR(a)->value)); } if( XAR_PROP(i)->value ) { if( strcmp(XAR_PROP(i)->key, "name") == 0 ) { unsigned char *tmp; const char* value = XAR_PROP(i)->value; int outlen = strlen(value); int inlen, len; inlen = len = outlen; tmp = malloc(len); assert(tmp); if( UTF8Toisolat1(tmp, &len, BAD_CAST(value), &inlen) < 0 ) { xmlTextWriterWriteAttribute(writer, BAD_CAST("enctype"), BAD_CAST("base64")); xmlTextWriterWriteBase64(writer, value, 0, strlen(value)); } else { xmlTextWriterWriteString(writer, BAD_CAST(value)); } free(tmp); } else xmlTextWriterWriteString(writer, BAD_CAST(XAR_PROP(i)->value)); } if( XAR_PROP(i)->children ) { xar_prop_serialize(XAR_PROP(i)->children, writer); } xmlTextWriterEndElement(writer); i = XAR_PROP(i)->next; } while(i); } /* xar_file_serialize * f: file to serialize * writer: the xmlTextWriterPtr allocated by xmlNewTextWriter*() * Summary: recursively serializes the file passed to it, including * children, siblings, properties, attributes, etc. */ void xar_file_serialize(xar_file_t f, xmlTextWriterPtr writer) { xar_file_t i; xar_attr_t a; i = f; do { if (xar_prop_serializable(XAR_FILE(i)->props) != 0) { // Prop is not serializable, move on to the next file. // This also has the side effect of skipping all children. i = XAR_FILE(i)->next; continue; } xmlTextWriterStartElement(writer, BAD_CAST("file")); for(a = XAR_FILE(i)->attrs; a; a = XAR_ATTR(a)->next) { xmlTextWriterWriteAttribute(writer, BAD_CAST(XAR_ATTR(a)->key), BAD_CAST(XAR_ATTR(a)->value)); } xar_prop_serialize(XAR_FILE(i)->props, writer); if( XAR_FILE(i)->children ) xar_file_serialize(XAR_FILE(i)->children, writer); xmlTextWriterEndElement(writer); i = XAR_FILE(i)->next; } while(i); return; } /* xar_prop_unserialize * f: file the property is to belong to * p: parent property, may be NULL * reader: xmlTextReaderPtr already allocated */ int32_t xar_prop_unserialize(xar_file_t f, xar_prop_t parent, xmlTextReaderPtr reader) { const char *name, *value, *ns; int type, i, isempty = 0; int isname = 0, isencoded = 0; xar_prop_t p; p = xar_prop_new(f, parent); if( xmlTextReaderIsEmptyElement(reader) ) isempty = 1; i = xmlTextReaderAttributeCount(reader); name = (const char *)xmlTextReaderConstLocalName(reader); XAR_PROP(p)->key = strdup(name); ns = (const char *)xmlTextReaderConstPrefix(reader); if( ns ) XAR_PROP(p)->prefix = strdup(ns); if( strcmp(name, "name") == 0 ) isname = 1; if( i > 0 ) { for(i = xmlTextReaderMoveToFirstAttribute(reader); i == 1; i = xmlTextReaderMoveToNextAttribute(reader)) { xar_attr_t a; const char *name = (const char *)xmlTextReaderConstLocalName(reader); const char *value = (const char *)xmlTextReaderConstValue(reader); const char *ns = (const char *)xmlTextReaderConstPrefix(reader); if( isname && (strcmp(name, "enctype") == 0) && (strcmp(value, "base64") == 0) ) { isencoded = 1; } else { a = xar_attr_new(); XAR_ATTR(a)->key = strdup(name); XAR_ATTR(a)->value = strdup(value); if(ns) XAR_ATTR(a)->ns = strdup(ns); XAR_ATTR(a)->next = XAR_PROP(p)->attrs; XAR_PROP(p)->attrs = a; } } } if( isempty ) return 0; while( xmlTextReaderRead(reader) == 1) { type = xmlTextReaderNodeType(reader); switch(type) { case XML_READER_TYPE_ELEMENT: if (xar_prop_unserialize(f, p, reader) != 0) { // Do not call free because this will result in a use after free because xar is wonderful in that it // inserts the properties into the parent link list before they're inited. return -1; } break; case XML_READER_TYPE_TEXT: value = (const char *)xmlTextReaderConstValue(reader); free((char*)XAR_PROP(p)->value); if( isencoded ) XAR_PROP(p)->value = (const char *)xar_from_base64(BAD_CAST(value), strlen(value), NULL); else XAR_PROP(p)->value = strdup(value); if( isname ) { // Sanitize the filename const char* unsafe_name = XAR_PROP(p)->value; char* safe_name; xar_is_safe_filename(unsafe_name, &safe_name); if (!safe_name) { return -1; } if( XAR_FILE(f)->parent ) { if (XAR_FILE(f)->fspath) { /* It's possible that a XAR header may contain multiple name entries. Make sure we don't smash the old one. */ free((void*)XAR_FILE(f)->fspath); XAR_FILE(f)->fspath = NULL; } asprintf((char **)&XAR_FILE(f)->fspath, "%s/%s", XAR_FILE(XAR_FILE(f)->parent)->fspath, safe_name); } else { if (XAR_FILE(f)->fspath) { /* It's possible that a XAR header may contain multiple name entries. Make sure we don't smash the old one. */ free((void*)XAR_FILE(f)->fspath); XAR_FILE(f)->fspath = NULL; } XAR_FILE(f)->fspath = strdup(safe_name); } free(safe_name); } break; case XML_READER_TYPE_END_ELEMENT: return 0; break; } } /* XXX: Should never be reached */ return 0; } /* xar_file_unserialize * x: archive we're unserializing to * parent: The parent file of the file to be unserialized. May be NULL * reader: The xmlTextReaderPtr we are reading the xml from. * Summary: Takes a node, and adds all attributes, child properties, * and child files. */ xar_file_t xar_file_unserialize(xar_t x, xar_file_t parent, xmlTextReaderPtr reader) { xar_file_t ret; const char *name; int type, i; ret = xar_file_new_from_parent(parent, NULL); i = xmlTextReaderAttributeCount(reader); if( i > 0 ) { for(i = xmlTextReaderMoveToFirstAttribute(reader); i == 1; i = xmlTextReaderMoveToNextAttribute(reader)) { xar_attr_t a; const char *name = (const char *)xmlTextReaderConstLocalName(reader); const char *value = (const char *)xmlTextReaderConstValue(reader); a = xar_attr_new(); XAR_ATTR(a)->key = strdup(name); XAR_ATTR(a)->value = strdup(value); XAR_ATTR(a)->next = XAR_FILE(ret)->attrs; XAR_FILE(ret)->attrs = a; } } // recursively unserialize each element nested within this while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); name = (const char *)xmlTextReaderConstLocalName(reader); if( (type == XML_READER_TYPE_END_ELEMENT) && (strcmp(name, "file")==0) ) { const char *opt; xar_prop_get(ret, "type", &opt); if( opt && (strcmp(opt, "hardlink") == 0) ) { opt = xar_attr_get(ret, "type", "link"); if( opt && (strcmp(opt, "original") == 0) ) { opt = xar_attr_get(ret, NULL, "id"); xmlHashAddEntry(XAR(x)->link_hash, BAD_CAST(opt), XAR_FILE(ret)); } } const char* this_file_name = NULL; xar_prop_get(ret, "name", &this_file_name); // Now sanity check. xar_file_t iter = NULL; if (parent) { iter = parent->children; } else { iter = x->files; } while(this_file_name && (iter != NULL)) { if (iter != ret) { // Uninited files are already in their parents list so, check it const char* iter_name_value = NULL; if (xar_prop_get(iter, "name", &iter_name_value) == 0) { if (iter_name_value) { // Redefinition of a file in the same directory, but is it the SAME file? if (strlen(this_file_name) == strlen(iter_name_value)) { if (strncasecmp(this_file_name, iter_name_value, strlen(this_file_name)) == 0) { // Is this the same file? if (xar_file_equals_file(ret, iter) == 0) { // Nope? Bail. if (parent == NULL) { xar_file_free(ret); } return NULL; } } } } } } iter = iter->next; } return ret; } if (type == XML_READER_TYPE_ELEMENT) { if (strcmp(name, "file") == 0) { if (xar_file_unserialize(x, ret, reader) == NULL) { if (parent == NULL) { xar_file_free(ret); } return NULL; } } else { if (xar_prop_unserialize(ret, NULL, reader) != 0) { if (parent == NULL) { xar_file_free(ret); } return NULL; } } } } /* XXX Should never be reached */ return ret; } xar-xar-498/xar/lib/filetree.h000066400000000000000000000130771446633275300163170ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_FILETREE_H_ #define _XAR_FILETREE_H_ #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #include #include struct __xar_attr_t { const char *key; const char *value; const char *ns; const struct __xar_attr_t *next; }; typedef const struct __xar_attr_t *xar_attr_t; struct __xar_prop_t { const char *key; const char *value; const struct __xar_prop_t *parent; const struct __xar_prop_t *children; const struct __xar_prop_t *next; const struct __xar_attr_t *attrs; const struct __xar_file_t *file; const char *prefix; const char *ns; }; typedef const struct __xar_prop_t *xar_prop_t; #include "ea.h" struct __xar_file_t { const struct __xar_prop_t *props; const struct __xar_attr_t *attrs; const char *prefix; const char *ns; const char *fspath; char parent_extracted; const struct __xar_file_t *parent; const struct __xar_file_t *children; const struct __xar_file_t *next; xar_ea_t eas; uint64_t nexteaid; }; /* Overview: * xar_file_t's exist within a xar_archive_t. xar_prop_t's exist * within xar_file_t's and xar_attr_t's exist within xar_prop_t's * and xar_file_t's. * Basically, a xar_file_t is a container for xar_prop_t's. * xar_attr_t's are things like: blah * In this example, foo is the key of a xar_prop_t, and blah is * the value. bar is the key of a xar_attr_t which is part of * foo's xar_prop_t, and 5 is bar's value. * xar_file_t's have xar_attr_t's for the case of: * * The file has an attribute of "id" with a value of "42". */ struct __xar_iter_t { const void *iter; char *path; void *node; int nochild; }; /* Convenience macros for dereferencing the structs */ #define XAR_ATTR(x) ((struct __xar_attr_t *)(x)) #define XAR_FILE(x) ((struct __xar_file_t *)(x)) #define XAR_PROP(x) ((struct __xar_prop_t *)(x)) #define XAR_ITER(x) ((struct __xar_iter_t *)(x)) void xar_file_free(xar_file_t f); xar_attr_t xar_attr_new(void); int32_t xar_attr_set(xar_file_t f, const char *prop, const char *key, const char *value); int32_t xar_attr_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value); const char *xar_attr_get(xar_file_t f, const char *prop, const char *key); const char *xar_attr_pget(xar_file_t f, xar_prop_t p, const char *key); int xar_attr_equals_attr(xar_attr_t a1, xar_attr_t a2); int xar_attr_equals_attr_ignoring_keys(xar_attr_t a1, xar_attr_t a2, uint64_t key_count, char** keys_to_ignore); void xar_attr_free(xar_attr_t a); void xar_file_serialize(xar_file_t f, xmlTextWriterPtr writer); int xar_prop_serializable(xar_prop_t p); xar_file_t xar_file_unserialize(xar_t x, xar_file_t parent, xmlTextReaderPtr reader); xar_file_t xar_file_find(xar_file_t f, const char *path); xar_file_t xar_file_new(const char *name); xar_file_t xar_file_new_from_parent(xar_file_t parent, const char *name); xar_file_t xar_file_replicate(xar_file_t original, xar_file_t newparent); int xar_file_equals_file(xar_file_t f1, xar_file_t f2); void xar_file_free(xar_file_t f); void xar_prop_serialize(xar_prop_t p, xmlTextWriterPtr writer); int32_t xar_prop_unserialize(xar_file_t f, xar_prop_t parent, xmlTextReaderPtr reader); void xar_prop_free(xar_prop_t p); xar_prop_t xar_prop_new(xar_file_t f, xar_prop_t parent); xar_prop_t xar_prop_pset(xar_file_t f, xar_prop_t p, const char *key, const char *value); xar_prop_t xar_prop_find(xar_prop_t p, const char *key); xar_prop_t xar_prop_pget(xar_prop_t p, const char *key); const char *xar_prop_getkey(xar_prop_t p); const char *xar_prop_getvalue(xar_prop_t p); int32_t xar_prop_setkey(xar_prop_t p, const char *key); int32_t xar_prop_setvalue(xar_prop_t p, const char *value); xar_prop_t xar_prop_pfirst(xar_file_t f); xar_prop_t xar_prop_pnext(xar_prop_t p); void xar_prop_punset(xar_file_t f, xar_prop_t p); int xar_prop_equals_prop(xar_prop_t prop1, xar_prop_t prop2); #endif /* _XAR_FILETREE_H_ */ xar-xar-498/xar/lib/hash.c000066400000000000000000000261751446633275300154410ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include #include #include #include #include #ifdef __APPLE__ #include #include #else #include #endif #include "xar.h" #include "hash.h" #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #pragma mark Hash Wrapper Object #ifdef __APPLE__ CCDigestRef digestRef_from_name(const char* name, unsigned int *outHashSize) { CCDigestRef result = NULL; if (NULL != outHashSize) *outHashSize = 0; if (0 == strcasecmp(name, "sha512")) { result = CCDigestCreate(kCCDigestSHA512); if (NULL != outHashSize) *outHashSize = CC_SHA512_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "sha256")) { result = CCDigestCreate(kCCDigestSHA256); if (NULL != outHashSize) *outHashSize = CC_SHA256_DIGEST_LENGTH; } else if (0 == strcasecmp(name, "sha") || !strcasecmp(name, "sha1")) { result = CCDigestCreate(kCCDigestSHA1); if (NULL != outHashSize) *outHashSize = CC_SHA1_DIGEST_LENGTH; #ifdef XAR_SUPPORT_MD5 } else if (0 == strcasecmp(name, "md5")) { result = CCDigestCreate(kCCDigestMD5); if (NULL != outHashSize) *outHashSize = CC_MD5_DIGEST_LENGTH; #endif // XAR_SUPPORT_MD5 } return result; } #endif // __APPLE__ struct __xar_hash_t { const char *digest_name; void *context; #ifdef __APPLE__ CCDigestRef digest; #else EVP_MD_CTX digest; const EVP_MD *type; #endif unsigned int length; }; #define HASH_CTX(x) ((struct __xar_hash_t *)(x)) xar_hash_t xar_hash_new(const char *digest_name, void *context) { struct __xar_hash_t *hash = calloc(1, sizeof(struct __xar_hash_t)); if( ! hash ) return NULL; // errno will already be set if( context ) HASH_CTX(hash)->context = context; #ifdef __APPLE__ HASH_CTX(hash)->digest = digestRef_from_name(digest_name, &HASH_CTX(hash)->length); #else OpenSSL_add_all_digests(); HASH_CTX(hash)->type = EVP_get_digestbyname(digest_name); EVP_DigestInit(&HASH_CTX(hash)->digest, HASH_CTX(hash)->type); #endif HASH_CTX(hash)->digest_name = strdup(digest_name); return hash; } void *xar_hash_get_context(xar_hash_t hash) { return HASH_CTX(hash)->context; } const char *xar_hash_get_digest_name(xar_hash_t hash) { return HASH_CTX(hash)->digest_name; } void xar_hash_update(xar_hash_t hash, void *buffer, size_t nbyte) { #ifdef __APPLE__ CCDigestUpdate(HASH_CTX(hash)->digest, buffer, nbyte); #else EVP_DigestUpdate(&HASH_CTX(hash)->digest, buffer, nbyte); #endif } void *xar_hash_finish(xar_hash_t hash, size_t *nbyte) { #ifdef __APPLE__ void *buffer = calloc(1, CC_SHA512_DIGEST_LENGTH); // current biggest digest size This is what OpenSSL uses #else void *buffer = calloc(1, EVP_MAX_MD_SIZE); #endif if( ! buffer ) return NULL; #ifdef __APPLE__ CCDigestFinal(HASH_CTX(hash)->digest, buffer); CCDigestDestroy(HASH_CTX(hash)->digest); #else EVP_DigestFinal(&HASH_CTX(hash)->digest, buffer, &HASH_CTX(hash)->length); #endif *nbyte = HASH_CTX(hash)->length; free((void *)HASH_CTX(hash)->digest_name); free((void *)hash); return buffer; } #undef HASH_CTX #pragma mark datamod struct _hash_context { xar_hash_t archived; xar_hash_t unarchived; uint64_t count; }; #define CONTEXT(x) ((struct _hash_context *)(*x)) static char *_xar_format_hash(const unsigned char* m,unsigned int len) { char *result = malloc((2*len)+1); char hexValue[3]; unsigned int itr = 0; result[0] = '\0'; for(itr = 0;itr < len;itr++) { sprintf(hexValue,"%02x",m[itr]); strncat(result,hexValue,2); } return result; } int32_t xar_hash_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { return xar_hash_fromheap_out(x,f,p,*in,*inlen,context); } int32_t xar_hash_fromheap_out(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context) { if (!context) return 0; if(!CONTEXT(context) || (! CONTEXT(context)->unarchived) ) { const char *opt; xar_prop_t tmpp; opt = NULL; tmpp = xar_prop_pget(p, "extracted-checksum"); if( tmpp ) { opt = xar_attr_pget(f, tmpp, "style"); } else { // The xar-1.7 release in OS X Yosemite accidentally wrote // instead of . Since archives like this are now in the wild, // we check for both. tmpp = xar_prop_pget(p, "unarchived-checksum"); if( tmpp ) { opt = xar_attr_pget(f, tmpp, "style"); } } // If there's an and no (or // ), the archive is malformed. if ( !opt && xar_prop_pget(p, "archived-checksum") ) { xar_err_new(x); xar_err_set_string(x, "No extracted-checksum"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } if( !opt ) opt = xar_opt_get(x, XAR_OPT_FILECKSUM); if( !opt || (0 == strcmp(opt, XAR_OPT_VAL_NONE) ) ) return 0; if (!CONTEXT(context)) { *context = calloc(1, sizeof(struct _hash_context)); if( ! *context ) return -1; } if( ! CONTEXT(context)->unarchived ) { CONTEXT(context)->unarchived = xar_hash_new(opt, NULL); if( ! CONTEXT(context)->unarchived ) { free(*context); *context = NULL; return -1; } } } if( inlen == 0 ) return 0; CONTEXT(context)->count += inlen; xar_hash_update(CONTEXT(context)->unarchived, in, inlen); return 0; } int32_t xar_hash_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { return xar_hash_toheap_out(x,f,p,*in,*inlen,context); } int32_t xar_hash_toheap_out(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context) { const char *opt; xar_prop_t tmpp; opt = NULL; tmpp = xar_prop_pget(p, "archived-checksum"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) opt = xar_opt_get(x, XAR_OPT_FILECKSUM); if( !opt || (0 == strcmp(opt, XAR_OPT_VAL_NONE) ) ) return 0; if( ! CONTEXT(context) ) { *context = calloc(1, sizeof(struct _hash_context)); if( ! *context ) return -1; } if( ! CONTEXT(context)->archived ) { CONTEXT(context)->archived = xar_hash_new(opt, NULL); if( ! CONTEXT(context)->archived ) { free(*context); *context = NULL; return -1; } } if( inlen == 0 ) return 0; CONTEXT(context)->count += inlen; xar_hash_update(CONTEXT(context)->archived, in, inlen); return 0; } int32_t xar_hash_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { const char *archived_style = NULL, *unarchived_style = NULL; size_t archived_length = -1, unarchived_length = -1; void *archived_hash = NULL, *unarchived_hash = NULL; if( ! CONTEXT(context) ) return 0; else if( CONTEXT(context)->count == 0 ) goto DONE; archived_style = strdup(xar_hash_get_digest_name(CONTEXT(context)->archived)); unarchived_style = strdup(xar_hash_get_digest_name(CONTEXT(context)->unarchived)); archived_hash = xar_hash_finish(CONTEXT(context)->archived, &archived_length); unarchived_hash = xar_hash_finish(CONTEXT(context)->unarchived, &unarchived_length); CONTEXT(context)->archived = NULL; CONTEXT(context)->unarchived = NULL; char *str; xar_prop_t tmpp; str = _xar_format_hash(archived_hash, archived_length); if( f ) { tmpp = xar_prop_pset(f, p, "archived-checksum", str); if( tmpp ) xar_attr_pset(f, tmpp, "style", archived_style); } free(str); str = _xar_format_hash(unarchived_hash, unarchived_length); if( f ) { tmpp = xar_prop_pset(f, p, "extracted-checksum", str); if( tmpp ) xar_attr_pset(f, tmpp, "style", unarchived_style); } free(str); DONE: free((void *)archived_style); free((void *)unarchived_style); free(archived_hash); free(unarchived_hash); free(*context); *context = NULL; return 0; } int32_t xar_hash_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { if(!CONTEXT(context)) return 0; int32_t result = 0; const char *archived_hash = NULL, *archived_style = NULL; // Fetch the existing hash from the archive if( CONTEXT(context)->archived ) { xar_prop_t tmpp = xar_prop_pget(p, "archived-checksum"); if( tmpp ) { archived_style = xar_attr_pget(f, tmpp, "style"); archived_hash = xar_prop_getvalue(tmpp); } // We have the fetched hash; now get the calculated hash if( archived_hash && archived_style ) { size_t calculated_length = -1; const char *calculated_style = strdup(xar_hash_get_digest_name(CONTEXT(context)->archived)); void *calculated_buffer = xar_hash_finish(CONTEXT(context)->archived, &calculated_length); CONTEXT(context)->archived = NULL; char *calculated_hash = _xar_format_hash(calculated_buffer, calculated_length); free(calculated_buffer); // Compare int hash_match = ( strcmp(archived_hash, calculated_hash) == 0 ); int style_match = (strcmp(archived_style, calculated_style) == 0 ); if( ! hash_match || ! style_match ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_formatted_string(x, "archived-checksum %s's do not match", archived_style); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); result = -1; } free((void *)calculated_style); free(calculated_hash); } } // Clean up the unarchived hash as well, if we have one if( CONTEXT(context)->unarchived ) { size_t length = -1; void *hash = xar_hash_finish(CONTEXT(context)->unarchived, &length); CONTEXT(context)->unarchived = NULL; free(hash); } if(*context) { free(*context); *context = NULL; } return result; } xar-xar-498/xar/lib/hash.h000066400000000000000000000054101446633275300154330ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_HASH_H_ #define _XAR_HASH_H_ #include "filetree.h" #pragma mark Hash Wrapper Object typedef struct __xar_hash_t *xar_hash_t; xar_hash_t xar_hash_new(const char *digest_name, void *context); void *xar_hash_get_context(xar_hash_t hash); const char *xar_hash_get_digest_name(xar_hash_t hash); // returns inner pointer void xar_hash_update(xar_hash_t hash, void *buffer, size_t nbyte); void *xar_hash_finish(xar_hash_t hash, size_t *nbyte); #pragma mark datamod int32_t xar_hash_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int32_t xar_hash_fromheap_out(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); int32_t xar_hash_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); int32_t xar_hash_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int32_t xar_hash_toheap_out(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); int32_t xar_hash_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _XAR_HASH_H_ */ xar-xar-498/xar/lib/io.c000066400000000000000000000540431446633275300151200ustar00rootroot00000000000000/* * Copyright (c) 2005-2008 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "filetree.h" #include "archive.h" #include "io.h" #include "zxar.h" #include "bzxar.h" #include "lzmaxar.h" #include "hash.h" #include "script.h" #include "macho.h" #include "util.h" #include "data.h" #if !defined(LLONG_MAX) && defined(LONG_LONG_MAX) #define LLONG_MAX LONG_LONG_MAX #endif #if !defined(LLONG_MIN) && defined(LONG_LONG_MIN) #define LLONG_MIN LONG_LONG_MIN #endif // IMPORTANT: Keep datamod count up to date in io.h! struct datamod xar_datamods[] = { { xar_hash_fromheap_in, xar_hash_fromheap_out, xar_hash_fromheap_done, xar_hash_toheap_in, xar_hash_toheap_out, xar_hash_toheap_done }, { (fromheap_in)NULL, (fromheap_out)NULL, (fromheap_done)NULL, xar_script_in, (toheap_out)NULL, xar_script_done }, { (fromheap_in)NULL, (fromheap_out)NULL, (fromheap_done)NULL, NULL, (toheap_out)NULL, NULL }, { xar_gzip_fromheap_in, (fromheap_out)NULL, xar_gzip_fromheap_done, xar_gzip_toheap_in, (toheap_out)NULL, xar_gzip_toheap_done }, { xar_bzip_fromheap_in, (fromheap_out)NULL, xar_bzip_fromheap_done, xar_bzip_toheap_in, (toheap_out)NULL, xar_bzip_toheap_done }, { xar_lzma_fromheap_in, (fromheap_out)NULL, xar_lzma_fromheap_done, xar_lzma_toheap_in, (toheap_out)NULL, xar_lzma_toheap_done } }; size_t xar_io_get_rsize(xar_t x) { size_t bsize = xar_optimal_io_size_at_path(XAR(x)->dirname); const char *opt = NULL; opt = xar_opt_get(x, XAR_OPT_RSIZE); if( opt ) { errno = 0; size_t potential_bsize = strtol(opt, NULL, 0); if ( potential_bsize != 0 && errno != ERANGE && potential_bsize != LONG_MAX && potential_bsize != LONG_MIN) { bsize = potential_bsize; } } return bsize; } off_t xar_io_get_heap_base_offset(xar_t x) { return XAR(x)->toc_count + sizeof(xar_header_t); } size_t xar_io_get_toc_checksum_length_for_type(const char *type) { if( !type ) { return 0; } else if( strcmp(type, XAR_OPT_VAL_NONE) == 0 ) { return 0; } else if( strcmp(type, XAR_OPT_VAL_SHA1) == 0 ) { return 20; } else if( strcmp(type, XAR_OPT_VAL_SHA256) == 0 ) { return 32; } else if( strcmp(type, XAR_OPT_VAL_SHA512) == 0 ) { return 64; } else if( strcmp(type, XAR_OPT_VAL_MD5) == 0 ) { // Left in place regardless of XAR_SUPPORT_MD5 for proper archive parsing return 16; } else { return 0; } } size_t xar_io_get_toc_checksum_length(xar_t x) { switch(XAR(x)->header.cksum_alg) { case XAR_CKSUM_NONE: // Left in place even though it is no longer supported for archive parsing return 0; case XAR_CKSUM_SHA1: return 20; case XAR_CKSUM_SHA256: return 32; case XAR_CKSUM_SHA512: return 64; case XAR_CKSUM_MD5: // Left in place regardless of XAR_SUPPORT_MD5 for proper archive parsing return 16; default: fprintf(stderr, "Unknown hashing algorithm, skipping\n"); return 0; }; } off_t xar_io_get_file_offset(xar_t x, xar_file_t f, xar_prop_t p) { xar_prop_t tmpp; const char *opt = NULL; tmpp = xar_prop_pget(p, "offset"); if( tmpp ) { opt = xar_prop_getvalue(tmpp); if (opt == NULL){ return -1; } return strtoll(opt, NULL, 0); } else { return -1; } } int64_t xar_io_get_length(xar_prop_t p) { const char *opt = NULL; int64_t fsize = 0; xar_prop_t tmpp; tmpp = xar_prop_pget(p, "length"); if( tmpp ) opt = xar_prop_getvalue(tmpp); if( !opt ) { return 0; } else { fsize = strtoll(opt, NULL, 10); if( ((fsize == LLONG_MAX) || (fsize == LLONG_MIN)) && (errno == ERANGE) ) { return -1; } } return fsize; } static void xar_io_seek(xar_t x, xar_file_t f, off_t seekoff) { int r; if( XAR(x)->fd >= 0 ) { r = lseek(XAR(x)->fd, seekoff, SEEK_SET); if( r == -1 ) { if( errno == ESPIPE ) { ssize_t rr; char *buf; unsigned int len; len = seekoff - XAR(x)->toc_count; len -= sizeof(xar_header_t); if( XAR(x)->heap_offset > len ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Unable to seek"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } else { len -= XAR(x)->heap_offset; buf = malloc(len); assert(buf); rr = xar_read_fd(XAR(x)->fd, buf, len); if( rr < len ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Unable to seek"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } XAR(x)->heap_offset += rr; free(buf); } } else { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Unable to seek"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } } } } int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, xar_prop_t p, read_callback rcb, void *context) { int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); void *modulecontext[modulecount]; int r, i; size_t bsize, rsize; int64_t readsize=0, writesize=0, inc = 0, this_write=0; void *inbuf; char *tmpstr = NULL; const char *opt = NULL, *csum = NULL; off_t orig_heap_offset = XAR(x)->heap_offset; xar_file_t tmpf = NULL; xar_prop_t tmpp = NULL; memset(modulecontext, 0, sizeof(void*)*modulecount); bsize = xar_io_get_rsize(x); r = 1; // (Apple) allocate once inbuf = malloc(bsize); if( !inbuf ) return -1; while(r != 0) { r = rcb(x, f, inbuf, bsize, context); if( r < 0 ) { free(inbuf); return -1; } readsize+=r; inc += r; rsize = r; /* filter the data through the in modules */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_in ) { xar_datamods[i].th_in(x, f, p, &inbuf, &rsize, &(modulecontext[i])); } } /* filter the data through the out modules */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_out ) xar_datamods[i].th_out(x, f, p, inbuf, rsize, &(modulecontext[i])); } size_t written = 0; if( rsize != 0 ) { while(written < rsize) { this_write = xar_write_fd(XAR(x)->heap_fd, inbuf, rsize); if( this_write < 0 ) { xar_err_new(x); xar_err_set_string(x, "write(2) error when writing to heap"); xar_err_set_errno(x, errno); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); free(inbuf); return -1; } written += this_write; } } XAR(x)->heap_offset += written; writesize += written; } free(inbuf); /* If size is 0, don't bother having anything in the heap */ if( readsize == 0 ) { XAR(x)->heap_offset = orig_heap_offset; lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR); for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) xar_datamods[i].th_done(x, f, p, &(modulecontext[i])); } return 0; } /* finish up anything that still needs doing */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].th_done ) xar_datamods[i].th_done(x, f, p, &(modulecontext[i])); } XAR(x)->heap_len += writesize; tmpp = xar_prop_pget(p, "archived-checksum"); if( tmpp ) csum = xar_prop_getvalue(tmpp); if( csum ) tmpf = xmlHashLookup(XAR(x)->csum_hash, BAD_CAST(csum)); if( tmpf ) { const char *attr = xar_prop_getkey(p); opt = xar_opt_get(x, XAR_OPT_LINKSAME); if( opt && (strcmp(attr, "data") == 0) ) { const char *id = xar_attr_pget(tmpf, NULL, "id"); xar_prop_pset(f, NULL, "type", "hardlink"); tmpp = xar_prop_pfirst(f); if( tmpp ) tmpp = xar_prop_find(tmpp, "type"); if( tmpp ) xar_attr_pset(f, tmpp, "link", id); xar_prop_pset(tmpf, NULL, "type", "hardlink"); tmpp = xar_prop_pfirst(tmpf); if( tmpp ) tmpp = xar_prop_find(tmpp, "type"); if( tmpp ) xar_attr_pset(tmpf, tmpp, "link", "original"); tmpp = xar_prop_pfirst(f); if( tmpp ) tmpp = xar_prop_find(tmpp, "data"); xar_prop_punset(f, tmpp); XAR(x)->heap_offset = orig_heap_offset; lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR); XAR(x)->heap_len -= writesize; return 0; } opt = xar_opt_get(x, XAR_OPT_COALESCE); if( opt ) { long long tmpoff; const char *offstr = NULL; tmpp = xar_prop_pfirst(tmpf); if( tmpp ) { const char *key; key = xar_prop_getkey(p); tmpp = xar_prop_find(tmpp, key); } if( tmpp ) tmpp = xar_prop_pget(tmpp, "offset"); if( tmpp ) offstr = xar_prop_getvalue(tmpp); if( offstr ) { tmpoff = strtoll(offstr, NULL, 10); XAR(x)->heap_offset = orig_heap_offset; lseek(XAR(x)->heap_fd, -writesize, SEEK_CUR); orig_heap_offset = tmpoff; XAR(x)->heap_len -= writesize; } } } else if( csum ) { xmlHashAddEntry(XAR(x)->csum_hash, BAD_CAST(csum), XAR_FILE(f)); } else { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "No archived-checksum"); xar_err_callback(x, XAR_SEVERITY_WARNING, XAR_ERR_ARCHIVE_CREATION); } asprintf(&tmpstr, "%"PRIu64, readsize); xar_prop_pset(f, p, "size", tmpstr); free(tmpstr); asprintf(&tmpstr, "%"PRIu64, (uint64_t)orig_heap_offset); xar_prop_pset(f, p, "offset", tmpstr); free(tmpstr); tmpstr = (char *)xar_opt_get(x, XAR_OPT_COMPRESSION); if( tmpstr && (strcmp(tmpstr, XAR_OPT_VAL_NONE) == 0) ) { xar_prop_pset(f, p, "encoding", NULL); tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) xar_attr_pset(f, tmpp, "style", "application/octet-stream"); } asprintf(&tmpstr, "%"PRIu64, writesize); xar_prop_pset(f, p, "length", tmpstr); free(tmpstr); return 0; } /* xar_copy_from_heap * This is the arcmod extraction entry point for extracting the file's * data from the heap file. * It is assumed the heap_fd is already positioned appropriately. */ int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, xar_prop_t p, write_callback wcb, void *context) { int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); void *modulecontext[modulecount]; int r, i; size_t bsize, def_bsize; int64_t fsize, inc = 0, seekoff, readsofar = 0; void *inbuf; const char *opt; xar_prop_t tmpp; memset(modulecontext, 0, sizeof(void*)*modulecount); def_bsize = xar_io_get_rsize(x); seekoff = xar_io_get_file_offset(x, f, p); if( seekoff == -1 ) { wcb(x, f, NULL, 0, context); return 0; } else if( ((seekoff == LLONG_MAX) || (seekoff == LLONG_MIN)) && (errno == ERANGE) ) { return -1; } seekoff += xar_io_get_heap_base_offset(x); xar_io_seek(x, f, seekoff); fsize = xar_io_get_length(p); if( fsize == 0 ) return 0; if( fsize < 0 ) return -1; bsize = def_bsize; inbuf = malloc(bsize); if( !inbuf ) { return -1; } while(1) { /* Size has been reached */ if( fsize == inc ) break; if( (fsize - inc) < bsize ) bsize = fsize - inc; r = read(XAR(x)->fd, inbuf, bsize); if( r == 0 ) break; if( (r < 0) && (errno == EINTR) ) continue; if( r < 0 ) { free(inbuf); return -1; } XAR(x)->heap_offset += r; inc += r; bsize = r; /* filter the data through the in modules */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_in ) { int32_t ret; ret = xar_datamods[i].fh_in(x, f, p, &inbuf, &bsize, &(modulecontext[i])); if( ret < 0 ) { free(inbuf); // (Apple) don't leak inbuf return -1; } } } /* Only due the write phase, if there is a write function to call */ if(wcb){ /* filter the data through the out modules */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_out ) { int32_t ret; ret = xar_datamods[i].fh_out(x, f, p, inbuf, bsize, &(modulecontext[i])); if( ret < 0 ) { free(inbuf); // (Apple) don't leak inbuf return -1; } } } wcb(x, f, inbuf, bsize, context); } readsofar += bsize; if (DATA_CONTEXT(context)->progress) DATA_CONTEXT(context)->progress(x, f, readsofar); bsize = def_bsize; } free(inbuf); /* finish up anything that still needs doing */ for( i = 0; i < modulecount; i++) { if( xar_datamods[i].fh_done ) { int32_t ret; ret = xar_datamods[i].fh_done(x, f, p, &(modulecontext[i])); if( ret < 0 ) return ret; } } return 0; } /* xar_attrcopy_from_heap_to_heap * This does a simple copy of the heap data from one head (read-only) to another heap (write only). * This does not set any properties or attributes of the file, so this should not be used alone. */ int32_t xar_attrcopy_from_heap_to_heap(xar_t xsource, xar_file_t fsource, xar_prop_t p, xar_t xdest, xar_file_t fdest){ int r, off; size_t bsize; int64_t fsize, inc = 0, seekoff, writesize=0; off_t orig_heap_offset = XAR(xdest)->heap_offset; void *inbuf; const char *opt; char *tmpstr = NULL; xar_prop_t tmpp; bsize = xar_io_get_rsize(xsource); seekoff = xar_io_get_file_offset(xsource, fsource, p); if( seekoff < 0 ) return -1; seekoff += XAR(xsource)->toc_count + sizeof(xar_header_t); xar_io_seek(xsource, fsource, seekoff); fsize = xar_io_get_length(p); if( fsize == 0 ) return 0; if( fsize < 0 ) return -1; inbuf = malloc(bsize); if( !inbuf ) { return -1; } while(1) { /* Size has been reached */ if( fsize == inc ) break; if( (fsize - inc) < bsize ) bsize = fsize - inc; r = read(XAR(xsource)->fd, inbuf, bsize); if( r == 0 ) break; if( (r < 0) && (errno == EINTR) ) continue; if( r < 0 ) { free(inbuf); return -1; } XAR(xsource)->heap_offset += r; inc += r; bsize = r; off = 0; do { r = write(XAR(xdest)->heap_fd, ((char *)inbuf)+off, r-off ); off += r; writesize += r; } while( off < r ); XAR(xdest)->heap_offset += off; XAR(xdest)->heap_len += off; } asprintf(&tmpstr, "%"PRIu64, (uint64_t)orig_heap_offset); opt = xar_prop_getkey(p); tmpp = xar_prop_pfirst(fdest); if( tmpp ) tmpp = xar_prop_find(tmpp, opt); if( tmpp ) xar_prop_pset(fdest, tmpp, "offset", tmpstr); free(tmpstr); free(inbuf); /* It is the caller's responsibility to copy the attributes of the file, etc, this only copies the data in the heap */ return 0; } static int32_t flush_stream(xar_stream *stream) { xar_stream_state_t *state = (xar_stream_state_t *)(stream->state); if( state->pending_buf && stream->avail_out ) { size_t len = state->pending_buf_size; if( stream->avail_out < len ) { len = stream->avail_out; } memcpy(stream->next_out, state->pending_buf, len); stream->next_out += len; stream->avail_out -= len; stream->total_out += len; if( state->pending_buf_size == len ) { state->pending_buf_size = 0; free(state->pending_buf); state->pending_buf = NULL; } else if( state->pending_buf_size > len ) { state->pending_buf_size -= len; memcpy(state->pending_buf, state->pending_buf + len, state->pending_buf_size); } } return XAR_STREAM_OK; } static int32_t write_to_stream(void *inbuf, size_t inlen, xar_stream *stream) { xar_stream_state_t *state = (xar_stream_state_t *)stream->state; size_t len = inlen; if( stream->avail_out < len ) { len = stream->avail_out; } memcpy(stream->next_out, inbuf, len); stream->next_out += len; stream->avail_out -= len; stream->total_out += len; if( inlen > len ) { state->pending_buf_size = inlen - len; state->pending_buf = malloc(state->pending_buf_size); memcpy(state->pending_buf, ((char *)inbuf) + len, state->pending_buf_size); } return XAR_STREAM_OK; } int32_t xar_attrcopy_from_heap_to_stream_init(xar_t x, xar_file_t f, xar_prop_t p, xar_stream *stream) { xar_stream_state_t *state; off_t seekoff; seekoff = xar_io_get_file_offset(x, f, p); if( seekoff < 0 ) return XAR_STREAM_ERR; state = calloc(1, sizeof(xar_stream_state_t)); if( !state ) { return XAR_STREAM_ERR; } stream->state = (void*)state; state->bsize = xar_io_get_rsize(x); state->modulecount = (sizeof(xar_datamods)/sizeof(struct datamod)); state->modulecontext = calloc(1, sizeof(void*)*state->modulecount); if( !state->modulecontext ) { free(state); return XAR_STREAM_ERR; } seekoff += XAR(x)->toc_count + sizeof(xar_header_t); xar_io_seek(x, f, seekoff); stream->total_in = 0; stream->total_out = 0; state->fsize = xar_io_get_length(p); if(state->fsize == 0) { return XAR_STREAM_OK; } else if(state->fsize == -1) { free(state->modulecontext); free(state); return XAR_STREAM_ERR; } state->pending_buf = NULL; state->pending_buf_size = 0; state->x = x; state->f = f; state->p = p; return XAR_STREAM_OK; } int32_t xar_attrcopy_from_heap_to_stream(xar_stream *stream) { xar_stream_state_t *state = stream->state; int r, i; size_t bsize; void *inbuf; if( state->pending_buf_size ) { return flush_stream(stream); } bsize = state->bsize; inbuf = malloc(bsize); if( !inbuf ) { return XAR_STREAM_ERR; } /* Size has been reached */ if( state->fsize == stream->total_in ) { free(inbuf); return XAR_STREAM_END; } if( (state->fsize - stream->total_in) < bsize ) bsize = state->fsize - stream->total_in; r = read(XAR(state->x)->fd, inbuf, bsize); if( r == 0 ) { free(inbuf); return XAR_STREAM_END; } if( (r < 0) && (errno == EINTR) ) { free(inbuf); return XAR_STREAM_OK; } if( r < 0 ) { free(inbuf); return XAR_STREAM_ERR; } XAR(state->x)->heap_offset += r; stream->total_in += r; bsize = r; /* filter the data through the in modules */ for( i = 0; i < state->modulecount; i++) { if( xar_datamods[i].fh_in ) { int32_t ret; ret = xar_datamods[i].fh_in(state->x, state->f, state->p, &inbuf, &bsize, &(state->modulecontext[i])); if( ret < 0 ) return XAR_STREAM_ERR; } } /* filter the data through the out modules */ for( i = 0; i < state->modulecount; i++) { if( xar_datamods[i].fh_out ) { int32_t ret; ret = xar_datamods[i].fh_out(state->x, state->f, state->p, inbuf, bsize, &(state->modulecontext[i])); if( ret < 0 ) return XAR_STREAM_ERR; } } write_to_stream(inbuf, bsize, stream); free(inbuf); return XAR_STREAM_OK; } int32_t xar_attrcopy_from_heap_to_stream_end(xar_stream *stream) { xar_stream_state_t *state = (xar_stream_state_t *)stream->state; int i; /* finish up anything that still needs doing */ for( i = 0; i < state->modulecount; i++) { if( xar_datamods[i].fh_done ) { int32_t ret; ret = xar_datamods[i].fh_done(state->x, state->f, state->p, &(state->modulecontext[i])); if( ret < 0 ) return ret; } } if( state->pending_buf ) { free(state->pending_buf); } free(state->modulecontext); free(state); return XAR_STREAM_OK; } static ssize_t xar_pread_block(int fd, void *buf, size_t nbyte, off_t offset) { ssize_t total = 0; while (total < nbyte) { ssize_t len = pread(fd, buf + total, nbyte - total, offset + total); if (len < 0) { if (errno == EINTR) { continue; } return -1; } if (len == 0) { // hit EOF, return partial read return total; } total += len; } return total; } static ssize_t xar_pwrite_block(int fd, const void *buf, size_t nbyte, off_t offset) { ssize_t total = 0; while (total < nbyte) { ssize_t len = pwrite(fd, buf + total, nbyte - total, offset + total); if (len < 0) { if (errno == EINTR) { continue; } return -1; } total += len; } return total; } /* xar_heap_to_archive * x: archive to operate on * Returns 0 on success, -1 on error * Summary: copies the heap into the archive. */ int32_t xar_heap_to_archive(xar_t x) { const long bsize = xar_io_get_rsize(x); const ssize_t dst_heap_start_offset = lseek(XAR(x)->fd, 0, SEEK_CUR); if ( dst_heap_start_offset < 0 ) { return -1; } const ssize_t src_heap_size = lseek(XAR(x)->heap_fd, 0, SEEK_END); if ( src_heap_size < 0 ) { return -1; } char *b = malloc(bsize); if( !b ) return -1; // Let's set our offset to the end of the XAR file (end of dst heap) ssize_t src_heap_offset = src_heap_size; while (1) { // Move backward by one block. src_heap_offset = MAX(0, src_heap_offset - bsize); // Read from the source heap using the current offset ssize_t read_len = xar_pread_block(XAR(x)->heap_fd, b, bsize, src_heap_offset); if ( read_len == 0 ) break; if ( read_len < 0 ) { free(b); return -1; } // This line right here is the entire reason we read / write the heap backwards. // We've already read anything after this offset, so go ahead and truncate it. if ( ftruncate(XAR(x)->heap_fd, src_heap_offset) != 0 ) { free(b); return -1; } // Write the same number of bytes into the output heap ssize_t write_len = xar_pwrite_block(XAR(x)->fd, b, read_len, dst_heap_start_offset + src_heap_offset); if ( ( write_len < 0 ) || ( write_len != read_len ) ) { free(b); return -1; } } free(b); return 0; } xar-xar-498/xar/lib/io.h000066400000000000000000000077411446633275300151300ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_IO_H_ #define _XAR_IO_H_ #include "archive.h" //typedef int (*read_callback)(xar_t, xar_file_t, void *, size_t, void *context); //typedef int (*write_callback)(xar_t, xar_file_t, void *, size_t, void *context); typedef int (*fromheap_in)(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); typedef int (*fromheap_out)(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); typedef int (*fromheap_done)(xar_t x, xar_file_t f, xar_prop_t p, void **context); typedef int (*toheap_in)(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); typedef int (*toheap_out)(xar_t x, xar_file_t f, xar_prop_t p, void *in, size_t inlen, void **context); typedef int (*toheap_done)(xar_t x, xar_file_t f, xar_prop_t p, void **context); struct datamod { fromheap_in fh_in; fromheap_out fh_out; fromheap_done fh_done; toheap_in th_in; toheap_out th_out; toheap_done th_done; }; typedef struct xar_stream_state { char *pending_buf; size_t pending_buf_size; void **modulecontext; int modulecount; size_t bsize; int64_t fsize; xar_t x; xar_file_t f; xar_prop_t p; } xar_stream_state_t; size_t xar_io_get_rsize(xar_t x); off_t xar_io_get_heap_base_offset(xar_t x); size_t xar_io_get_toc_checksum_length_for_type(const char *type); size_t xar_io_get_toc_checksum_length(xar_t x); off_t xar_io_get_file_offset(xar_t x, xar_file_t f, xar_prop_t p); int64_t xar_io_get_length(xar_prop_t p); int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, xar_prop_t p, read_callback rcb, void *context); int32_t xar_attrcopy_from_heap(xar_t x, xar_file_t f, xar_prop_t p, write_callback wcb, void *context); int32_t xar_attrcopy_from_heap_to_heap(xar_t xsource, xar_file_t fsource, xar_prop_t p, xar_t xdest, xar_file_t fdest); int32_t xar_attrcopy_from_heap_to_stream_init(xar_t x, xar_file_t f, xar_prop_t p, xar_stream *stream); int32_t xar_attrcopy_from_heap_to_stream(xar_stream *stream); int32_t xar_attrcopy_from_heap_to_stream_end(xar_stream *stream); int32_t xar_heap_to_archive(xar_t x); #pragma mark internal // IMPORTANT: Keep count synchronized with declaration in io.c! extern struct datamod xar_datamods[6]; #endif /* _XAR_IO_H_ */ xar-xar-498/xar/lib/libxar.la.in.in000066400000000000000000000013641446633275300171540ustar00rootroot00000000000000# libxar.la - a libtool library file # Generated by @PACKAGE_STRING@ for libtool # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='@LIBXAR_SNAME@' # Names of this library. library_names='@LIBXAR_SNAME@ @LIBXAR_LNAME@' # The name of the static archive. old_library='@LIBXAR_ANAME@' # Libraries that this one depends upon. dependency_libs='@LIBS@' # Version information for libxar. current=0 age=0 revision=@LIB_REV@ # Is this an already installed library? installed=no # Should we warn about portability when linking against -modules? shouldnotlink=no # Files to dlopen/dlpreopen dlopen='' dlpreopen='' # Directory that this library needs to be installed in: libdir='@LIBDIR@' xar-xar-498/xar/lib/linuxattr.c000066400000000000000000000167251446633275300165500ustar00rootroot00000000000000/* * Copyright (c) 2004 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 26-Oct-2004 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #include #include #include #include "xar.h" #include "arcmod.h" #include "b64.h" #include #include #include "util.h" #include "linuxattr.h" #include "io.h" #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_STATFS_H /* Nonexistant future OS needs this */ #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_XATTR_H #include #endif #ifndef EXT3_SUPER_MAGIC #define EXT3_SUPER_MAGIC 0xEF53 #endif #ifndef JFS_SUPER_MAGIC #define JFS_SUPER_MAGIC 0x3153464a #endif #ifndef REISERFS_SUPER_MAGIC #define REISERFS_SUPER_MAGIC 0x52654973 #endif #ifndef XFS_SUPER_MAGIC #define XFS_SUPER_MAGIC 0x58465342 #endif #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__) struct _linuxattr_context{ const char *file; const char *attrname; xar_ea_t ea; void *buf; int off; int bufsz; }; #define LINUXATTR_CONTEXT(x) ((struct _linuxattr_context *)(x)) int32_t xar_linuxattr_read(xar_t x, xar_file_t f, void * buf, size_t len, void *context) { if( !LINUXATTR_CONTEXT(context)->buf ) { int r; LINUXATTR_CONTEXT(context)->bufsz = 1024; AGAIN2: LINUXATTR_CONTEXT(context)->buf = malloc(LINUXATTR_CONTEXT(context)->bufsz); if(!LINUXATTR_CONTEXT(context)->buf) goto AGAIN2; memset(LINUXATTR_CONTEXT(context)->buf, 0, LINUXATTR_CONTEXT(context)->bufsz); r = lgetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attrname, LINUXATTR_CONTEXT(context)->buf, LINUXATTR_CONTEXT(context)->bufsz); if( r < 0 ) { switch(errno) { case ERANGE: LINUXATTR_CONTEXT(context)->bufsz *= 2; free(LINUXATTR_CONTEXT(context)->buf); goto AGAIN2; case ENOTSUP: free(LINUXATTR_CONTEXT(context)->buf); return 0; default: break; }; return -1; } LINUXATTR_CONTEXT(context)->bufsz = r; } if( (LINUXATTR_CONTEXT(context)->bufsz-LINUXATTR_CONTEXT(context)->off) <= len ) { int32_t ret; ret = LINUXATTR_CONTEXT(context)->bufsz - LINUXATTR_CONTEXT(context)->off; memcpy(buf, ((char *)LINUXATTR_CONTEXT(context)->buf)+LINUXATTR_CONTEXT(context)->off, ret); LINUXATTR_CONTEXT(context)->off += ret; return(ret); } else { memcpy(buf, ((char *)LINUXATTR_CONTEXT(context)->buf)+LINUXATTR_CONTEXT(context)->off, len); LINUXATTR_CONTEXT(context)->buf = ((char *)LINUXATTR_CONTEXT(context)->buf) + len; return len; } } int32_t xar_linuxattr_write(xar_t x, xar_file_t f, void *buf, size_t len, void *context) { return lsetxattr(LINUXATTR_CONTEXT(context)->file, LINUXATTR_CONTEXT(context)->attrname, buf, len, 0); } #endif int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len) { #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LGETXATTR) && !defined(__APPLE__) char *i, *buf = NULL; int ret, retval=0, bufsz = 1024; struct statfs sfs; char *fsname = NULL; struct _linuxattr_context context; memset(&context,0,sizeof(struct _linuxattr_context)); /* data from buffers don't have linuxattr */ if(len) return 0; if( file == NULL ) return 0; if( !xar_check_prop(x, "ea") ) return 0; TRYAGAIN: buf = malloc(bufsz); if(!buf) goto TRYAGAIN; ret = llistxattr(file, buf, bufsz); if( ret < 0 ) { switch(errno) { case ERANGE: bufsz = bufsz*2; free(buf); goto TRYAGAIN; case ENOTSUP: retval = 0; goto BAIL; default: retval = -1; goto BAIL; }; } if( ret == 0 ) goto BAIL; memset(&sfs, 0, sizeof(sfs)); statfs(file, &sfs); switch(sfs.f_type) { case EXT3_SUPER_MAGIC: fsname = "ext3"; break; /* assume ext3 */ case JFS_SUPER_MAGIC: fsname = "jfs" ; break; case REISERFS_SUPER_MAGIC:fsname = "reiser" ; break; case XFS_SUPER_MAGIC: fsname = "xfs" ; break; default: retval=0; goto BAIL; }; for( i=buf; (i-buf) < ret; i += strlen(i)+1 ) { xar_ea_t e; context.bufsz = 0; context.off = 0; context.buf = NULL; context.file = file; e = xar_ea_new(f, i); xar_ea_pset(f, e, "fstype", fsname); context.attrname = i; context.ea = e; if (XAR(x)->attrcopy_to_heap(x, f, xar_ea_root(e), xar_linuxattr_read,&context) < 0) { retval = -1; goto BAIL; } free(context.buf); context.attrname = NULL; } BAIL: free(buf); return retval; #endif return 0; } int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #if defined HAVE_SYS_XATTR_H && defined(HAVE_LSETXATTR) && !defined(__APPLE__) const char *fsname = "bogus"; struct statfs sfs; int eaopt = 0; struct _linuxattr_context context; xar_prop_t p; memset(&context,0,sizeof(struct _linuxattr_context)); /* data buffers, can't store linux attrs */ if(len){ return 0; } /* Check for EA extraction behavior */ memset(&sfs, 0, sizeof(sfs)); if( statfs(file, &sfs) != 0 ) { char *tmp, *bname; tmp = strdup(file); bname = safe_dirname(tmp); statfs(bname, &sfs); free(tmp); free(bname); } switch(sfs.f_type) { case EXT3_SUPER_MAGIC: fsname = "ext3"; break; /* assume ext3 */ case JFS_SUPER_MAGIC: fsname = "jfs" ; break; case REISERFS_SUPER_MAGIC:fsname = "reiser" ; break; case XFS_SUPER_MAGIC: fsname = "xfs" ; break; }; for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { const char *fs = NULL; const char *prop; const char *eaname = NULL; xar_prop_t tmpp; prop = xar_prop_getkey(p); if( strncmp(prop, XAR_EA_FORK, strlen(XAR_EA_FORK)) != 0 ) continue; if( strlen(prop) != strlen(XAR_EA_FORK) ) continue; tmpp = xar_prop_pget(p, "fstype"); if( tmpp ) fs = xar_prop_getvalue(tmpp); if( !eaopt && fs && strcmp(fs, fsname) != 0 ) { continue; } if( !fs ) continue; tmpp = xar_prop_pget(p, "name"); if( tmpp ) eaname = xar_prop_getvalue(tmpp); context.file = file; context.attrname = eaname; if (XAR(x)->attrcopy_from_heap(x, f, p, xar_linuxattr_write, &context) < 0) return -1; } #endif return 0; } xar-xar-498/xar/lib/linuxattr.h000066400000000000000000000037341446633275300165510ustar00rootroot00000000000000/* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Rob Braun * 26-Oct-2004 * Copyright (c) 2004 Rob Braun. All rights reserved. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_LINUXATTR_H_ #define _XAR_LINUXATTR_H_ int32_t xar_linuxattr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len); int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len); #endif /* _XAR_LINUXATTR_H_ */ xar-xar-498/xar/lib/lzmaxar.c000066400000000000000000000255611446633275300161720ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 19-Sep-2007 * DRI: Anders F Bjorklund */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include #include #include #include #include #ifdef HAVE_LIBLZMA #include #endif #include "xar.h" #include "filetree.h" #include "io.h" #ifdef HAVE_LIBLZMA #ifndef UINT32_C #define UINT32_C(v) (v ## U) /* from normally */ #endif #ifndef LZMA_VERSION #define LZMA_VERSION UINT32_C(40420000) /* = 4.42.0alpha6 */ #endif struct _lzma_context{ uint8_t lzmacompressed; lzma_stream lzma; lzma_options_stream options; lzma_allocator allocator; #if LZMA_VERSION < 40420010U lzma_memory_limitter *limit; #else lzma_memlimit *limit; #endif }; #define preset_level 7 #define memory_limit 93*1024*1024 /* 1=1M, 5=24M, 6=39M, 7=93M, 8=185M, 9=369M */ #define LZMA_CONTEXT(x) ((struct _lzma_context *)(*x)) #endif int xar_lzma_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { #ifdef HAVE_LIBLZMA if( !context || !LZMA_CONTEXT(context) ) return 0; if( LZMA_CONTEXT(context)->lzmacompressed){ lzma_end(&LZMA_CONTEXT(context)->lzma); } /* free the context */ free(LZMA_CONTEXT(context)); *context = NULL; #endif return 0; } int xar_lzma_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { const char *opt; xar_prop_t tmpp; #ifdef HAVE_LIBLZMA void *out = NULL; size_t outlen, offset = 0; lzma_ret r; /* on first run, we init the context and check the compression type */ if( !LZMA_CONTEXT(context) ) { *context = calloc(1,sizeof(struct _lzma_context)); opt = NULL; tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) return 0; if( strcmp(opt, "application/x-lzma") != 0 ) return 0; lzma_init_decoder(); LZMA_CONTEXT(context)->lzma = LZMA_STREAM_INIT_VAR; r = lzma_stream_decoder(&LZMA_CONTEXT(context)->lzma, NULL, NULL); if( (r != LZMA_OK) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error decompressing file"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } LZMA_CONTEXT(context)->lzmacompressed = 1; }else if( !LZMA_CONTEXT(context)->lzmacompressed ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen; LZMA_CONTEXT(context)->lzma.next_in = *in; LZMA_CONTEXT(context)->lzma.avail_in = *inlen; LZMA_CONTEXT(context)->lzma.next_out = out; LZMA_CONTEXT(context)->lzma.avail_out = 0; while( LZMA_CONTEXT(context)->lzma.avail_in != 0 ) { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); LZMA_CONTEXT(context)->lzma.next_out = ((unsigned char *)out) + offset; LZMA_CONTEXT(context)->lzma.avail_out = outlen - offset; r = lzma_code(&(LZMA_CONTEXT(context)->lzma), LZMA_RUN); if( (r != LZMA_OK) && (r != LZMA_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_errno(x, r); xar_err_set_string(x, "Error decompressing file"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } offset += outlen - offset - LZMA_CONTEXT(context)->lzma.avail_out; if( (r == LZMA_STREAM_END) && (offset == 0) ) break; } free(*in); *in = out; *inlen = offset; #else opt = NULL; tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) return 0; if( strcmp(opt, "application/x-lzma") != 0 ) return 0; xar_err_new(x); xar_err_set_file(x, f); xar_err_set_errno(x, 0); xar_err_set_string(x, "lzma support not compiled in."); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); #endif /* HAVE_LIBLZMA */ return 0; } int xar_lzma_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { #ifdef HAVE_LIBLZMA xar_prop_t tmpp; if( LZMA_CONTEXT(context)->lzmacompressed){ lzma_end(&LZMA_CONTEXT(context)->lzma); #if LZMA_VERSION < 40420010U lzma_memory_limitter_end(LZMA_CONTEXT(context)->limit, 1); #else lzma_memlimit_end(LZMA_CONTEXT(context)->limit, 1); #endif tmpp = xar_prop_pset(f, p, "encoding", NULL); if( tmpp ) xar_attr_pset(f, tmpp, "style", "application/x-lzma"); } /* free the context */ free(LZMA_CONTEXT(context)); *context = NULL; #endif /* HAVE_LIBLZMA */ return 0; } int32_t xar_lzma_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { const char *opt; #ifdef HAVE_LIBLZMA void *out = NULL; size_t outlen, offset = 0; lzma_ret r; /* on first run, we init the context and check the compression type */ if( !LZMA_CONTEXT(context) ) { int level = preset_level; *context = calloc(1,sizeof(struct _lzma_context)); opt = xar_opt_get(x, XAR_OPT_COMPRESSION); if( !opt ) return 0; if( strcmp(opt, XAR_OPT_VAL_LZMA) != 0 ) return 0; opt = xar_opt_get(x, XAR_OPT_COMPRESSIONARG); if( opt ) { int tmp; errno = 0; tmp = strtol(opt, NULL, 10); if( errno == 0 ) { if( (level >= 0) && (level <= 9) ) level = tmp; } } lzma_init_encoder(); LZMA_CONTEXT(context)->options.check = LZMA_CHECK_CRC64; LZMA_CONTEXT(context)->options.has_crc32 = 1; /* true */ LZMA_CONTEXT(context)->options.alignment = 0; #if defined (__ppc__) || defined (powerpc) || defined (__ppc64__) LZMA_CONTEXT(context)->options.filters[0].id = LZMA_FILTER_POWERPC; #elif defined (__i386__) || defined (__amd64__) || defined(__x86_64__) LZMA_CONTEXT(context)->options.filters[0].id = LZMA_FILTER_X86; #else LZMA_CONTEXT(context)->options.filters[0].id = LZMA_FILTER_COPY; #endif LZMA_CONTEXT(context)->options.filters[0].options = NULL; LZMA_CONTEXT(context)->options.filters[1].id = LZMA_FILTER_LZMA; LZMA_CONTEXT(context)->options.filters[1].options = (lzma_options_lzma *)(lzma_preset_lzma + level - 1); /* Terminate the filter options array. */ LZMA_CONTEXT(context)->options.filters[2].id = UINT64_MAX; LZMA_CONTEXT(context)->lzma = LZMA_STREAM_INIT_VAR; #if LZMA_VERSION < 40420010U LZMA_CONTEXT(context)->limit = lzma_memory_limitter_create(memory_limit); LZMA_CONTEXT(context)->allocator.alloc = (void*) lzma_memory_alloc; LZMA_CONTEXT(context)->allocator.free = (void*) lzma_memory_free; #else LZMA_CONTEXT(context)->limit = lzma_memlimit_create(memory_limit); LZMA_CONTEXT(context)->allocator.alloc = (void*) lzma_memlimit_alloc; LZMA_CONTEXT(context)->allocator.free = (void*) lzma_memlimit_free; #endif LZMA_CONTEXT(context)->allocator.opaque = LZMA_CONTEXT(context)->limit; LZMA_CONTEXT(context)->lzma.allocator = &LZMA_CONTEXT(context)->allocator; r = lzma_stream_encoder_single(&LZMA_CONTEXT(context)->lzma, &(LZMA_CONTEXT(context)->options)); if( (r != LZMA_OK) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error compressing file"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } LZMA_CONTEXT(context)->lzmacompressed = 1; if( *inlen == 0 ) return 0; }else if( !LZMA_CONTEXT(context)->lzmacompressed ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen/2; if(outlen == 0) outlen = 1024; LZMA_CONTEXT(context)->lzma.next_in = *in; LZMA_CONTEXT(context)->lzma.avail_in = *inlen; LZMA_CONTEXT(context)->lzma.next_out = out; LZMA_CONTEXT(context)->lzma.avail_out = 0; if( *inlen != 0 ) { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ if( out == NULL ) abort(); LZMA_CONTEXT(context)->lzma.next_out = ((unsigned char *)out) + offset; LZMA_CONTEXT(context)->lzma.avail_out = outlen - offset; r = lzma_code(&LZMA_CONTEXT(context)->lzma, LZMA_RUN); offset = outlen - LZMA_CONTEXT(context)->lzma.avail_out; } while( r == LZMA_OK && LZMA_CONTEXT(context)->lzma.avail_in != 0); } else { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ if( out == NULL ) abort(); LZMA_CONTEXT(context)->lzma.next_out = ((unsigned char *)out) + offset; LZMA_CONTEXT(context)->lzma.avail_out = outlen - offset; r = lzma_code(&LZMA_CONTEXT(context)->lzma, LZMA_FINISH); offset = outlen - LZMA_CONTEXT(context)->lzma.avail_out; } while( r == LZMA_OK && r != LZMA_STREAM_END); } if( (r != LZMA_OK && r != LZMA_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error compressing file"); xar_err_set_errno(x, r); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } free(*in); *in = out; *inlen = offset; #else opt = xar_opt_get(x, XAR_OPT_COMPRESSION); if( !opt ) return 0; if( strcmp(opt, XAR_OPT_VAL_LZMA) != 0 ) return 0; xar_err_new(x); xar_err_set_file(x, f); xar_err_set_errno(x, 0); xar_err_set_string(x, "lzma support not compiled in."); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); #endif /* HAVE_LIBLZMA */ return 0; } xar-xar-498/xar/lib/lzmaxar.h000066400000000000000000000041071446633275300161700ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * * DRI: */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_LZMA_H_ #define _XAR_LZMA_H_ int xar_lzma_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_lzma_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); int32_t xar_lzma_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_lzma_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _XAR_LZMA_H_ */ xar-xar-498/xar/lib/macho.c000066400000000000000000000330411446633275300155730ustar00rootroot00000000000000/* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "macho.h" #include "util.h" #include "data.h" #include "arcmod.h" #include "xar.h" #define BIT64 0x01000000 #define PPC 0x00000012 #define I386 0x00000007 struct machexecutables { struct mach_header mh; struct lc *lc; uint32_t curlc; uint64_t nextlc; char **strings; uint32_t stringsz; uint8_t byteswapped; uint8_t bits; }; struct _macho_context{ struct fat_header fath; /* Need to read and buffer the fat header */ struct fat_arch *arches; /* Read and buffer array of arches */ uint32_t curarch; /* Current arch being parsed */ struct machexecutables *me; uint64_t nextme; /* Offset of the next mach header */ uint32_t curme; /* Current me being parsed */ unsigned char buffer[512]; /* Place to store incomplete struct info */ uint16_t buffersz; /* Keep track of how much of buffer is used*/ uint16_t state; /* Keep track of what we're looking for */ uint64_t curroffset; /* Current offset in file */ uint8_t byteswapped; /* Keep track of whether we're byteswapping*/ }; /* Looking for... */ enum { lf_fatheader = 0, lf_inc_fatheader, lf_archheader, lf_inc_archheader, lf_machheader, lf_inc_machheader, lf_loadcommand, lf_inc_loadcommand, lf_lcstr, lf_inc_lcstr, lf_none }; #define MACHO_CONTEXT(x) ((struct _macho_context *)(*x)) static const char *macho_cpustr(uint32_t cputype) { const char *cpustr; switch(cputype) { case PPC: cpustr = "ppc"; break; case I386: cpustr = "i386"; break; case PPC|BIT64: cpustr = "ppc64"; break; default: cpustr = "unknown"; break; }; return cpustr; } /* Returns number of bytes consumed during the parsing process */ static int32_t macho_parse(xar_file_t f, void *in, size_t inlen, struct _macho_context *context) { int32_t consumed = 0; switch( context->state ) { case(lf_fatheader): if( inlen >= sizeof(struct fat_header) ) { struct fat_header *fh = (struct fat_header *)in; if( fh->magic == 0xcafebabe ) { context->fath.magic = fh->magic; context->fath.nfat_arch = fh->nfat_arch; context->arches = calloc(1,sizeof(struct fat_arch) * fh->nfat_arch); context->me = calloc(1,sizeof(struct machexecutables) * fh->nfat_arch); context->state = lf_archheader; context->byteswapped = 0; context->curarch = 0; consumed = 8; xar_prop_set(f, "contents/type", "Mach-O Fat File"); } else if( fh->magic == 0xbebafeca ) { context->fath.magic = xar_swap32(fh->magic); context->fath.nfat_arch = xar_swap32(fh->nfat_arch); context->arches = calloc(1,sizeof(struct fat_arch) * context->fath.nfat_arch); context->me = calloc(1,sizeof(struct machexecutables) * context->fath.nfat_arch); context->state = lf_archheader; context->byteswapped = 1; context->curarch = 0; consumed = 8; xar_prop_set(f, "contents/type", "Mach-O Fat File"); } else { context->me = calloc(1,sizeof(struct machexecutables)); context->curme = 0; context->state = lf_machheader; } } else { uint32_t *tmp = in; if( (*tmp == 0xcafebabe) || (*tmp == 0xbebafeca) ) { memcpy(context->buffer, in, inlen); context->buffersz = inlen; consumed = (int32_t)inlen; context->state = lf_inc_fatheader; } else { context->me = calloc(1,sizeof(struct machexecutables)); context->curme = 0; context->state = lf_machheader; } } break; case lf_archheader: if( inlen >= sizeof(struct fat_arch) ) { struct fat_arch *fa = in; if( context->byteswapped ) { context->arches[context->curarch].cputype = xar_swap32(fa->cputype); context->arches[context->curarch].cpusubtype = xar_swap32(fa->cpusubtype); context->arches[context->curarch].offset = xar_swap32(fa->offset); context->arches[context->curarch].size = xar_swap32(fa->size); context->arches[context->curarch].alighn = xar_swap32(fa->alighn); } else { memcpy(&context->arches[context->curarch], in, sizeof(struct fat_arch)); } context->curarch++; if( context->curarch >=context->fath.nfat_arch ) { context->nextme = context->arches[0].offset; context->state = lf_machheader; } consumed = sizeof(struct fat_arch); } else { memcpy(context->buffer, in, inlen); context->buffersz = inlen; consumed = (int32_t)inlen; context->state = lf_inc_archheader; } break; case lf_machheader: if( (context->curroffset+inlen) <= context->nextme ) consumed = inlen; else { uint64_t off; unsigned char *tmpin = in; off = context->nextme - context->curroffset; tmpin += off; if( (inlen-off) >= sizeof(struct mach_header) ) { const char *cpustr; char *typestr, *typestr2; struct mach_header *mh = (struct mach_header *)tmpin; switch(mh->magic) { case 0xcffaedfe: context->me[context->curme].bits = 64; context->me[context->curme].byteswapped = 1; break; case 0xcefaedfe: context->me[context->curme].bits = 32; context->me[context->curme].byteswapped = 1; break; case 0xfeedface: context->me[context->curme].bits = 32; break; case 0xfeedfacf: context->me[context->curme].bits = 64; break; default: context->state = lf_none; return inlen; }; if( context->me[context->curme].byteswapped ) { context->me[context->curme].mh.magic = xar_swap32(mh->magic); context->me[context->curme].mh.cputype = xar_swap32(mh->cputype); context->me[context->curme].mh.cpusubtype = xar_swap32(mh->cpusubtype); context->me[context->curme].mh.filetype = xar_swap32(mh->filetype); context->me[context->curme].mh.ncmds = xar_swap32(mh->ncmds); context->me[context->curme].mh.sizeofcmds = xar_swap32(mh->sizeofcmds); context->me[context->curme].mh.flags = xar_swap32(mh->flags); } else { memcpy(&context->me[context->curme].mh, tmpin, sizeof(struct mach_header)); } cpustr = macho_cpustr(context->me[context->curme].mh.cputype); switch(context->me[context->curme].mh.filetype) { case 0x01: typestr = "Mach-O Object"; break; case 0x02: typestr = "Mach-O Executable"; break; case 0x03: typestr = "Mach-O Fixed VM Library"; break; case 0x04: typestr = "Mach-O core"; break; case 0x05: typestr = "Mach-O Preloaded Executable"; break; case 0x06: typestr = "Mach-O Dylib"; break; case 0x07: typestr = "Mach-O Dylinker"; break; case 0x08: typestr = "Mach-O Bundle"; break; case 0x09: typestr = "Mach-O Stub"; break; default: typestr = "Unknown"; break; }; if( xar_prop_get(f, "contents/type", (const char **)&typestr2) ) { xar_prop_set(f, "contents/type", typestr); } asprintf(&typestr2, "contents/%s/type", cpustr); xar_prop_set(f, typestr2, typestr); free(typestr2); context->me[context->curme].lc = malloc(sizeof(struct lc) * context->me[context->curme].mh.ncmds); context->me[context->curme].strings = malloc(sizeof(char *) * context->me[context->curme].mh.ncmds); context->me[context->curme].curlc = 0; consumed = off + sizeof(struct mach_header); if( context->me[context->curme].bits == 64 ) consumed += 4; context->me[context->curme].nextlc = context->curroffset + consumed; context->state = lf_loadcommand; } else { memcpy(context->buffer, tmpin, inlen-off); context->buffersz = inlen-off; consumed = (int32_t)inlen; context->state = lf_inc_machheader; } } break; case lf_loadcommand: if( (context->curroffset+inlen) <= context->me[context->curme].nextlc ) consumed = inlen; else { uint64_t off; unsigned char *tmpin = in; off = context->me[context->curme].nextlc - context->curroffset; tmpin += off; if( (inlen-off) >= sizeof(struct lc) ) { if( context->me[context->curme].byteswapped ) { struct lc *lc = (struct lc *)tmpin; context->me[context->curme].lc[context->me[context->curme].curlc].cmd = xar_swap32(lc->cmd); context->me[context->curme].lc[context->me[context->curme].curlc].cmdsize = xar_swap32(lc->cmdsize); } else { memcpy(&context->me[context->curme].lc[context->me[context->curme].curlc], tmpin, sizeof(struct lc)); } consumed = off + sizeof(struct lc); context->me[context->curme].nextlc += context->me[context->curme].lc[context->me[context->curme].curlc].cmdsize; if( (context->me[context->curme].lc[context->me[context->curme].curlc].cmd == 0xc) || (context->me[context->curme].lc[context->me[context->curme].curlc].cmd == 0xd) ) { context->state = lf_lcstr; } else { context->me[context->curme].curlc++; if( context->me[context->curme].curlc >= context->me[context->curme].mh.ncmds ) { context->curme++; if( context->fath.nfat_arch ) { if( context->curme >= context->fath.nfat_arch ) { context->state = lf_none; } else { context->nextme = context->arches[context->curme].offset; context->state = lf_machheader; } } else { context->state = lf_none; } } } } else { memcpy(context->buffer, ((char *)in)+off, inlen-off); context->buffersz = inlen-off; consumed = inlen; context->state = lf_inc_loadcommand; } } break; case lf_lcstr: if( inlen >= (context->me[context->curme].lc[context->me[context->curme].curlc].cmdsize-8) ) { const char *tmpstr; uint32_t cmdsize = context->me[context->curme].lc[context->me[context->curme].curlc].cmdsize; uint32_t *offsetp, offset; char *lib, *propstr; offsetp = in; if( context->me[context->curme].byteswapped ) offset = xar_swap32(*offsetp); else offset = *offsetp; lib = calloc(1,(cmdsize - offset)+1); memcpy(lib, ((char *)in)+(offset - 8), cmdsize - offset); tmpstr = macho_cpustr(context->me[context->curme].mh.cputype); asprintf(&propstr, "contents/%s/library", tmpstr); xar_prop_create(f, propstr, lib); free(lib); free(propstr); consumed = cmdsize-8; context->state = lf_loadcommand; context->me[context->curme].curlc++; if( context->me[context->curme].curlc >= context->me[context->curme].mh.ncmds ) { context->curme++; if( context->fath.nfat_arch ) { if( context->curme >= context->fath.nfat_arch ) { context->state = lf_none; } else { context->nextme = context->arches[context->curme].offset; context->state = lf_machheader; } } else { context->state = lf_none; } } } else { memcpy(context->buffer, in, inlen); context->buffersz = inlen; consumed = inlen; context->state = lf_inc_lcstr; } break; case lf_none: default: consumed = inlen; break; }; return consumed; } int32_t xar_macho_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { int32_t consumed = 0, total = 0; if( strcmp(xar_prop_getkey(p), "data") != 0 ) return 0; if( !xar_check_prop(x, "contents") ) return 0; if( !*context ) { *context = calloc(1,sizeof(struct _macho_context)); } while( total < *inlen ) { consumed = macho_parse(f, ((char *)*in)+total, *inlen-total, MACHO_CONTEXT(context)); total += consumed; MACHO_CONTEXT(context)->curroffset += consumed; } return 0; } int32_t xar_macho_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { if( MACHO_CONTEXT(context) ){ int i; if( MACHO_CONTEXT(context)->fath.nfat_arch ) { for(i = 0; i < MACHO_CONTEXT(context)->fath.nfat_arch; i++) { if( MACHO_CONTEXT(context)->me[i].lc ) free(MACHO_CONTEXT(context)->me[i].lc); if( MACHO_CONTEXT(context)->me[i].strings ) free(MACHO_CONTEXT(context)->me[i].strings); } } else { if( MACHO_CONTEXT(context)->me ) { if( MACHO_CONTEXT(context)->me[0].lc ) free(MACHO_CONTEXT(context)->me[0].lc); if( MACHO_CONTEXT(context)->me[0].strings ) free(MACHO_CONTEXT(context)->me[0].strings); } } if( MACHO_CONTEXT(context)->me ) free(MACHO_CONTEXT(context)->me); if( MACHO_CONTEXT(context)->arches ) free(MACHO_CONTEXT(context)->arches); free(*context); } return 0; } xar-xar-498/xar/lib/macho.h000066400000000000000000000043671446633275300156110ustar00rootroot00000000000000/* All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _MACHO_H_ #define _MACHO_H_ #include "xar.h" #include "filetree.h" struct mach_header { uint32_t magic; uint32_t cputype; uint32_t cpusubtype; uint32_t filetype; uint32_t ncmds; uint32_t sizeofcmds; uint32_t flags; }; struct lc { uint32_t cmd; uint32_t cmdsize; }; struct fat_header { uint32_t magic; uint32_t nfat_arch; }; struct fat_arch { uint32_t cputype; uint32_t cpusubtype; uint32_t offset; uint32_t size; uint32_t alighn; }; int32_t xar_macho_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int32_t xar_macho_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _MACHO_H_ */ xar-xar-498/xar/lib/script.c000066400000000000000000000062101446633275300160060ustar00rootroot00000000000000/* * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include #include #include #include #include #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "filetree.h" #include "arcmod.h" struct _script_context{ int initted; }; #define SCRIPT_CONTEXT(x) ((struct _script_context*)(*x)) int32_t xar_script_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { char *buf = *in; xar_prop_t tmpp; if(!SCRIPT_CONTEXT(context)){ *context = calloc(1,sizeof(struct _script_context)); } if( SCRIPT_CONTEXT(context)->initted ) return 0; if( !xar_check_prop(x, "contents") ) return 0; /* Sanity check *inlen, which really shouldn't be more than a * few kbytes... */ if( *inlen > INT_MAX ) return 0; /*We only run on the begining of the file, so once we init, we don't run again*/ SCRIPT_CONTEXT(context)->initted = 1; if( (*inlen > 2) && (buf[0] == '#') && (buf[1] == '!') ) { char *exe; int i; exe = malloc(*inlen); if( !exe ) return -1; memset(exe, 0, *inlen); for(i = 2; (i < *inlen) && (buf[i] != '\0') && (buf[i] != '\n') && (buf[i] != ' '); ++i) { exe[i-2] = buf[i]; } tmpp = xar_prop_pset(f, p, "contents", NULL); if( tmpp ) { xar_prop_pset(f, tmpp, "type", "script"); xar_prop_pset(f, tmpp, "interpreter", exe); } free(exe); } return 0; } int32_t xar_script_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { if(!SCRIPT_CONTEXT(context)){ return 0; } if( *context ){ free(*context); *context = NULL; } return 0; } xar-xar-498/xar/lib/script.h000066400000000000000000000035101446633275300160130ustar00rootroot00000000000000/* * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _SCRIPT_H_ #define _SCRIPT_H_ int32_t xar_script_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int32_t xar_script_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _SCRIPT_H_ */ xar-xar-498/xar/lib/signature.c000066400000000000000000000400641446633275300165100ustar00rootroot00000000000000/* * Copyright (c) 2006 Apple Computer, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 6-July-2006 * DRI: Christopher Ryan */ #include #include #include #include #include #include /* for PRIu64 */ #include #include "xar.h" #include "archive.h" #include "b64.h" #include "signature.h" struct _signature_copy_context{ void *buffer; size_t length; off_t offset; }; #ifdef __APPLE__ xar_signature_t xar_signature_new_internal(xar_t x, int is_extended, const char *type, int32_t length, xar_signer_callback callback, void *callback_context) #else xar_signature_t xar_signature_new(xar_t x,const char *type, int32_t length, xar_signer_callback callback, void *callback_context) #endif { xar_signature_t ret; if( XAR(x)->files ){ xar_err_new(x); xar_err_set_string(x, "Signatures must be added before files are added"); xar_err_callback(x, XAR_SEVERITY_WARNING, XAR_ERR_ARCHIVE_CREATION); return NULL; } ret = malloc(sizeof(struct __xar_signature_t)); if( ! ret ) return NULL; memset(XAR_SIGNATURE(ret), 0, sizeof(struct __xar_signature_t)); XAR_SIGNATURE(ret)->type = strdup(type); XAR_SIGNATURE(ret)->len = length; XAR_SIGNATURE(ret)->offset = XAR(x)->heap_offset; XAR_SIGNATURE(ret)->signer_callback = callback; XAR_SIGNATURE(ret)->callback_context = callback_context; #ifdef __APPLE__ XAR_SIGNATURE(ret)->is_extended = is_extended; #endif /* Pre allocate space in the heap */ XAR(x)->heap_offset += length; XAR(x)->heap_len += length; // Put the new on at the end of the list if( XAR_SIGNATURE(XAR(x)->signatures) ) { struct __xar_signature_t *sig; // (Apple) Find the end of the signatures list // The open source code seems to smash list items 1 through n when the head of this list is already defined // despite the fact that the xar signatures are implemented as a list. This is an Apple xar 1.4 edit // to allow that list to grow beyond 2 for( sig = XAR_SIGNATURE(XAR(x)->signatures); sig->next; sig = sig->next); sig->next = XAR_SIGNATURE(ret); } else XAR(x)->signatures = ret; XAR_SIGNATURE(ret)->x = x; return ret; } #ifdef __APPLE__ xar_signature_t xar_signature_new(xar_t x,const char *type, int32_t length, xar_signer_callback callback, void *callback_context) { return xar_signature_new_internal(x, 0, type, length, callback, callback_context); } #endif xar_signature_t xar_signature_new_extended(xar_t x,const char *type, int32_t length, xar_signer_callback callback, void *callback_context) { #ifdef __APPLE__ return xar_signature_new_internal(x, 1, type, length, callback, callback_context); #else return xar_signature_new(x, type, length, callback, callback_context); #endif } const char *xar_signature_type(xar_signature_t s) { if( !s ) return NULL; return XAR_SIGNATURE(s)->type; } /* Add x509 cert data to this signature */ int32_t xar_signature_add_x509certificate(xar_signature_t sig, const uint8_t *cert_data, uint32_t cert_len ) { struct __xar_x509cert_t *newcert; if( !sig ) return -1; newcert = malloc(sizeof(struct __xar_x509cert_t)); memset(newcert, 0, sizeof(struct __xar_x509cert_t)); newcert->content = malloc(sizeof(const char)*cert_len); memcpy(newcert->content,cert_data,cert_len); newcert->len = cert_len; if( XAR_SIGNATURE(sig)->x509certs ){ struct __xar_x509cert_t *cert; // Find the end of the linked list for( cert = XAR_SIGNATURE(sig)->x509certs; cert->next; cert = cert->next ); cert->next = newcert; }else{ XAR_SIGNATURE(sig)->x509certs = newcert; } XAR_SIGNATURE(sig)->x509cert_count++; return 0; } int32_t xar_signature_get_x509certificate_count(xar_signature_t sig) { if( !sig ){ return 0; } return XAR_SIGNATURE(sig)->x509cert_count; } int32_t xar_signature_get_x509certificate_data(xar_signature_t sig, int32_t index, const uint8_t **cert_data, uint32_t *cert_len) { struct __xar_x509cert_t *cert; int i = 0; /* If there are no certs to return, return immediatly */ if( !XAR_SIGNATURE(sig)->x509cert_count ){ if( cert_data ) *cert_data = 0; return -1; } /* Loop through the certs, copying each one's string ptr to the array */ for( cert = XAR_SIGNATURE(sig)->x509certs; cert; cert = cert->next ){ if( i == index ){ if( cert_data ) *cert_data = cert->content; if( cert_len ) *cert_len = cert->len; break; } i++; } /* If the cert iterator is still valid, we did not find the proper index */ if( !cert ){ return -1; } return 0; } xar_signature_t xar_signature_first(xar_t x) { return XAR(x)->signatures; } xar_signature_t xar_signature_next(xar_signature_t s) { return XAR_SIGNATURE(s)->next; } int32_t _xar_signature_read_from_heap(xar_t x ,off_t offset,size_t length,uint8_t *data) { off_t seek_off = XAR(x)->toc_count + sizeof(xar_header_t) + offset; int r = 0; r = lseek(XAR(x)->fd, seek_off, SEEK_SET); /* can't seek to the proper location */ if( -1 == r ){ xar_err_new(x); xar_err_set_string(x, "Unable to seek"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } r = read(XAR(x)->fd,data,length); if( r != length ){ xar_err_new(x); xar_err_set_string(x, "Unable to read"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } return 0; } /* This method retrieves the signed data for this segment as well as the data the signed data is signing */ uint8_t xar_signature_copy_signed_data(xar_signature_t sig, uint8_t **data, uint32_t *length, uint8_t **signed_data, uint32_t *signed_length, off_t *signed_offset) { uint64_t offset = 0; xar_t x = NULL; const char *value; // xar 1.6 fails this method if any of data, length, signed_data, signed_length are NULL // within OS X we use this method to get combinations of signature, signed data, or signed_offset, // so this method checks and sets these out values independently if( !sig ) return -1; x = XAR_SIGNATURE(sig)->x; /* Get the checksum, to be used for signing. If we support multiple checksums in the future, all checksums should be retrieved */ if(length) { if(0 == xar_prop_get_expect_notnull( XAR_FILE(x) , "checksum/size", &value)){ *length = strtoull( value, (char **)NULL, 10); } if(0 == xar_prop_get_expect_notnull( XAR_FILE(x) , "checksum/offset", &value)){ offset = strtoull( value, (char **)NULL, 10); } if(data) { *data = malloc(sizeof(char)*(*length)); // This function will either read all of length or return -1. Check and bubble up. if (_xar_signature_read_from_heap(x, offset, *length, *data) != 0) return -1; } } /* read signature data */ offset = XAR_SIGNATURE(sig)->offset; // This parameter is an Apple edit // This out value is ignored OS X in SL, but this method prototype is included in the 10.5 SDK if( signed_offset ) *signed_offset = offset; if(signed_length) { *signed_length = XAR_SIGNATURE(sig)->len; if(signed_data) { *signed_data = malloc(sizeof(char)*(*signed_length)); // This function will either read all of length or return -1. Check and bubble up. if (_xar_signature_read_from_heap(x, offset, *signed_length, *signed_data) != 0) return -1; } } return 0; } xar_signature_t xar_signature_unserialize(xar_t x, xmlTextReaderPtr reader) { struct __xar_signature_t *ret = NULL; #ifdef __APPLE__ const xmlChar *sig_type = NULL; #endif const xmlChar *value = NULL; const xmlChar *name = NULL; int type; size_t outputLength = 0; ret = malloc(sizeof(struct __xar_signature_t)); if( ! ret ) return NULL; memset(ret, 0, sizeof(struct __xar_signature_t)); ret->x = x; /* Read One Signature Element */ #ifdef __APPLE__ sig_type = xmlTextReaderConstLocalName(reader); if(strcmp((const char*)sig_type, "x-signature") == 0) { ret->is_extended = 1; } #endif /* Retrieve the type attr */ value = xmlTextReaderGetAttribute(reader, (const xmlChar*)"style"); if( value ){ ret->type = strdup((const char *)value); } /* Look for the rest of the child elements */ while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); name = xmlTextReaderConstLocalName(reader); if (value) { xmlFree((void*)value); value = NULL; } if (!name) { /* archive corruption */ free(ret); return NULL; } if (!ret) { /* archive corruption */ return NULL; } if( type == XML_READER_TYPE_ELEMENT ) { if(strcmp((const char*)name, "size") == 0) { while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); if( type == XML_READER_TYPE_TEXT ) { value = xmlTextReaderConstValue(reader); ret->len = strtoull( (const char *)value, (char **)NULL, 10); value = NULL; /* We don't want to accidentally release this const. */ }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } } else if( strcmp((const char*)name, "offset") == 0 ){ while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); if( type == XML_READER_TYPE_TEXT ) { value = xmlTextReaderConstValue(reader); ret->offset = strtoull( (const char *)value, (char **)NULL, 10); value = NULL; /* We don't want to accidentally release this const. */ }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } } else if( strcmp((const char*)name, "KeyInfo") == 0 ){ while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); name = xmlTextReaderConstLocalName(reader); if( type == XML_READER_TYPE_ELEMENT ) { if(strcmp((const char*)name, "X509Data") == 0) { while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); name = xmlTextReaderConstLocalName(reader); if( type == XML_READER_TYPE_ELEMENT ) { if(strcmp((const char*)name, "X509Certificate") == 0) { while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); if( type == XML_READER_TYPE_TEXT ) { unsigned char *sig_data = NULL; value = xmlTextReaderConstValue(reader); /* this method allocates the resulting data */ sig_data = xar_from_base64(value, strlen((const char *)value), &outputLength); if(sig_data){ /* for convience we just use the same method, which means multiple allocations */ xar_signature_add_x509certificate(ret, sig_data, outputLength); free(sig_data); }else{ free(ret); ret = NULL; } value = NULL; /* We don't want to accidentally release this const. */ //break; }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } } }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } } }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } } }else if( type == XML_READER_TYPE_TEXT ) { value = xmlTextReaderConstValue(reader); value = NULL; /* We don't want to accidentally release this const. */ break; }else if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } if (value) { xmlFree((void*)value); value = NULL; } return ret; } /* 20 256 MIICXTCCA...base64... */ /* This function will serialize an entire list of signatures */ int32_t xar_signature_serialize(xar_signature_t sig, xmlTextWriterPtr writer) { if( !sig ) return 0; /* */ #ifdef __APPLE__ const char* element_name = XAR_SIGNATURE(sig)->is_extended ? "x-signature" : "signature"; xmlTextWriterStartElementNS( writer, NULL, BAD_CAST(element_name), NULL); #else xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("signature"), NULL); #endif /* write out the style */ xmlTextWriterWriteAttribute(writer, BAD_CAST("style"), BAD_CAST(XAR_SIGNATURE(sig)->type)); /* */ xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("offset"), NULL); xmlTextWriterWriteFormatString(writer, "%"PRIu64, (uint64_t)(XAR_SIGNATURE(sig)->offset)); xmlTextWriterEndElement(writer); /* */ xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("size"), NULL); xmlTextWriterWriteFormatString(writer, "%d", (XAR_SIGNATURE(sig)->len)); xmlTextWriterEndElement(writer); /* */ xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("KeyInfo"), NULL); xmlTextWriterWriteAttribute(writer, BAD_CAST("xmlns"), BAD_CAST("http://www.w3.org/2000/09/xmldsig#")); /* If we have x509 certs, write them out */ if( XAR_SIGNATURE(sig)->x509certs ){ struct __xar_x509cert_t *cert; /* */ xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("X509Data"), NULL); /* Loop through the certs, copying each one's string ptr to the array */ for( cert = XAR_SIGNATURE(sig)->x509certs; cert; cert = cert->next ){ xmlTextWriterStartElementNS( writer, NULL, BAD_CAST("X509Certificate"), NULL); xmlTextWriterWriteBase64( writer, (const char *)cert->content, 0, cert->len); xmlTextWriterEndElement(writer); } /* */ xmlTextWriterEndElement(writer); } /* */ xmlTextWriterEndElement(writer); /* */ xmlTextWriterEndElement(writer); /* serialize the next signature */ if( XAR_SIGNATURE(sig)->next ) xar_signature_serialize(XAR_SIGNATURE(sig)->next,writer); return 0; } void _xar_signature_remove_cert(struct __xar_x509cert_t *cert) { struct __xar_x509cert_t *next; if( !cert ) return; next = cert->next; if( cert->content ) free(cert->content); free(cert); _xar_signature_remove_cert(next); return; } void xar_signature_remove(xar_signature_t sig) { xar_signature_t next; if( !sig ) return; next = XAR_SIGNATURE(sig)->next; if( XAR_SIGNATURE(sig)->type ) free(XAR_SIGNATURE(sig)->type); if( XAR_SIGNATURE(sig)->x509cert_count ){ _xar_signature_remove_cert(XAR_SIGNATURE(sig)->x509certs); } free(XAR_SIGNATURE(sig)); /* remove the next one in the list */ xar_signature_remove(next); return; } xar-xar-498/xar/lib/signature.h000066400000000000000000000051641446633275300165170ustar00rootroot00000000000000/* * Copyright (c) 2006 Apple Computer, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 6-July-2006 * DRI: Christopher Ryan */ #ifndef _XAR_SIGNATURE_H_ #define _XAR_SIGNATURE_H_ #include "xar.h" struct __xar_x509cert_t{ uint8_t *content; int32_t len; struct __xar_x509cert_t *next; }; struct __xar_signature_t { char *type; int32_t len; off_t offset; int32_t x509cert_count; struct __xar_x509cert_t *x509certs; struct __xar_signature_t *next; xar_signer_callback signer_callback; /* callback for signing */ void *callback_context; /* context for callback */ xar_t x; #ifdef __APPLE__ int is_extended; #endif }; #define XAR_SIGNATURE(x) ((struct __xar_signature_t *)(x)) #ifdef __APPLE__ xar_signature_t xar_signature_new_internal(xar_t x, int is_extended, const char *type, int32_t length, xar_signer_callback callback, void *callback_context); #endif int32_t xar_signature_serialize(xar_signature_t sig, xmlTextWriterPtr writer); xar_signature_t xar_signature_unserialize(xar_t x, xmlTextReaderPtr reader); /* deallocates the link list of xar signatures */ void xar_signature_remove(xar_signature_t sig); #endif /* _XAR_SIGNATURE_H_ */ xar-xar-498/xar/lib/stat.c000066400000000000000000000501211446633275300154550ustar00rootroot00000000000000/* * Copyright (c) 2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2003, Apple Computer, Inc. * filetype_name() and associated structure. * DRI: Kevin Van Vechten */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #define _FILE_OFFSET_BITS 64 #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_ACL_H #include #endif #include "xar.h" #include "arcmod.h" #include "archive.h" #include "util.h" #ifndef LLONG_MIN #define LLONG_MIN LONG_LONG_MIN #endif #ifndef LLONG_MAX #define LLONG_MAX LONG_LONG_MAX #endif static struct { const char *name; mode_t type; } filetypes [] = { { "file", S_IFREG }, { "directory", S_IFDIR }, { "symlink", S_IFLNK }, { "fifo", S_IFIFO }, { "character special", S_IFCHR }, { "block special", S_IFBLK }, { "socket", S_IFSOCK }, #ifdef S_IFWHT { "whiteout", S_IFWHT }, #endif { NULL, 0 } }; static const char * filetype_name (mode_t mode) { unsigned int i; for (i = 0; filetypes[i].name; i++) if (mode == filetypes[i].type) return (filetypes[i].name); return ("unknown"); } static xar_file_t xar_link_lookup(xar_t x, dev_t dev, ino_t ino, xar_file_t f) { char key[32]; xar_file_t ret; memset(key, 0, sizeof(key)); snprintf(key, sizeof(key)-1, "%08" DEV_HEXSTRING "%08" INO_HEXSTRING, DEV_CAST dev, INO_CAST ino); ret = xmlHashLookup(XAR(x)->ino_hash, BAD_CAST(key)); if( ret == NULL ) { xmlHashAddEntry(XAR(x)->ino_hash, BAD_CAST(key), XAR_FILE(f)); return NULL; } return ret; } static int32_t aacls(xar_t x, xar_file_t f, const char *file) { #ifdef HAVE_SYS_ACL_H #if !defined(__APPLE__) acl_t a; const char *type; xar_prop_get(f, "type", &type); if( !type || (strcmp(type, "symlink") == 0) ) return 0; if( !xar_check_prop(x, "acl") ) return 0; a = acl_get_file(file, ACL_TYPE_DEFAULT); if( a ) { char *t; acl_entry_t e; /* If the acl is empty, or not valid, skip it */ if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 ) goto NEXT; t = acl_to_text(a, NULL); if( t ) { xar_prop_set(f, "acl/default", t); acl_free(t); } acl_free(a); } NEXT: a = acl_get_file(file, ACL_TYPE_ACCESS); if( a ) { char *t; acl_entry_t e; /* If the acl is empty, or not valid, skip it */ if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 ) goto DONE; t = acl_to_text(a, NULL); if( t ) { xar_prop_set(f, "acl/access", t); acl_free(t); } acl_free(a); } DONE: #else /* !__APPLE__ */ acl_entry_t e = NULL; acl_t a; int i; if( !xar_check_prop(x, "acl") ) return 0; a = acl_get_file(file, ACL_TYPE_EXTENDED); if( !a ) return 0; for( i = 0; acl_get_entry(a, e == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, &e) == 0; i++ ) { char *t; t = acl_to_text(a, NULL); if( t ) { xar_prop_set(f, "acl/appleextended", t); acl_free(t); } } acl_free(a); #endif /* !__APPLE__ */ #endif return 0; } static int32_t eacls(xar_t x, xar_file_t f, const char *file) { #ifdef HAVE_SYS_ACL_H #if !defined(__APPLE__) const char *t; acl_t a; const char *type; xar_prop_get(f, "type", &type); if( !type || (strcmp(type, "symlink") == 0) ) return 0; xar_prop_get(f, "acl/default", &t); if( t ) { a = acl_from_text(t); if( !a ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error extracting default acl from toc"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } else { if( acl_set_file(file, ACL_TYPE_DEFAULT, a) != 0 ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error setting default acl"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } } } xar_prop_get(f, "acl/access", &t); if( t ) { a = acl_from_text(t); if( !a ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error extracting access acl from toc"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } else { if( acl_set_file(file, ACL_TYPE_ACCESS, a) != 0 ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error setting access acl"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } acl_free(a); } } #else /* !__APPLE__ */ const char *t; acl_t a; xar_prop_get(f, "acl/appleextended", &t); if( t ) { a = acl_from_text(t); if( !a ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error extracting access acl from toc"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } else { if( acl_set_file(file, ACL_TYPE_ACCESS, a) != 0 ) { xar_err_new(x); xar_err_set_errno(x, errno); xar_err_set_string(x, "Error setting access acl"); xar_err_set_file(x, f); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } acl_free(a); } } #endif /* !__APPLE__ */ #endif return 0; } #ifdef HAVE_STRUCT_STAT_ST_FLAGS #define XAR_FLAG_FORK "flags" static void x_addflag(xar_file_t f, const char *name) { char opt[1024]; memset(opt, 0, sizeof(opt)); snprintf(opt, sizeof(opt)-1, "%s/%s", XAR_FLAG_FORK, name); xar_prop_set(f, opt, NULL); return; } #endif static int32_t flags_archive(xar_t x, xar_file_t f, const struct stat *sb) { #ifdef HAVE_STRUCT_STAT_ST_FLAGS if( !sb->st_flags ) return 0; if( !xar_check_prop(x, XAR_FLAG_FORK) ) return 0; #ifdef UF_NODUMP if( sb->st_flags & UF_NODUMP ) x_addflag(f, "UserNoDump"); #endif #ifdef UF_IMMUTABLE if( sb->st_flags & UF_IMMUTABLE ) x_addflag(f, "UserImmutable"); #endif #ifdef UF_APPEND if( sb->st_flags & UF_APPEND ) x_addflag(f, "UserAppend"); #endif #ifdef UF_OPAQUE if( sb->st_flags & UF_OPAQUE ) x_addflag(f, "UserOpaque"); #endif #ifdef SF_ARCHIVED if( sb->st_flags & SF_ARCHIVED ) x_addflag(f, "SystemArchived"); #endif #ifdef SF_IMMUTABLE if( sb->st_flags & SF_IMMUTABLE ) x_addflag(f, "SystemImmutable"); #endif #ifdef SF_APPEND if( sb->st_flags & SF_APPEND ) x_addflag(f, "SystemAppend"); #endif #endif /* HAVE_STRUCT_STAT_ST_FLAGS */ return 0; } #ifdef HAVE_CHFLAGS static int32_t x_getprop(xar_file_t f, const char *name, char **value) { char v[1024]; memset(v, 0, sizeof(v)); snprintf(v, sizeof(v)-1, "%s/%s", XAR_FLAG_FORK, name); return xar_prop_get(f, v, (const char **)value); } #endif int32_t xar_flags_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { #ifdef HAVE_CHFLAGS char *tmp; u_int flags = 0; if( xar_prop_get(f, XAR_FLAG_FORK, NULL) ) return 0; #ifdef UF_NODUMP if( x_getprop(f, "UserNoDump", (char **)&tmp) == 0 ) flags |= UF_NODUMP; #endif #ifdef UF_IMMUTABLE if( x_getprop(f, "UserImmutable", (char **)&tmp) == 0 ) flags |= UF_IMMUTABLE; #endif #ifdef UF_APPEND if( x_getprop(f, "UserAppend", (char **)&tmp) == 0 ) flags |= UF_APPEND; #endif #ifdef UF_OPAQUE if( x_getprop(f, "UserOpaque", (char **)&tmp) == 0 ) flags |= UF_OPAQUE; #endif #ifdef SF_ARCHIVED if( x_getprop(f, "SystemArchived", (char **)&tmp) == 0 ) flags |= SF_ARCHIVED; #endif #ifdef SF_IMMUTABLE if( x_getprop(f, "SystemImmutable", (char **)&tmp) == 0 ) flags |= SF_IMMUTABLE; #endif #ifdef SF_APPEND if( x_getprop(f, "SystemAppend", (char **)&tmp) == 0 ) flags |= SF_APPEND; #endif if( !flags ) return 0; if( chflags(file, flags) != 0 ) { char e[1024]; memset(e, 0, sizeof(e)); snprintf(e, sizeof(e)-1, "chflags: %s", strerror(errno)); xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, e); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } #endif return 0; } int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) { char *tmpstr; struct passwd *pw; struct group *gr; char time[128]; struct tm t; const char *type; /* no stat attributes for data from a buffer, it is just a file */ if(len){ if( xar_check_prop(x, "type") ) xar_prop_set(f, "type", "file"); return 0; } if( S_ISREG(XAR(x)->sbcache.st_mode) && (XAR(x)->sbcache.st_nlink > 1) ) { xar_file_t tmpf; const char *id = xar_attr_get(f, NULL, "id"); if( !id ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: No file id for file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } tmpf = xar_link_lookup(x, XAR(x)->sbcache.st_dev, XAR(x)->sbcache.st_ino, f); if( xar_check_prop(x, "type") ) { xar_prop_set(f, "type", "hardlink"); if( tmpf ) { const char *id; id = xar_attr_get(tmpf, NULL, "id"); xar_attr_set(f, "type", "link", id); } else { xar_attr_set(f, "type", "link", "original"); } } } else { type = filetype_name(XAR(x)->sbcache.st_mode & S_IFMT); if( xar_check_prop(x, "type") ) xar_prop_set(f, "type", type); } /* Record major/minor device node numbers */ if( xar_check_prop(x, "device") && (S_ISBLK(XAR(x)->sbcache.st_mode) || S_ISCHR(XAR(x)->sbcache.st_mode))) { uint32_t major, minor; char tmpstr[12]; xar_devmake(XAR(x)->sbcache.st_rdev, &major, &minor); memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr)-1, "%u", major); xar_prop_set(f, "device/major", tmpstr); memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr)-1, "%u", minor); xar_prop_set(f, "device/minor", tmpstr); } if( S_ISLNK(XAR(x)->sbcache.st_mode) ) { char link[4096]; struct stat lsb; memset(link, 0, sizeof(link)); readlink(file, link, sizeof(link)-1); xar_prop_set(f, "link", link); if( stat(file, &lsb) != 0 ) { xar_attr_set(f, "link", "type", "broken"); } else { type = filetype_name(lsb.st_mode & S_IFMT); xar_attr_set(f, "link", "type", type); } } if( xar_check_prop(x, "inode") ) { asprintf(&tmpstr, "%"INO_STRING, XAR(x)->sbcache.st_ino); xar_prop_set(f, "inode", tmpstr); free(tmpstr); } if( xar_check_prop(x, "deviceno") ) { asprintf(&tmpstr, "%"DEV_STRING, XAR(x)->sbcache.st_dev); xar_prop_set(f, "deviceno", tmpstr); free(tmpstr); } if( xar_check_prop(x, "mode") ) { asprintf(&tmpstr, "%04o", XAR(x)->sbcache.st_mode & (~S_IFMT)); xar_prop_set(f, "mode", tmpstr); free(tmpstr); } if( xar_check_prop(x, "uid") ) { asprintf(&tmpstr, "%"PRIu64, (uint64_t)XAR(x)->sbcache.st_uid); xar_prop_set(f, "uid", tmpstr); free(tmpstr); } if( xar_check_prop(x, "user") ) { pw = getpwuid(XAR(x)->sbcache.st_uid); if( pw ) xar_prop_set(f, "user", pw->pw_name); } if( xar_check_prop(x, "gid") ) { asprintf(&tmpstr, "%"PRIu64, (uint64_t)XAR(x)->sbcache.st_gid); xar_prop_set(f, "gid", tmpstr); free(tmpstr); } if( xar_check_prop(x, "group") ) { gr = getgrgid(XAR(x)->sbcache.st_gid); if( gr ) xar_prop_set(f, "group", gr->gr_name); } if( xar_check_prop(x, "atime") ) { gmtime_r(&XAR(x)->sbcache.st_atime, &t); memset(time, 0, sizeof(time)); strftime(time, sizeof(time), "%FT%T", &t); strcat(time, "Z"); xar_prop_set(f, "atime", time); } if( xar_check_prop(x, "mtime") ) { gmtime_r(&XAR(x)->sbcache.st_mtime, &t); memset(time, 0, sizeof(time)); strftime(time, sizeof(time), "%FT%T", &t); strcat(time, "Z"); xar_prop_set(f, "mtime", time); } if( xar_check_prop(x, "ctime") ) { gmtime_r(&XAR(x)->sbcache.st_ctime, &t); memset(time, 0, sizeof(time)); strftime(time, sizeof(time), "%FT%T", &t); strcat(time, "Z"); xar_prop_set(f, "ctime", time); } flags_archive(x, f, &(XAR(x)->sbcache)); aacls(x, f, file); return 0; } int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; int32_t m=0, mset=0; uid_t u; gid_t g; const char *timestr; struct tm t; enum {ATIME=0, MTIME}; struct timeval tv[2]; char savesuid = 0; /* when writing to a buffer, there are no permissions to set */ if ( len ) return 0; /* in case we don't find anything useful in the archive */ u = geteuid(); g = getegid(); opt = xar_opt_get(x, XAR_OPT_OWNERSHIP); if( opt && (strcmp(opt, XAR_OPT_VAL_SYMBOLIC) == 0) ) { struct passwd *pw; struct group *gr; xar_prop_get(f, "user", &opt); if( opt ) { pw = getpwnam(opt); if( pw ) { u = pw->pw_uid; } } xar_prop_get(f, "group", &opt); if( opt ) { gr = getgrnam(opt); if( gr ) { g = gr->gr_gid; } } savesuid = 1; } if( opt && (strcmp(opt, XAR_OPT_VAL_NUMERIC) == 0) ) { xar_prop_get(f, "uid", &opt); if( opt ) { long long tmp; tmp = strtol(opt, NULL, 10); if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) { return -1; } u = (uid_t)tmp; } xar_prop_get(f, "gid", &opt); if( opt ) { long long tmp; tmp = strtol(opt, NULL, 10); if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) { return -1; } g = (gid_t)tmp; } savesuid = 1; } opt = xar_opt_get(x, XAR_OPT_SAVESUID); if( opt && (strcmp(opt, XAR_OPT_VAL_TRUE) == 0) ) { savesuid = 1; } xar_prop_get(f, "mode", &opt); if( opt ) { long long tmp; tmp = strtoll(opt, NULL, 8); if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) { return -1; } m = (mode_t)tmp; if( !savesuid ) { m &= ~S_ISUID; m &= ~S_ISGID; } mset = 1; } xar_prop_get(f, "type", &opt); if( opt && !mset ) { mode_t u = umask(0); umask(u); if( strcmp(opt, "directory") == 0 ) { m = (mode_t)(0777 & ~u); } else { m = (mode_t)(0666 & ~u); } mset = 1; } if( opt && (strcmp(opt, "symlink") == 0) ) { #ifdef HAVE_LCHOWN if( lchown(file, u, g) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "perm: could not lchown symlink"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); m &= ~S_ISUID; m &= ~S_ISGID; } #ifdef HAVE_LCHMOD if( mset ) if( lchmod(file, m) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "perm: could not lchmod symlink"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } #endif #endif } else { if( chown(file, u, g) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "perm: could not chown file"); xar_err_set_errno(x, errno); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); m &= ~S_ISUID; m &= ~S_ISGID; } if( mset ) if( chmod(file, m) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "perm: could not chmod file"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } } eacls(x, f, file); memset(tv, 0, sizeof(struct timeval) * 2); xar_prop_get(f, "atime", ×tr); if( timestr ) { memset(&t, 0, sizeof(t)); strptime(timestr, "%FT%T", &t); tv[ATIME].tv_sec = timegm(&t); } else { tv[ATIME].tv_sec = time(NULL); } xar_prop_get(f, "mtime", ×tr); if( timestr ) { memset(&t, 0, sizeof(t)); strptime(timestr, "%FT%T", &t); tv[MTIME].tv_sec = timegm(&t); } else { tv[MTIME].tv_sec = time(NULL); } utimes(file, tv); return 0; } int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) { const char *opt; int ret, fd; mode_t modet = 0; xar_prop_get(f, "type", &opt); if(opt && ( (strcmp(opt, "character special") == 0) || (strcmp(opt, "block special") == 0)) ) { // We do not extract device nodes anymore return -1; } if(opt && (strcmp(opt, "directory") == 0)) { ret = mkdir(file, 0700); if( (ret != 0) && (errno != EEXIST)) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: Could not create directory"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return ret; } if (errno == EEXIST) { struct stat statdata; if (lstat(file, &statdata) != 0 || (statdata.st_mode & S_IFDIR) == 0) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: Could not create directory because overwriting file is not a directory"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return EINVAL; } } return 0; } if(opt && (strcmp(opt, "symlink") == 0)) { xar_prop_get(f, "link", &opt); if( opt ) { unlink(file); ret = symlink(opt, file); if( ret != 0 ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: Could not create symlink"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); } return ret; } } if(opt && (strcmp(opt, "hardlink") == 0)) { xar_file_t tmpf; opt = xar_attr_get(f, "type", "link"); if( !opt ) return 0; if( strcmp(opt, "original") == 0 ) goto CREATEFILE; tmpf = xmlHashLookup(XAR(x)->link_hash, BAD_CAST(opt)); if( !tmpf ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: Encountered hardlink with no original"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } unlink(file); if( link(XAR_FILE(tmpf)->fspath, file) != 0 ) { if( errno == ENOENT ) { xar_iter_t i; const char *ptr; i = xar_iter_new(); for(ptr = xar_prop_first(tmpf, i); ptr; ptr = xar_prop_next(i)) { xar_iter_t a; const char *val = NULL; const char *akey, *aval; if( strncmp("data", ptr, 4) != 0 ) continue; if( xar_prop_get(tmpf, ptr, &val) ) continue; xar_prop_set(f, ptr, val); a = xar_iter_new(); for(akey = xar_attr_first(tmpf, ptr, a); akey; akey = xar_attr_next(a)) { aval = xar_attr_get(tmpf, ptr, akey); xar_attr_set(f, ptr, akey, aval); } xar_iter_free(a); } xar_iter_free(i); xar_attr_set(f, "type", "link", "original"); return 0; } else { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "stat: Could not link hardlink to original"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } } return 0; } if(opt && (strcmp(opt, "fifo") == 0)) { unlink(file); if( mkfifo(file, 0) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "mkfifo: Could not create fifo"); xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } return 0; } /* skip sockets */ if(opt && (strcmp(opt, "socket") == 0)) { return 0; } CREATEFILE: if (!file) return 0; unlink(file); fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0600); if( fd > 0 ) close(fd); return 0; } xar-xar-498/xar/lib/stat.h000066400000000000000000000042101446633275300154600ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_STAT_H_ #define _XAR_STAT_H_ #include "xar.h" int32_t xar_stat_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len); int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); int32_t xar_flags_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len); #endif /* _XAR_STAT_H_ */ xar-xar-498/xar/lib/strmode.h000077500000000000000000000067021446633275300161750ustar00rootroot00000000000000/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef HAVE_STRMODE #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strmode.c 8.3 (Berkeley) 8/15/94"; #endif /* LIBC_SCCS and not lint */ #include #include #include void strmode(mode, p) mode_t mode; char *p; { /* print type */ switch (mode & S_IFMT) { case S_IFDIR: /* directory */ *p++ = 'd'; break; case S_IFCHR: /* character special */ *p++ = 'c'; break; case S_IFBLK: /* block special */ *p++ = 'b'; break; case S_IFREG: /* regular */ *p++ = '-'; break; case S_IFLNK: /* symbolic link */ *p++ = 'l'; break; case S_IFSOCK: /* socket */ *p++ = 's'; break; #ifdef S_IFIFO case S_IFIFO: /* fifo */ *p++ = 'p'; break; #endif #ifdef S_IFWHT case S_IFWHT: /* whiteout */ *p++ = 'w'; break; #endif default: /* unknown */ *p++ = '?'; break; } /* usr */ if (mode & S_IRUSR) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWUSR) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXUSR | S_ISUID)) { case 0: *p++ = '-'; break; case S_IXUSR: *p++ = 'x'; break; case S_ISUID: *p++ = 'S'; break; case S_IXUSR | S_ISUID: *p++ = 's'; break; } /* group */ if (mode & S_IRGRP) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWGRP) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXGRP | S_ISGID)) { case 0: *p++ = '-'; break; case S_IXGRP: *p++ = 'x'; break; case S_ISGID: *p++ = 'S'; break; case S_IXGRP | S_ISGID: *p++ = 's'; break; } /* other */ if (mode & S_IROTH) *p++ = 'r'; else *p++ = '-'; if (mode & S_IWOTH) *p++ = 'w'; else *p++ = '-'; switch (mode & (S_IXOTH | S_ISVTX)) { case 0: *p++ = '-'; break; case S_IXOTH: *p++ = 'x'; break; case S_ISVTX: *p++ = 'T'; break; case S_IXOTH | S_ISVTX: *p++ = 't'; break; } *p++ = ' '; /* will be a '+' if ACL's implemented */ *p = '\0'; } #endif /* HAVE_STRMODE */ xar-xar-498/xar/lib/subdoc.c000066400000000000000000000144441446633275300157710ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 04-Apr-2005 * DRI: Rob Braun */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include "xar.h" #include "subdoc.h" #include "archive.h" #include "filetree.h" xar_subdoc_t xar_subdoc_new(xar_t x, const char *name) { xar_subdoc_t ret; if( xar_subdoc_find(x, name) ) return NULL; ret = malloc(sizeof(struct __xar_subdoc_t)); if( ! ret ) return NULL; memset(XAR_SUBDOC(ret), 0, sizeof(struct __xar_subdoc_t)); XAR_SUBDOC(ret)->name = strdup(name); XAR_SUBDOC(ret)->next = XAR_SUBDOC(XAR(x)->subdocs); XAR(x)->subdocs = ret; XAR_SUBDOC(ret)->x = x; return ret; } int32_t xar_subdoc_prop_set(xar_subdoc_t s, const char *key, const char *value){ return xar_prop_set((xar_file_t)s, key, value); } int32_t xar_subdoc_prop_get(xar_subdoc_t s, const char *key, const char **value) { return xar_prop_get((xar_file_t)s, key, value); } int32_t xar_subdoc_attr_set(xar_subdoc_t s, const char *prop, const char *key, const char *value){ return xar_attr_set((xar_file_t)s, prop, key, value); } const char *xar_subdoc_attr_get(xar_subdoc_t s, const char *prop, const char *key) { return xar_attr_get((xar_file_t)s, prop, key); } xar_subdoc_t xar_subdoc_first(xar_t x) { return XAR(x)->subdocs; } xar_subdoc_t xar_subdoc_next(xar_subdoc_t s) { return XAR_SUBDOC(s)->next; } const char *xar_subdoc_name(xar_subdoc_t s) { return XAR_SUBDOC(s)->name; } xar_subdoc_t xar_subdoc_find(xar_t x, const char *name) { xar_subdoc_t i; for(i = XAR(x)->subdocs; i; i = XAR_SUBDOC(i)->next) { if( strcmp(name, XAR_SUBDOC(i)->name) == 0 ) return i; } return NULL; } int32_t xar_subdoc_copyout(xar_subdoc_t s, unsigned char **ret, unsigned int *size) { xmlBufferPtr buf; xmlTextWriterPtr writer; buf = xmlBufferCreate(); if( !buf ) return -1; writer = xmlNewTextWriterMemory(buf, 0); if( !writer ) { xmlBufferFree(buf); return -1; } xmlTextWriterSetIndent(writer, 4); xar_subdoc_serialize(s, writer, 0); xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); if( size != NULL ) *size = buf->use; *ret = malloc(buf->size); if( *ret == NULL ) { xmlBufferFree(buf); return -1; } assert(size != NULL); memcpy(*ret, buf->content, *size); xmlBufferFree(buf); return 0; } int32_t xar_subdoc_copyin(xar_subdoc_t s, const unsigned char *buf, unsigned int len) { xmlTextReaderPtr reader; reader = xmlReaderForMemory((const char *)buf, len, NULL, NULL, 0); if( !reader ) return -1; if (xar_subdoc_unserialize(s, reader) != 0) { xmlFreeTextReader(reader); return -1; } xmlFreeTextReader(reader); return 0; } /* xar_subdoc_serialize * s: a subdoc structure allocated and initialized by xar_subdoc_new() * writer: and xmlTextWriterPtr that has already been opend and initialized * and is pointing to the place where the subdocument will be serialized. * wrap: an integer describing whether the subdocument is to be wrapped * for placement in the xml header of an archive, or if we are trying to * reconstruct the original document. 1 for wrapping, 0 for original. */ void xar_subdoc_serialize(xar_subdoc_t s, xmlTextWriterPtr writer, int wrap) { if( !s ) return; if( wrap ) { xmlTextWriterStartElementNS(writer, BAD_CAST(XAR_SUBDOC(s)->prefix), BAD_CAST("subdoc"), BAD_CAST(XAR_SUBDOC(s)->ns)); xmlTextWriterWriteAttribute(writer, BAD_CAST("subdoc_name"), BAD_CAST(XAR_SUBDOC(s)->name)); if( XAR_SUBDOC(s)->value ) xmlTextWriterWriteString(writer, BAD_CAST(XAR_SUBDOC(s)->value)); } xar_prop_serialize(XAR_SUBDOC(s)->props, writer); xmlTextWriterEndElement(writer); } void xar_subdoc_remove(xar_subdoc_t s) { xar_prop_t p; xar_subdoc_t tmp = xar_subdoc_first(XAR_SUBDOC(s)->x); if( tmp == s ) { XAR(XAR_SUBDOC(s)->x)->subdocs = XAR_SUBDOC(s)->next; } else { while(XAR_SUBDOC(tmp)->next) { if( XAR_SUBDOC(tmp)->next == s ) { XAR_SUBDOC(tmp)->next = XAR_SUBDOC(s)->next; break; } tmp = xar_subdoc_next(tmp); } } while(XAR_SUBDOC(s)->props) { p = XAR_SUBDOC(s)->props; XAR_SUBDOC(s)->props = XAR_PROP(XAR_PROP(p)->next); xar_prop_free(p); } free((char *)XAR_SUBDOC(s)->blank1); free((char *)XAR_SUBDOC(s)->name); free((void *)s); return; } int xar_subdoc_unserialize(xar_subdoc_t s, xmlTextReaderPtr reader) { int type; while( xmlTextReaderRead(reader) == 1 ) { type = xmlTextReaderNodeType(reader); if( type == XML_READER_TYPE_ELEMENT ) { if (xar_prop_unserialize((xar_file_t)s, NULL, reader) != 0) { return -1; } } if( type == XML_READER_TYPE_TEXT ) { const char *value; value = (const char *)xmlTextReaderConstValue(reader); free((char*)XAR_SUBDOC(s)->value); XAR_SUBDOC(s)->value = strdup(value); } if( type == XML_READER_TYPE_END_ELEMENT ) { break; } } return 0; } xar-xar-498/xar/lib/subdoc.h000066400000000000000000000046601446633275300157750ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ #ifndef _XAR_SUBDOC_H_ #define _XAR_SUBDOC_H_ #include "xar.h" #include "filetree.h" struct __xar_subdoc_t { struct __xar_prop_t *props; struct __xar_attr_t *attrs; const char *prefix; const char *ns; const char *blank1; /* filler for xar_file_t compatibility */ const char *blank2; /* filler for xar_file_t compatibility */ const char blank3; /* filler for xar_file_t compatibility */ const char *name; struct __xar_subdoc_t *next; const char *value; /* a subdoc should very rarely have a value */ xar_t x; }; #define XAR_SUBDOC(x) ((struct __xar_subdoc_t *)(x)) int xar_subdoc_unserialize(xar_subdoc_t s, xmlTextReaderPtr reader); void xar_subdoc_serialize(xar_subdoc_t s, xmlTextWriterPtr writer, int wrap); void xar_subdoc_free(xar_subdoc_t s); xar_subdoc_t xar_subdoc_find(xar_t x, const char *name); #endif /* _XAR_SUBDOC_H_ */ xar-xar-498/xar/lib/util.c000066400000000000000000000335241446633275300154670ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include #include #include #include #include #include #include #include #include #include #include "config.h" #include #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include "xar.h" #include "archive.h" #include "filetree.h" int xar_is_safe_filename(const char *in_filename, char** out_filename) { int result = -1; // Bail for NULL if (in_filename == NULL) { goto exit; } // Set walker. size_t slash_count = 0; size_t in_filename_length = strlen(in_filename); // Find how many "/" we have. // This doesn't deal with \/ but it's close enough. for (size_t index = 0; index < in_filename_length; ++index) { if (in_filename[index] == '/') { if (slash_count <= PATH_MAX) { ++slash_count; } else { fprintf(stderr, "slash_count exceeded PATH_MAX. Filename is invalid.\n"); goto exit; } } } // If we didn't find any "/" just return 0. result = (slash_count == 0) ? 0 : -1; // If we don't have a slash or don't have a out, just bail. if (out_filename == NULL) { goto exit; } // Shortcut the rest with strdup in this case. if (slash_count == 0) { *out_filename = strdup(in_filename); goto exit; } // Now do the translation. *out_filename = calloc(in_filename_length+1, 1); for (size_t index = 0; index < in_filename_length; ++index) { if (in_filename[index] == '/') { // Add "_" at this location (*out_filename)[index] = ':'; } else { (*out_filename)[index] = in_filename[index]; } } exit: return result; } // SC: This is function is a exact copy of dirname BUT instead of // just using the same buffer over and over again, we allocate one. // This means the result needs to be freed, but it also means the // result will be correct. char *xar_safe_dirname(const char *path) { char *dname = malloc(PATH_MAX); const char *endp; size_t len; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { dname[0] = '.'; dname[1] = '\0'; return (dname); } /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; /* Find the start of the dir */ while (endp > path && *endp != '/') endp--; /* Either the dir is "/" or there are no slashes */ if (endp == path) { dname[0] = *endp == '/' ? '/' : '.'; dname[1] = '\0'; return (dname); } else { /* Move forward past the separating slashes */ do { endp--; } while (endp > path && *endp == '/'); } len = endp - path + 1; if (len >= MAXPATHLEN) { errno = ENAMETOOLONG; free(dname); return (NULL); } memmove(dname, path, len); dname[len] = '\0'; return (dname); } uint64_t xar_ntoh64(uint64_t num) { int t = 1234; union conv { uint64_t i64; uint32_t i32[2]; } *in, out; if( ntohl(t) == t ) { out.i64 = num; return out.i64; } in = (union conv *)# out.i32[1] = ntohl(in->i32[0]); out.i32[0] = ntohl(in->i32[1]); return(out.i64); } uint32_t xar_swap32(uint32_t num) { uint8_t *one, *two; uint32_t ret; two = (uint8_t *)&ret; one = (uint8_t *)# two[3] = one[0]; two[2] = one[1]; two[1] = one[2]; two[0] = one[3]; return ret; } char *xar_get_safe_path(xar_file_t f) { char *ret = NULL, *tmp; const char *unsafe_parent_name; xar_file_t i; xar_prop_get(f, "name", &unsafe_parent_name); if( unsafe_parent_name == NULL ) { return NULL; } // strdup the parent name into ret if safe. xar_is_safe_filename(unsafe_parent_name, &ret); for(i = XAR_FILE(f)->parent; i; i = XAR_FILE(i)->parent) { const char *unsafe_name; char* name = NULL; xar_prop_get(i, "name", &unsafe_name); if (unsafe_name) { xar_is_safe_filename(unsafe_name, &name); tmp = ret; asprintf(&ret, "%s/%s", name, tmp); free(tmp); free(name); } } return ret; } /* xar_get_path * Summary: returns the archive path of the file f. * Caller needs to free the return value. */ char *xar_get_path(xar_file_t f) { char *ret, *tmp; const char *name; xar_file_t i; xar_prop_get(f, "name", &name); if( name == NULL ) { return NULL; } ret = strdup(name); for(i = XAR_FILE(f)->parent; i; i = XAR_FILE(i)->parent) { const char *name; xar_prop_get(i, "name", &name); if (name != NULL) { tmp = ret; asprintf(&ret, "%s/%s", name, tmp); free(tmp); } else { return NULL; } } return ret; } off_t xar_get_heap_offset(xar_t x) { return XAR(x)->toc_count + sizeof(xar_header_t); } /* xar_read_fd * Summary: Reads from a file descriptor a certain number of bytes to a specific * buffer. This simple wrapper just handles certain retryable error situations. * Returns -1 when it fails fatally; the number of bytes read otherwise. */ ssize_t xar_read_fd( int fd, void * buffer, size_t nbyte ) { ssize_t rb; ssize_t total = 0; while ( total < nbyte ) { rb = read(fd, ((char *)buffer)+total, nbyte-total); if( rb == 0 ) { return total; } else if( rb < 0 ) { if( (errno == EINTR) || (errno == EAGAIN) ) continue; return rb; } total += rb; } return total; } /* xar_pread_fd * Summary: Does the same as xar_read_fd, but uses pread(2) instead of read(2). */ ssize_t xar_pread_fd(int fd, void * buffer, size_t nbyte, off_t offset) { ssize_t rb; ssize_t total = 0; while ( total < nbyte ) { rb = pread(fd, ((char *)buffer)+total, nbyte-total, offset+total); if( rb == 0 ) { return total; } else if( rb < 0 ) { if( (errno == EINTR) || (errno == EAGAIN) ) continue; return rb; } total += rb; } return total; } /* xar_write_fd * Summary: Writes from a buffer to a file descriptor. Like xar_read_fd it * also just handles certain retryable error situations. * Returns -1 when it fails fatally; the number of bytes written otherwise. */ ssize_t xar_write_fd( int fd, void * buffer, size_t nbyte ) { ssize_t rb; ssize_t total = 0; while ( total < nbyte ) { rb = write(fd, ((char *)buffer)+total, nbyte-total); if( rb == 0 ) { return total; } else if( rb < 0 ) { if( (errno == EINTR) || (errno == EAGAIN) ) continue; return rb; } total += rb; } return total; } /* xar_pwrite_fd * Summary: Does the same as xar_write_fd, but uses pwrite(2) instead of write(2). */ ssize_t xar_pwrite_fd( int fd, void * buffer, size_t nbyte, off_t offset ) { ssize_t rb; size_t total = 0; while( total < nbyte ) { rb = pwrite(fd, ((char *)buffer)+total, nbyte-total, offset+total); if( rb == 0 ) { return total; } else if( rb < 0 ) { if( (errno == EINTR) || (errno == EAGAIN) ) continue; return rb; } total += rb; } return total; } dev_t xar_makedev(uint32_t major, uint32_t minor) { #ifdef makedev return makedev(major, minor); #else return (major << 8) | minor; #endif } void xar_devmake(dev_t dev, uint32_t *out_major, uint32_t *out_minor) { #ifdef major *out_major = major(dev); #else *out_major = (dev >> 8) & 0xFF; #endif #ifdef minor *out_minor = minor(dev); #else *out_minor = dev & 0xFF; #endif return; } char* xar_path_nextcomponent(char** path_to_advance) { char* component_start = *path_to_advance; unsigned int component_length = 1; char* out_component = NULL; if (**path_to_advance == '\0') // If we're trying to look at the end of the path, punt return NULL; for (; **path_to_advance && (**path_to_advance != '/'); ++(*path_to_advance), ++component_length) { if (**path_to_advance == '\\') { // Escape ignores next char ++(*path_to_advance); ++component_length; continue; } } if (**path_to_advance == '/') { ++(*path_to_advance); } out_component = (char*)malloc(component_length); strncpy(out_component, component_start, component_length); out_component[component_length-1] = 0; return out_component; } char* xar_lowercase_string(const char* string) { if (string == NULL) return NULL; size_t string_length = strlen(string)+1; char* result = calloc(string_length, 1); for (size_t index = 0; index < string_length; ++index) { result[index] = tolower(string[index]); } return result; } int xar_path_issane(char* path) { char* path_walker = path; char* component = NULL; int path_depth = 0; if (path == NULL) { return 0; } // Ban 0 length / absolute paths. if (strlen(path) == 0 || path[0] == '/') return 0; while ((component = xar_path_nextcomponent(&path_walker))) { if (strlen(component) == 0 || strcmp(component, ".") == 0) { // Since // is legal, and '.' is legal it's possible to have empty path elements. Ignore them free(component); continue; } if (strcmp(component, "..")) ++path_depth; else --path_depth; free(component); if (path_depth < 0) // We've escaped our root, this path is not sane. return 0; } return 1; } #ifndef HAVE_STRMODE #include "strmode.h" #endif char *xar_get_type(xar_t x, xar_file_t f) { const char *type = NULL; xar_prop_get(f, "type", &type); if( type == NULL ) type = "unknown"; return strdup(type); } char *xar_get_size(xar_t x, xar_file_t f) { const char *size = NULL; const char *type = NULL; xar_prop_get(f, "type", &type); if( type != NULL ) { if( strcmp(type, "hardlink") == 0 ) { const char *link = NULL; link = xar_attr_get(f, "type", "link"); if( link ) { if( strcmp(link, "original") != 0 ) { xar_iter_t i; i = xar_iter_new(); if( i ) { xar_file_t tmpf; for(tmpf = xar_file_first(x, i); tmpf; tmpf = xar_file_next(i)) { const char *id; id = xar_attr_get(tmpf, NULL, "id"); if( !id ) continue; if( strcmp(id, link) == 0 ) { f = tmpf; break; } } } xar_iter_free(i); } } } } xar_prop_get(f, "data/size", &size); if( size == NULL ) size = "0"; return strdup(size); } char *xar_get_mode(xar_t x, xar_file_t f) { const char *mode = NULL; const char *type = NULL; char *ret; mode_t m; xar_prop_get(f, "mode", &mode); if( mode == NULL ) return strdup("??????????"); errno = 0; m = strtoll(mode, 0, 8); if( errno ) return strdup("??????????"); xar_prop_get(f, "type", &type); if( type == NULL ) return strdup("??????????"); if( strcmp(type, "file") == 0 ) m |= S_IFREG; else if( strcmp(type, "hardlink") == 0 ) m |= S_IFREG; else if( strcmp(type, "directory") == 0 ) m |= S_IFDIR; else if( strcmp(type, "symlink") == 0 ) m |= S_IFLNK; else if( strcmp(type, "fifo") == 0 ) m |= S_IFIFO; else if( strcmp(type, "character special") == 0 ) m |= S_IFCHR; else if( strcmp(type, "block special") == 0 ) m |= S_IFBLK; else if( strcmp(type, "socket") == 0 ) m |= S_IFSOCK; #ifdef S_IFWHT else if( strcmp(type, "whiteout") == 0 ) m |= S_IFWHT; #endif ret = calloc(12,1); strmode(m, ret); return ret; } char *xar_get_owner(xar_t x, xar_file_t f) { const char *user = NULL; xar_prop_get(f, "user", &user); if( !user ) return strdup("unknown"); return strdup(user); } char *xar_get_group(xar_t x, xar_file_t f) { const char *group = NULL; xar_prop_get(f, "group", &group); if( !group ) return strdup("unknown"); return strdup(group); } char *xar_get_mtime(xar_t x, xar_file_t f) { const char *mtime = NULL; char *tmp; struct tm tm; xar_prop_get(f, "mtime", &mtime); if( !mtime ) mtime = "1970-01-01T00:00:00Z"; strptime(mtime, "%FT%T", &tm); tmp = calloc(128,1); strftime(tmp, 127, "%F %T", &tm); return tmp; } size_t xar_optimal_io_size_at_path(const char *path) { // Start at 1MiB size_t optimal_rsize = 1024 * 1024; // Stat the destination of the archive to determine the optimal fs operation size struct statfs target_mount_stat_fs; if ( statfs(path, &target_mount_stat_fs) == 0 ) { // iosize is the size that the filesystem likes to work in size_t fs_iosize = target_mount_stat_fs.f_iosize; if ( fs_iosize == -1 ) { fs_iosize = optimal_rsize; } // If we're a remote filesystem, never let us go below the optimal size above of 1MiB // NFS is horrible and lies that the optimal size is 512 bytes. // Whereas SMB in my testing returns 7MiBs (far more practicle) // This ensures that we do something sane if reading over the network if ( ( target_mount_stat_fs.f_flags & MNT_LOCAL ) != MNT_LOCAL ) { if ( fs_iosize > optimal_rsize ) { optimal_rsize = fs_iosize; } } else { optimal_rsize = fs_iosize; } } return optimal_rsize; } xar-xar-498/xar/lib/util.h000066400000000000000000000063671446633275300155010ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan * Steven Cento */ #ifndef _XAR_UTIL_H_ #define _XAR_UTIL_H_ #include #include "xar.h" uint64_t xar_ntoh64(uint64_t num); uint32_t xar_swap32(uint32_t num); char *xar_get_path(xar_file_t f); off_t xar_get_heap_offset(xar_t x); ssize_t xar_read_fd(int fd, void * buffer, size_t nbyte); ssize_t xar_pread_fd(int fd, void * buffer, size_t nbyte, off_t offset); ssize_t xar_write_fd(int fd, void * buffer, size_t nbyte); ssize_t xar_pwrite_fd( int fd, void * buffer, size_t nbyte, off_t offset ); dev_t xar_makedev(uint32_t major, uint32_t minor); void xar_devmake(dev_t dev, uint32_t *major, uint32_t *minor); char* xar_safe_dirname(const char* path); // This is used to check to see if a given path escapes from // the extraction root. int xar_path_issane(char* path); // Returns a string containing the name of the next path component in path_to_advance. // Path to advance also gets moved forward to the start of the next component in the path. // The returned string must be released by the caller. char* xar_path_nextcomponent(char** path_to_advance); // Make a lower string char* xar_lowercase_string(const char* string); /*! @abstract Returns the optimal io size of the filesystem backing the file at the path provided. */ size_t xar_optimal_io_size_at_path(const char *path); /*! @returns 0 if the file name is safe, < 0 if the file name is not safe. If out_filename is supplied a corrected file name is returned. You must free the returned file name */ int xar_is_safe_filename(const char *in_filename, char** out_filename); #endif /* _XAR_UTIL_H_ */ xar-xar-498/xar/lib/zxar.c000066400000000000000000000166651446633275300155050ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #include "config.h" #ifndef HAVE_ASPRINTF #include "asprintf.h" #endif #include #include #include #include #include #include #include "xar.h" #include "filetree.h" #include "io.h" struct _gzip_context{ uint8_t gzipcompressed; uint64_t count; z_stream z; }; #define GZIP_CONTEXT(x) ((struct _gzip_context *)(*x)) int xar_gzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { if( !context || !GZIP_CONTEXT(context) ) return 0; if( GZIP_CONTEXT(context)->gzipcompressed){ inflateEnd(&GZIP_CONTEXT(context)->z); } /* free the context */ free(GZIP_CONTEXT(context)); *context = NULL; return 0; } int xar_gzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { const char *opt; void *out = NULL; size_t outlen, offset = 0; int r; xar_prop_t tmpp; /* on first run, we init the context and check the compression type */ if( !GZIP_CONTEXT(context) ) { *context = calloc(1,sizeof(struct _gzip_context)); opt = NULL; tmpp = xar_prop_pget(p, "encoding"); if( tmpp ) opt = xar_attr_pget(f, tmpp, "style"); if( !opt ) return 0; if( strcmp(opt, "application/x-gzip") != 0 ) return 0; inflateInit(&GZIP_CONTEXT(context)->z); GZIP_CONTEXT(context)->gzipcompressed = 1; }else if( !GZIP_CONTEXT(context)->gzipcompressed ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen; GZIP_CONTEXT(context)->z.next_in = *in; GZIP_CONTEXT(context)->z.avail_in = *inlen; GZIP_CONTEXT(context)->z.next_out = out; GZIP_CONTEXT(context)->z.avail_out = 0; while( GZIP_CONTEXT(context)->z.avail_in != 0 ) { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); GZIP_CONTEXT(context)->z.next_out = ((unsigned char *)out) + offset; GZIP_CONTEXT(context)->z.avail_out = outlen - offset; size_t start_avail_in = GZIP_CONTEXT(context)->z.avail_in; size_t start_avail_out = GZIP_CONTEXT(context)->z.avail_out; r = inflate(&(GZIP_CONTEXT(context)->z), Z_NO_FLUSH); if( (r != Z_OK) && (r != Z_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error decompressing file"); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_EXTRACTION); return -1; } offset += outlen - offset - GZIP_CONTEXT(context)->z.avail_out; } free(*in); *in = out; *inlen = offset; return 0; } int xar_gzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context) { xar_prop_t tmpp; if( GZIP_CONTEXT(context)->gzipcompressed){ deflateEnd(&GZIP_CONTEXT(context)->z); if( GZIP_CONTEXT(context)->count ) { tmpp = xar_prop_pset(f, p, "encoding", NULL); if( tmpp ) xar_attr_pset(f, tmpp, "style", "application/x-gzip"); } } /* free the context */ free(GZIP_CONTEXT(context)); *context = NULL; return 0; } int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context) { void *out = NULL; size_t outlen, offset = 0; int r; const char *opt; /* on first run, we init the context and check the compression type */ if( !GZIP_CONTEXT(context) ) { int level = Z_BEST_COMPRESSION; *context = calloc(1,sizeof(struct _gzip_context)); opt = xar_opt_get(x, XAR_OPT_COMPRESSION); if( !opt ) return 0; if( strcmp(opt, XAR_OPT_VAL_GZIP) != 0 ) return 0; opt = xar_opt_get(x, XAR_OPT_COMPRESSIONARG); if( opt ) { int tmp; errno = 0; tmp = strtol(opt, NULL, 10); if( errno == 0 ) { if( (level >= 0) && (level <= 9) ) level = tmp; } } deflateInit(&GZIP_CONTEXT(context)->z, level); GZIP_CONTEXT(context)->gzipcompressed = 1; if( *inlen == 0 ) return 0; }else if( !GZIP_CONTEXT(context)->gzipcompressed ){ /* once the context has been initialized, then we have already checked the compression type, so we need only check if we actually are compressed */ return 0; } outlen = *inlen/2; if(outlen == 0) outlen = 1024; GZIP_CONTEXT(context)->z.next_in = *in; GZIP_CONTEXT(context)->z.avail_in = *inlen; GZIP_CONTEXT(context)->z.next_out = out; GZIP_CONTEXT(context)->z.avail_out = 0; if( *inlen != 0 ) { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); GZIP_CONTEXT(context)->z.next_out = ((unsigned char *)out) + offset; GZIP_CONTEXT(context)->z.avail_out = outlen - offset; r = deflate(&GZIP_CONTEXT(context)->z, Z_NO_FLUSH); offset = outlen - GZIP_CONTEXT(context)->z.avail_out; } while( r == Z_OK && GZIP_CONTEXT(context)->z.avail_in != 0 ); } else { do { size_t newlen = outlen * 2; if (newlen > outlen) outlen = newlen; else abort(); /* Someone has somehow malloced over 2^64 bits of ram. */ out = realloc(out, outlen); if( out == NULL ) abort(); GZIP_CONTEXT(context)->z.next_out = ((unsigned char *)out) + offset; GZIP_CONTEXT(context)->z.avail_out = outlen - offset; r = deflate(&GZIP_CONTEXT(context)->z, Z_FINISH); offset = outlen - GZIP_CONTEXT(context)->z.avail_out; } while( r == Z_OK && r != Z_STREAM_END /* no-op */); } if( (r != Z_OK && r != Z_STREAM_END) ) { xar_err_new(x); xar_err_set_file(x, f); xar_err_set_string(x, "Error compressing file"); xar_err_set_errno(x, r); xar_err_callback(x, XAR_SEVERITY_FATAL, XAR_ERR_ARCHIVE_CREATION); return -1; } free(*in); *in = out; GZIP_CONTEXT(context)->count += *inlen; *inlen = offset; return 0; } xar-xar-498/xar/lib/zxar.h000066400000000000000000000041641446633275300155010ustar00rootroot00000000000000/* * Copyright (c) 2005-2007 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ /* * Portions Copyright 2006, Apple Computer, Inc. * Christopher Ryan */ #ifndef _XAR_ZLIB_H_ #define _XAR_ZLIB_H_ int xar_gzip_fromheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_gzip_fromheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); int32_t xar_gzip_toheap_in(xar_t x, xar_file_t f, xar_prop_t p, void **in, size_t *inlen, void **context); int xar_gzip_toheap_done(xar_t x, xar_file_t f, xar_prop_t p, void **context); #endif /* _XAR_ZLIB_H_ */ xar-xar-498/xar/src/000077500000000000000000000000001446633275300143605ustar00rootroot00000000000000xar-xar-498/xar/src/.cvsignore000066400000000000000000000000321446633275300163530ustar00rootroot00000000000000Makefile.inc ixar xar *.d xar-xar-498/xar/src/Makefile.inc.in000066400000000000000000000033371446633275300172030ustar00rootroot00000000000000# # Include generated dependency files. # XAR_SRCS := xar.c XAR_SRCS := $(patsubst %, @srcroot@src/%, $(XAR_SRCS)) -include $(XAR_SRCS:@srcroot@%.c=@objroot@%.d) src_all : @objroot@src/xar @objroot@src/ixar src_install : @objroot@src/ixar @INSTALL@ -d $(DESTDIR)$(BINDIR) @INSTALL@ -m 0755 $< $(DESTDIR)$(BINDIR)/xar @INSTALL@ -d $(DESTDIR)$(MANDIR)/man1 @INSTALL@ -m 0644 @srcroot@src/xar.1 $(DESTDIR)$(MANDIR)/man1 src_uninstall : rm -f $(DESTDIR)/$(BINDIR)/xar rm -f $(DESTDIR)/$(MANDIR)/man1/xar.1 src_clean : rm -f @objroot@src/xar rm -f @objroot@src/ixar rm -f $(XAR_SRCS:@srcroot@%.c=@objroot@%.o) rm -f $(XAR_SRCS:@srcroot@%.c=@objroot@%.d) src_distclean : ifeq (yes, @shared@) LIBRXAR := $(LIBRXAR_S) endif ifeq (yes, @static@) LIBRXAR := $(LIBXAR_A) endif # xar links against librxar, so that it can be run without first installing # libxar. @objroot@src/% : @objroot@src/%.o $(LIBRXAR) @mkdir -p $(@D) ifneq ($(words "" @RPATH@), 1) $(CC) $(CFLAGS) -o $@ $< @RPATH@@abs_objroot@lib $(LDFLAGS) $(LIBRXAR) @LIBS@ else $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LIBRXAR) @LIBS@ endif ifeq (yes, @static@) LIBXAR := $(LIBXAR_A) endif ifeq (yes, @shared@) LIBXAR := $(LIBXAR_S) endif # ixar is the version of the xar binary that gets installed. @objroot@src/i% : @objroot@src/%.o $(LIBXAR) @mkdir -p $(@D) ifneq ($(words "" @RPATH@), 1) $(CC) $(CFLAGS) -o $@ $< @RPATH@$(LIBDIR) $(LDFLAGS) $(LIBXAR) @LIBS@ else $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LIBXAR) @LIBS@ endif @objroot@src/%.o : @srcroot@src/%.c @mkdir -p $(@D) $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ @$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)" xar-xar-498/xar/src/xar.1000066400000000000000000000133621446633275300152410ustar00rootroot00000000000000.TH XAR "1" "June 4, 2015" "version 1.8" "User Commands" .SH NAME xar \- eXtensible ARchiver .SH DEPRECATION WARNING .B xar is no longer under active development by Apple. Clients of xar should pursue alternative archive formats. .SH SYNOPSIS .B xar \-[\fIctx\fR][\fIv\fR] ... .SH DESCRIPTION The XAR project aims to provide an easily extensible archive format. Important design decisions include an easily extensible XML table of contents (TOC) for random access to archived files, storing the TOC at the beginning of the archive to allow for efficient handling of streamed archives, the ability to handle files of arbitrarily large sizes, the ability to choose independent encodings for individual files in the archive, the ability to store checksums for individual files in both compressed and uncompressed form, and the ability to query the table of content's rich meta-data. .SH FUNCTIONS .TP .B One of the following options must be used: .TP \-c Creates an archive .TP \-t Lists the contents of an archive .TP \-x Extracts an archive .TP .B NOTE: all of the above require the use of the -f option (filename) as this release of xar doesn't correctly handle pipes or sockets. .TP \-f The filename to use for creation, listing or extraction. With extraction, this can be a POSIX regular expression. .SH OPTIONS .TP \-\-compression Specifies the compression type to use. Valid values: none, gzip, bzip2, lzma (on some systems). Default value: gzip .TP \-C On extract, xar will chdir to the specified path before extracting the archive. .TP \-a Synonym for \-\-compression=lzma .TP \-j Synonym for \-\-compression=bzip2 .TP \-z Synonym for \-\-compression=gzip .TP \-\-compression-args= Specifies arguments to the compression engine selected. gzip, bzip2, and lzma all take a single integer argument between 0 and 9 specifying the compression level to use. .TP \-\-dump\-toc= Has xar dump the xml header into the specified file. "-" can be specified to mean stdout. .TP \-\-dump\-toc\-cksum Dumps the ToC checksum to stdout along with the algorithm of the ToC. .TP \-\-dump\-header Has xar print out the xar binary header information to stdout. .TP \-\-extract\-subdoc= Extracts the specified subdocument to a document in cwd named .xml .TP \-\-list\-subdocs List the subdocuments in the xml header .TP \-\-toc\-cksum Specifies the hashing algorithm to use for xml header verification. Valid values: md5 (on some systems), sha1, sha256, and sha512. Default value: sha1 .TP \-\-file\-cksum Specifies the hashing algorithm to use for file content verification. Valid values: md5 (on some systems), sha1, sha256, and sha512. Default value: sha1 .TP \-l On archival, stay on the local device. .TP \-P On extract, set ownership based on uid/gid. If the uid/gid can be set on the extracted file, setuid/setgid bits will also be preserved. .TP \-p On extract, set ownership based on symbolic names, if possible. If the uid/gid can be set on the extracted file, setuid/setgid bits will also be preserved. .TP \-s On extract, specifies the file to extract subdocuments to. On archival, specifies an xml file to add as a subdocument. .TP \-v Verbose output .TP \-\-exclude Specifies a POSIX regular expression of files to exclude from adding to the archive during creation or from being extracted during extraction. This option can be specified multiple times. .TP \-\-rsize Specifies a size (in bytes) for the internal libxar read buffer while performing I/O. .TP \-\-coalesce-heap When multiple files in the archive are identical, only store one copy of the data in the heap. This creates smaller archives, but the archives created are not streamable. .TP \-\-link-same When the data section of multiple files are identical, hardlink them within the archive. .TP \-\-no-compress Specifies a POSIX regular expression of files to archive, but not compress. The archived files will be copied raw into the archive. This can be used to exclude already gzipped files from being gzipped during the archival process. .TP \-\-prop-include Specifies a file property to be included in the archive. When this option is specified, only the specified options will be included. Anything not specifically included with this option will be omitted. This option can be used multiple times. .TP \-\-prop-exclude Specifies a file property to be excluded from the archive. When this option is specified, all file properties will be included except the specified properties. This option can be used multiple times. .TP \-\-distribution Creates an archive to only contain file properties safe for file distribution. Currently, only name, type, mode, and data are preserved with this option. .TP \-\-keep-existing Does not overwrite existing files during extraction. Keeps any previously existing files while extracting. .TP \-k Synonym for \-\-keep-existing. .TP \-\-keep-setuid When extracting without -p or -P options, xar will extract files as the uid/gid of the extracting process. In this situation, xar will strip setuid/setgid bits from the extracted files for security reasons. \-\-keep-setuid will preserve the setuid/setgid bits even though the uid/gid of the extracted file is not the same as the archived file. .SH EXAMPLES .TP xar -cf sample.xar /home/uid Create a xar archive of all files in /home/uid .TP xar -tf sample.xar List the contents of the xar archive sample.xar .TP xar -xf sample.xar Extract the contents of sample.xar to the current working directory .SH BUGS .TP Doesn't currently work with pipes or streams. Might be fixed in a future release. .TP Probably one or two more somewhere in there. If you find one please report it to http://code.google.com/p/xar/ .SH AUTHORS Rob Braun .br Landon Fuller .br David Leimbach .br Kevin Van Vechten xar-xar-498/xar/src/xar.c000066400000000000000000001025121446633275300153170ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xar_internal.h" #include "config.h" #include "filetree.h" #include "util.h" #define SYMBOLIC 1 #define NUMERIC 2 static int Perms = 0; static int Local = 0; static char *Subdoc = NULL; static char *SubdocName = NULL; static char *Toccksum = NULL; static char *Filecksum = NULL; static char *Compression = NULL; static char *Rsize = NULL; static char *CompressionArg = NULL; static char *Chdir = NULL; static int Err = 0; static int List = 0; static int Verbose = 0; static int Coalesce = 0; static int LinkSame = 0; static int NoOverwrite = 0; static int SaveSuid = 0; struct lnode { char *str; regex_t reg; struct lnode *next; }; struct lnode *Exclude = NULL; struct lnode *Exclude_Tail = NULL; struct lnode *NoCompress = NULL; struct lnode *NoCompress_Tail = NULL; struct lnode *PropInclude = NULL; struct lnode *PropInclude_Tail = NULL; struct lnode *PropExclude = NULL; struct lnode *PropExclude_Tail = NULL; static int32_t err_callback(int32_t sev, int32_t err, xar_errctx_t ctx, void *usrctx); static void print_file(xar_t x, xar_file_t f) { if( List && Verbose ) { char *size = xar_get_size(x, f); char *path = xar_get_safe_path(f); char *type = xar_get_type(x, f); char *mode = xar_get_mode(x, f); char *user = xar_get_owner(x, f); char *group = xar_get_group(x, f); char *mtime = xar_get_mtime(x, f); printf("%s %8s/%-8s %10s %s %s\n", mode, user, group, size, mtime, path); free(size); free(type); free(path); free(mode); free(user); free(group); free(mtime); } else if( List || Verbose ) { char *path = xar_get_safe_path(f); if (xar_path_issane(path) == 0) printf("Warning, archive contains invalid path: %s\n", path); else printf("%s\n", path); free(path); } } static void add_subdoc(xar_t x) { xar_subdoc_t s; int fd; unsigned char *buf; unsigned int len; struct stat sb; if( SubdocName == NULL ) SubdocName = "subdoc"; fd = open(Subdoc, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "ERROR: subdoc file %s doesn't exist. Ignoring.\n", Subdoc); return; } s = xar_subdoc_new(x, (const char *)SubdocName); fstat(fd, &sb); len = sb.st_size; buf = malloc(len+1); if( buf == NULL ) { close(fd); return; } memset(buf, 0, len+1); read(fd, buf, len); close(fd); xar_subdoc_copyin(s, buf, len); return; } static void extract_subdoc(xar_t x, const char *name) { xar_subdoc_t i; for( i = xar_subdoc_first(x); i; i = xar_subdoc_next(i) ) { const char *sname = xar_subdoc_name(i); unsigned char *sdoc; int fd, size; if( name && strcmp(name, sname) != 0 ) continue; xar_subdoc_copyout(i, &sdoc, (unsigned int *)&size); fd = open(Subdoc, O_WRONLY|O_CREAT|O_TRUNC, 0644); if( fd < 0 ) return; write(fd, sdoc, size); close(fd); free(sdoc); } return; } static int archive(const char *filename, int arglen, char *args[]) { xar_t x; FTS *fts; FTSENT *ent; int flags; struct lnode *i; const char *default_compression; x = xar_open(filename, WRITE); if( !x ) { fprintf(stderr, "Error creating archive %s\n", filename); exit(1); } if( Toccksum ) xar_opt_set(x, XAR_OPT_TOCCKSUM, Toccksum); if( Filecksum ) xar_opt_set(x, XAR_OPT_FILECKSUM, Filecksum); if( CompressionArg ) xar_opt_set(x, XAR_OPT_COMPRESSIONARG, CompressionArg); if( Compression ) xar_opt_set(x, XAR_OPT_COMPRESSION, Compression); if( Coalesce ) xar_opt_set(x, XAR_OPT_COALESCE, "true"); if( LinkSame ) xar_opt_set(x, XAR_OPT_LINKSAME, "true"); if ( Rsize != NULL ) xar_opt_set(x, XAR_OPT_RSIZE, Rsize); xar_register_errhandler(x, err_callback, NULL); for( i = PropInclude; i; i=i->next ) { xar_opt_set(x, XAR_OPT_PROPINCLUDE, i->str); } for( i = PropExclude; i; i=i->next ) { xar_opt_set(x, XAR_OPT_PROPEXCLUDE, i->str); } if( Subdoc ) add_subdoc(x); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } default_compression = strdup(xar_opt_get(x, XAR_OPT_COMPRESSION)); if( !default_compression ) default_compression = strdup(XAR_OPT_VAL_GZIP); flags = FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR; if( Local ) flags |= FTS_XDEV; fts = fts_open(args, flags, NULL); if( !fts ) { fprintf(stderr, "Error traversing file tree\n"); exit(1); } while( (ent = fts_read(fts)) ) { xar_file_t f; int exclude_match = 1; int nocompress_match = 1; if( ent->fts_info == FTS_DP ) continue; if( strcmp(ent->fts_path, "/") == 0 ) continue; if( strcmp(ent->fts_path, ".") == 0 ) continue; for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", ent->fts_path); continue; } for( i = NoCompress; i; i=i->next ) { nocompress_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !nocompress_match ) { xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE); break; } } f = xar_add(x, ent->fts_path); if( !f ) { fprintf(stderr, "Error adding file %s\n", ent->fts_path); } else { print_file(x, f); } if( !nocompress_match ) xar_opt_set(x, XAR_OPT_COMPRESSION, default_compression); } fts_close(fts); if( xar_close(x) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } free((char *)default_compression); for( i = Exclude; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } for( i = NoCompress; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } return Err; } static int extract(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t iter; xar_file_t f; int files_extracted = 0; int argi; struct lnode *extract_files = NULL; struct lnode *extract_tail = NULL; struct lnode *lnodei = NULL; struct lnode *dirs = NULL; for(argi = 0; args[argi]; argi++) { struct lnode *tmp; int err; tmp = malloc(sizeof(struct lnode)); tmp->str = strdup(args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( extract_files == NULL ) { extract_files = tmp; extract_tail = tmp; } else { extract_tail->next = tmp; extract_tail = tmp; } /* Add a clause for recursive extraction */ tmp = malloc(sizeof(struct lnode)); asprintf(&tmp->str, "%s/.*", args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( extract_files == NULL ) { extract_files = tmp; extract_tail = tmp; } else { extract_tail->next = tmp; extract_tail = tmp; } } x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } if(Chdir) { if( chdir(Chdir) != 0 ) { fprintf(stderr, "Unable to chdir to %s\n", Chdir); exit(1); } } xar_register_errhandler(x, err_callback, NULL); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } if ( Rsize != NULL ) { xar_opt_set(x, XAR_OPT_RSIZE, Rsize); } if( SaveSuid ) { xar_opt_set(x, XAR_OPT_SAVESUID, XAR_OPT_VAL_TRUE); } iter = xar_iter_new(); if( !iter ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, iter); f; f = xar_file_next(iter)) { int matched = 0; int exclude_match = 1; struct lnode *i; char *path = xar_get_safe_path(f); char *unsafe_path = xar_get_path(f); // To not break anyone, also match our regex on the bogus path. // Check to see if this file is a symlink const char* type = NULL; xar_prop_get(f, "type", &type); if( type == NULL ) { if (Verbose) printf("Warning, not extracting file \"%s\" because we can't get it's type.\n", path); free(path); free(unsafe_path); continue; } // Sanity check if we have a symlink, that it's a valid path. const char* kSymlinkName = "symlink"; // Why there is no const for this I have no idea. if (strncmp(kSymlinkName, type, strlen(kSymlinkName)) == 0) { if (XAR_FILE(f)->children != NULL) { if (Verbose) printf("Warning, children of \"%s\" will not extract because it's a symlink.\n", path); XAR_ITER(iter)->nochild = 1; // Do no extract children of a symlink } } // This includes a null check if (!xar_path_issane(path)) { if (Verbose) printf("Warning, not extracting file \"%s\" because it's path is invalid.\n", path); free(path); free(unsafe_path); continue; } if( args[0] ) { for(i = extract_files; i != NULL; i = i->next) { int extract_match = 1; extract_match = regexec(&i->reg, path, 0, NULL, 0); if( !extract_match ) { matched = 1; break; } // Compat with broken archives. extract_match = regexec(&i->reg, unsafe_path, 0, NULL, 0); if( !extract_match ) { matched = 1; break; } } } else { matched = 1; } for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, path, 0, NULL, 0); if( !exclude_match ) break; exclude_match = regexec(&i->reg, unsafe_path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", path); free(path); free(unsafe_path); continue; } if( matched ) { struct stat sb; if( NoOverwrite && (lstat(path, &sb) == 0) ) { printf("%s already exists, not overwriting\n", path); } else { const char *prop = NULL; int deferred = 0; if( xar_prop_get(f, "type", &prop) == 0 && prop != NULL ) { if( strcmp(prop, "directory") == 0 ) { struct lnode *tmpl = calloc(sizeof(struct lnode),1); tmpl->str = (char *)f; tmpl->next = dirs; dirs = tmpl; deferred = 1; } } if( ! deferred ) { files_extracted++; print_file(x, f); xar_extract(x, f); } } } free(path); free(unsafe_path); } for(lnodei = dirs; lnodei; lnodei = lnodei->next) { files_extracted++; print_file(x,(xar_file_t)lnodei->str); xar_extract(x, (xar_file_t)lnodei->str); } if( args[0] && (files_extracted == 0) ) { fprintf(stderr, "No files matched extraction criteria.\n"); Err = 3; } if( Subdoc ) extract_subdoc(x, NULL); xar_iter_free(iter); if( xar_close(x) != 0 ) { fprintf(stderr, "Error extracting the archive\n"); if( !Err ) Err = 42; } for(lnodei = extract_files; lnodei != NULL; ) { struct lnode *tmp; free(lnodei->str); regfree(&lnodei->reg); tmp = lnodei; lnodei = lnodei->next; free(tmp); } return Err; } static int list_subdocs(const char *filename) { xar_t x; xar_subdoc_t s; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } for(s = xar_subdoc_first(x); s; s = xar_subdoc_next(s)) { printf("%s\n", xar_subdoc_name(s)); } xar_close(x); return Err; } static int list(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; int argi = 0; struct lnode *list_files = NULL; struct lnode *list_tail = NULL; struct lnode *lnodei = NULL; for(argi = 0; args[argi]; argi++) { struct lnode *tmp; int err; tmp = malloc(sizeof(struct lnode)); tmp->str = strdup(args[argi]); tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( list_files == NULL ) { list_files = tmp; list_tail = tmp; } else { list_tail->next = tmp; list_tail = tmp; } } x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { int matched = 0; if( args[0] ) { char *path = xar_get_safe_path(f); char *unsafe_path = xar_get_path(f); if (xar_path_issane(path) == 0) { fprintf(stderr, "Warning, archive contains invalid path: %s\n", path); free(path); continue; } for(lnodei = list_files; lnodei != NULL; lnodei = lnodei->next) { int list_match = 1; list_match = regexec(&lnodei->reg, path, 0, NULL, 0); if( !list_match ) { matched = 1; break; } list_match = regexec(&lnodei->reg, unsafe_path, 0, NULL, 0); if( !list_match ) { matched = 1; break; } } free(path); free(unsafe_path); } else { matched = 1; } if( matched ) print_file(x, f); } xar_iter_free(i); xar_close(x); for(lnodei = list_files; lnodei != NULL; ) { struct lnode *tmp; free(lnodei->str); regfree(&lnodei->reg); tmp = lnodei; lnodei = lnodei->next; free(tmp); } return Err; } static int dumptoc(const char *filename, const char* tocfile) { xar_t x; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_serialize(x, tocfile); xar_close(x); return Err; } static int dump_toc_chksum(const char *filename) { xar_t x; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } // locate data to sign const char *value; if( 0 != xar_prop_get_expect_notnull((xar_file_t)x, "checksum/offset" ,&value) ) { fprintf(stderr, "Could not locate checksum/offset in archive.\n"); exit(1); } uint32_t dataToSignOffset = xar_get_heap_offset(x); dataToSignOffset += strtoull(value, (char **)NULL, 10); if( 0 != xar_prop_get_expect_notnull((xar_file_t)x, "checksum/size" ,&value) ) { fprintf(stderr, "Could not locate checksum/size in archive.\n"); exit(1); } uint32_t dataToSignSize = strtoull(value, (char **)NULL, 10); xar_close(x); // now get data to be signed, using offset and size FILE *file = fopen(filename, "r"); if (!file) { fprintf(stderr, "Could not open %s for reading data to sign!\n", filename); exit(1); } fseek(file, dataToSignOffset, SEEK_SET); unsigned char *buffer = malloc(dataToSignSize); int i = fread(buffer, dataToSignSize, 1, file); if (i != 1) { fprintf(stderr, "Failed to read data to sign from %s!\n", filename); exit(1); } printf("Checksum: "); for (int i = 0; i < dataToSignSize; i++) printf("%02x", buffer[i]); printf("\n"); free(buffer); xar_header_t xh; fseek(file, 0, SEEK_SET); i = fread(&xh, sizeof(xh), 1, file); printf("Algorithm: "); switch( ntohl(xh.cksum_alg) ) { case XAR_CKSUM_NONE: printf("NONE\n"); break; case XAR_CKSUM_SHA1: printf("SHA1\n"); break; case XAR_CKSUM_SHA256: printf("SHA256\n"); break; case XAR_CKSUM_SHA512: printf("SHA512\n"); break; case XAR_CKSUM_MD5: printf("MD5\n"); break; default: printf("UNKNOWN\n"); break; } fflush(stdout); fclose(file); return 0; } static int dump_header(const char *filename) { int fd; xar_header_t xh; if(filename == NULL) fd = 0; else { fd = open(filename, O_RDONLY); if( fd < 0 ) { perror("open"); exit(1); } } if( read(fd, &xh, sizeof(xh)) < sizeof(xh) ) { fprintf(stderr, "error reading header\n"); exit(1); } printf("magic: 0x%x ", ntohl(xh.magic)); if( ntohl(xh.magic) != XAR_HEADER_MAGIC ) printf("(BAD)\n"); else printf("(OK)\n"); printf("size: %d\n", ntohs(xh.size)); printf("version: %d\n", ntohs(xh.version)); printf("Compressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_compressed)); printf("Uncompressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_uncompressed)); printf("Checksum algorithm: %d ", ntohl(xh.cksum_alg)); switch( ntohl(xh.cksum_alg) ) { case XAR_CKSUM_NONE: printf("(unsupported (none))\n"); break; case XAR_CKSUM_SHA1: printf("(SHA1)\n"); break; case XAR_CKSUM_SHA256: printf("(SHA256)\n"); break; case XAR_CKSUM_SHA512: printf("(SHA512)\n"); break; #ifdef XAR_SUPPORT_MD5 case XAR_CKSUM_MD5: printf("(MD5)\n"); break; #else case XAR_CKSUM_MD5: printf("(unsupported (MD5))\n"); break; #endif // XAR_SUPPORT_MD5 default: printf("(unknown)\n"); break; }; return 0; } static int32_t err_callback(int32_t sev, int32_t err, xar_errctx_t ctx, void *usrctx) { xar_file_t f; xar_t x; const char *str; int e; x = xar_err_get_archive(ctx); f = xar_err_get_file(ctx); str = xar_err_get_string(ctx); e = xar_err_get_errno(ctx); switch(sev) { case XAR_SEVERITY_DEBUG: case XAR_SEVERITY_INFO: break; case XAR_SEVERITY_WARNING: printf("%s\n", str); break; case XAR_SEVERITY_NORMAL: if( (err = XAR_ERR_ARCHIVE_CREATION) && f ) print_file(x, f); break; case XAR_SEVERITY_NONFATAL: case XAR_SEVERITY_FATAL: Err = 2; printf("Error while "); if( err == XAR_ERR_ARCHIVE_CREATION ) printf("creating"); if( err == XAR_ERR_ARCHIVE_EXTRACTION ) printf("extracting"); printf(" archive"); if( f ) { const char *file = xar_get_safe_path(f); if( file ) printf(":(%s)", file); free((char *)file); } if( str ) printf(": %s", str); if( err && e ) printf(" (%s)", strerror(e)); if( sev == XAR_SEVERITY_NONFATAL ) { printf(" - ignored"); printf("\n"); } else { printf("\n"); exit(1); } break; } return 0; } static void usage(const char *prog) { fprintf(stderr, "DEPRECATION WARNING:\n" "\txar is no longer under active development by Apple.\n" "\tClients of xar should pursue alternative archive formats.\n\n"); fprintf(stderr, "Usage: %s -[ctx][v] -f ...\n", prog); fprintf(stderr, "\t-c Creates an archive\n"); fprintf(stderr, "\t-x Extracts an archive\n"); fprintf(stderr, "\t-t Lists an archive\n"); fprintf(stderr, "\t-f Specifies an archive to operate on [REQUIRED!]\n"); fprintf(stderr, "\t-v Print filenames as they are archived\n"); fprintf(stderr, "\t-C On extract, chdir to this location\n"); fprintf(stderr, "\t-n name Provides a name for a subdocument\n"); fprintf(stderr, "\t-s On extract, specifies the file to extract\n"); fprintf(stderr, "\t subdocuments to.\n"); fprintf(stderr, "\t On archival, specifies an xml file to add\n"); fprintf(stderr, "\t as a subdocument.\n"); fprintf(stderr, "\t-l On archival, stay on the local device.\n"); fprintf(stderr, "\t-p On extract, set ownership based on symbolic\n"); fprintf(stderr, "\t names, if possible.\n"); fprintf(stderr, "\t-P On extract, set ownership based on uid/gid.\n"); fprintf(stderr, "\t--toc-cksum Specifies the hashing algorithm to use for\n"); fprintf(stderr, "\t xml header verification.\n"); #ifdef XAR_SUPPORT_MD5 fprintf(stderr, "\t Valid values: md5, sha1, sha256, and sha512\n"); #else fprintf(stderr, "\t Valid values: sha1, sha256, and sha512\n"); #endif // XAR_SUPPORT_MD5 fprintf(stderr, "\t Default: sha1\n"); fprintf(stderr, "\t--file-cksum Specifies the hashing algorithm to use for\n"); fprintf(stderr, "\t file content verification.\n"); #ifdef XAR_SUPPORT_MD5 fprintf(stderr, "\t Valid values: md5, sha1, sha256, and sha512\n"); #else fprintf(stderr, "\t Valid values: sha1, sha256, and sha512\n"); #endif fprintf(stderr, "\t Default: sha1\n"); fprintf(stderr, "\t--dump-toc-cksum Prints out the ToC chksum in hex.\n"); fprintf(stderr, "\t The output is a hash of the ToC generated.\n"); fprintf(stderr, "\t Also prints out the algorithm used.\n"); fprintf(stderr, "\t by the checksum algorithm used during xar creation.\n"); fprintf(stderr, "\t--dump-toc= Has xar dump the xml header into the\n"); fprintf(stderr, "\t specified file.\n"); fprintf(stderr, "\t--dump-header Prints out the xar binary header information\n"); fprintf(stderr, "\t--compression Specifies the compression type to use.\n"); fprintf(stderr, "\t Valid values: none, gzip, bzip2, lzma\n"); fprintf(stderr, "\t Default: gzip\n"); fprintf(stderr, "\t-a Synonym for \"--compression=lzma\"\n"); fprintf(stderr, "\t-j Synonym for \"--compression=bzip2\"\n"); fprintf(stderr, "\t-z Synonym for \"--compression=gzip\"\n"); fprintf(stderr, "\t--compression-args=arg Specifies arguments to be passed\n"); fprintf(stderr, "\t to the compression engine.\n"); fprintf(stderr, "\t--compress-heap Compress entire heap instead of individual files.\n"); fprintf(stderr, "\t Currently limited to gzip compression.\n"); fprintf(stderr, "\t--list-subdocs List the subdocuments in the xml header\n"); fprintf(stderr, "\t--extract-subdoc=name Extracts the specified subdocument\n"); fprintf(stderr, "\t to a document in cwd named .xml\n"); fprintf(stderr, "\t--exclude POSIX regular expression of files to \n"); fprintf(stderr, "\t ignore while archiving.\n"); fprintf(stderr, "\t--rsize Specifies the size of the buffer used\n"); fprintf(stderr, "\t for read IO operations in bytes.\n"); fprintf(stderr, "\t--coalesce-heap When archived files are identical, only store one copy\n"); fprintf(stderr, "\t This option creates an archive which\n"); fprintf(stderr, "\t is not streamable\n"); fprintf(stderr, "\t--link-same Hardlink identical files\n"); fprintf(stderr, "\t--no-compress POSIX regular expression of files\n"); fprintf(stderr, "\t to archive, but not compress.\n"); fprintf(stderr, "\t--prop-include File properties to include in archive\n"); fprintf(stderr, "\t--prop-exclude File properties to exclude in archive\n"); fprintf(stderr, "\t--distribution Only includes a subset of file properties\n"); fprintf(stderr, "\t appropriate for archive distribution\n"); fprintf(stderr, "\t--keep-existing Do not overwrite existing files while extracting\n"); fprintf(stderr, "\t-k Synonym for --keep-existing\n"); fprintf(stderr, "\t--keep-setuid Preserve the suid/sgid bits when extracting\n"); fprintf(stderr, "\t--version Print xar's version number\n"); return; } static void print_version() { printf("xar %s\n", XAR_VERSION); } int main(int argc, char *argv[]) { int ret; char *filename = NULL; char command = 0, c; char **args; const char *tocfile = NULL; int arglen, i, err; xar_t x; int loptind = 0; int required_dash_f = 0; /* This release requires us to use -f */ struct lnode *tmp; long int longtmp; struct option o[] = { {"toc-cksum", required_argument, 0, 1}, {"file-cksum", required_argument, 0, 19}, // out of order to avoid regressions {"dump-toc", required_argument, 0, 'd'}, {"dump-toc-cksum", no_argument, 0, 20}, {"compression", required_argument, 0, 2}, {"list-subdocs", no_argument, 0, 3}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 4}, {"dump-header", no_argument, 0, 5}, {"extract-subdoc", required_argument, 0, 6}, {"exclude", required_argument, 0, 7}, {"rsize", required_argument, 0, 8}, {"coalesce-heap", no_argument, 0, 9}, {"link-same", no_argument, 0, 10}, {"no-compress", required_argument, 0, 11}, {"prop-include", required_argument, 0, 12}, {"prop-exclude", required_argument, 0, 13}, {"distribution", no_argument, 0, 14}, {"keep-existing", no_argument, 0, 15}, {"keep-setuid", no_argument, 0, 16}, {"compression-args", required_argument, 0, 17}, { 0, 0, 0, 0} }; if( argc < 2 ) { usage(argv[0]); exit(1); } while( (c = getopt_long(argc, argv, "axcC:vtjzf:hpPln:s:d:vk", o, &loptind)) != -1 ) { switch(c) { case 1 : // toc-cksum if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && #ifdef XAR_SUPPORT_MD5 (strcmp(optarg, XAR_OPT_VAL_MD5) != 0) && #endif // XAR_SUPPORT_MD5 (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA256) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA512) != 0) ) { usage(argv[0]); exit(1); } Toccksum = optarg; break; case 20: command = 20; break; case 19 : // file-cksum if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && #ifdef XAR_SUPPORT_MD5 (strcmp(optarg, XAR_OPT_VAL_MD5) != 0) && #endif // XAR_SUPPORT_MD5 (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA256) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA512) != 0) ) { usage(argv[0]); exit(1); } Filecksum = optarg; break; case 2 : // compression if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && (strcmp(optarg, XAR_OPT_VAL_GZIP) != 0) && (strcmp(optarg, XAR_OPT_VAL_BZIP) != 0) && (strcmp(optarg, XAR_OPT_VAL_LZMA) != 0) ) { usage(argv[0]); exit(1); } Compression = optarg; break; case 3 : // list-subdocs if( command && (command != 3) ) { fprintf(stderr, "Conflicting commands specified\n"); exit(1); } command = 3; break; case 4 : // version print_version(); exit(0); case 'd': // dump-toc if( !optarg ) { usage(argv[0]); exit(1); } tocfile = optarg; command = 'd'; break; case 5 : // dump-header command = 5; break; case 6 : // extract-subdoc SubdocName = optarg; asprintf(&Subdoc, "%s.xml", SubdocName); if( !command ) command = 6; break; case 7 : // exclude tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( Exclude == NULL ) { Exclude = tmp; Exclude_Tail = tmp; } else { Exclude_Tail->next = tmp; Exclude_Tail = tmp; } break; case 8 : // rsize if ( !optarg ) { usage(argv[0]); exit(1); } longtmp = strtol(optarg, NULL, 10); if( (((longtmp == LONG_MIN) || (longtmp == LONG_MAX)) && (errno == ERANGE)) || (longtmp < 1) ) { fprintf(stderr, "Invalid rsize value: %s\n", optarg); exit(5); } Rsize = optarg; break; case 9 : Coalesce = 1; break; // coalesce-heap case 10 : LinkSame = 1; break; // link-same case 11 : // no-compress tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( NoCompress == NULL ) { NoCompress = tmp; NoCompress_Tail = tmp; } else { NoCompress_Tail->next = tmp; NoCompress_Tail = tmp; } break; case 12 : // prop-include tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; if( PropInclude == NULL ) { PropInclude = tmp; PropInclude_Tail = tmp; } else { PropInclude_Tail->next = tmp; PropInclude_Tail = tmp; } break; case 13 : // prop-exclude tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; if( PropExclude == NULL ) { PropExclude = tmp; PropExclude_Tail = tmp; } else { PropExclude_Tail->next = tmp; PropExclude_Tail = tmp; } break; case 14 : // distribution { char *props[] = { "type", "data", "mode", "name" }; int i; for( i = 0; i < 4; i++ ) { tmp = malloc(sizeof(struct lnode)); tmp->str = strdup(props[i]); tmp->next = NULL; if( PropInclude == NULL ) { PropInclude = tmp; PropInclude_Tail = tmp; } else { PropInclude_Tail->next = tmp; PropInclude_Tail = tmp; } } } break; case 'k': // keep-existing case 15 : NoOverwrite++; break; case 16 : // keep-setuid SaveSuid++; break; case 17 : // compression-args CompressionArg = optarg; break; case 'C': // chdir to if( !optarg ) { usage(argv[0]); exit(1); } Chdir = optarg; break; case 'c': // create case 'x': // extract case 't': // list if( command && (command != 's') ) { usage(argv[0]); fprintf(stderr, "Conflicting command flags: %c and %c specified\n", c, command); exit(1); } if( c == 't' ) List = 1; command = c; break; case 'a': Compression = "lzma"; break; case 'j': Compression = "bzip2"; break; case 'z': Compression = "gzip"; break; case 'f': // filename required_dash_f = 1; filename = optarg; break; case 'p': // set ownership based on symbolic names (if possible) Perms = SYMBOLIC; break; case 'P': // set ownership based on uid/gid Perms = NUMERIC; break; case 'l': // stay on local device Local = 1; break; case 'n': // provide subdocument name SubdocName = optarg; break; case 's': // extract subdocuments to/add subdocuments from Subdoc = optarg; if( !command ) command = 's'; break; case 'v': // print filenames Verbose++; break; case 'h': // help default: usage(argv[0]); exit(1); } } if (! required_dash_f) { usage(argv[0]); fprintf(stderr, "\n -f option is REQUIRED\n"); exit(1); } switch(command) { case 5 : return dump_header(filename); case 3 : return list_subdocs(filename); case 'c': if( optind == argc ) { usage(argv[0]); fprintf(stderr, "No files to operate on.\n"); exit(1); } arglen = argc - optind; args = malloc(sizeof(char*) * (arglen+1)); memset(args, 0, sizeof(char*) * (arglen+1)); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); return archive(filename, arglen, args); case 'd': if( !tocfile ) { usage(argv[0]); exit(1); } return dumptoc(filename, tocfile); case 20: if( !required_dash_f ) { usage(argv[0]); exit(1); } return dump_toc_chksum(filename); break; case 'x': arglen = argc - optind; args = malloc(sizeof(char*) * (arglen+1)); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); args[i] = NULL; return extract(filename, arglen, args); case 't': arglen = argc - optind; args = calloc(sizeof(char*) * (arglen+1),1); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); ret = list(filename, arglen, args); for( i = 0; i < arglen; i++ ) free(args[i]); case 6 : case 's': x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_register_errhandler(x, err_callback, NULL); extract_subdoc(x, SubdocName); xar_close(x); exit(Err); break; default: usage(argv[0]); fprintf(stderr, "Unrecognized command.\n"); exit(1); } /* unreached */ exit(0); } xar-xar-498/xar/src/xar_internal.h000066400000000000000000000011331446633275300172150ustar00rootroot00000000000000// // xar_internal.h // xarLib // // Created by Jared Jones on 10/12/21. // #ifndef _XAR_INTERNAL_H_ #define _XAR_INTERNAL_H_ #ifdef XARSIG_BUILDING_WITH_XAR #include "xar.h" #else #include #endif // XARSIG_BUILDING_WITH_XAR // Undeprecate these for internal usage xar_t xar_open(const char *file, int32_t flags) API_AVAILABLE(macos(10.4)); xar_t xar_open_digest_verify(const char *file, int32_t flags, void *expected_toc_digest, size_t expected_toc_digest_len) API_AVAILABLE(macos(10.14.4)); char *xar_get_path(xar_file_t f) API_AVAILABLE(macos(10.4)); #endif /* _XAR_INTERNAL_H_ */ xar-xar-498/xar/test/000077500000000000000000000000001446633275300145505ustar00rootroot00000000000000xar-xar-498/xar/test/attr.py000077500000000000000000000116771446633275300161130ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import os.path import shutil import subprocess import xattr import util # Notes: # * Due to internal buffer sizing, "large" should be at least 4096 bytes for # uncompressed archives and archives with individual file compression, and # and at least 32768 bytes for archives with compressed heaps. # * For large files, we intentionally use a non-base-2 file size to ensure we # catch file extraction bugs for files with a size not equal to the internal # read buffer size (which is base-2). # * For large extended attributes, we do the same thing. # # Utility Functions # class MissingExtendedAttributeError(AssertionError): pass def _random_big_data(bytes=65536, path="/dev/random"): """ Returns a random string with the number of bytes requested. Due to xar implementation details, this should be greater than 4096 (32768 for compressed heap testing). """ with open(path, "r") as f: return f.read(bytes) def _test_xattr_on_file_with_contents(filename, file_contents, xattrs=[], xar_create_flags=[], xar_extract_flags=[]): try: # Write file out with open(filename, "w") as f: f.write(file_contents) for (key, value) in xattrs: xattr.setxattr(f, key, value) # Store it into a xarchive archive_name = "{f}.xar".format(f=filename) with util.archive_created(archive_name, filename, *xar_create_flags) as path: # Extract xarchive with util.directory_created("extracted") as directory: # Validate resulting xattrs subprocess.check_call(["xar", "-x", "-C", directory, "-f", path] + xar_extract_flags) for (key, value) in xattrs: try: assert xattr.getxattr(os.path.join(directory, filename), key) == value, "extended attribute \"{n}\" has incorrect contents after extraction".format(n=key) except KeyError: raise MissingExtendedAttributeError("extended attribute \"{n}\" missing after extraction".format(n=key)) # Validate file contents with open(os.path.join(directory, filename), "r") as f: if f.read() != file_contents: raise MissingExtendedAttributeError("archived file \"{f}\" has has incorrect contents after extraction".format(f=filename)) finally: os.unlink(filename) # # Test Cases # # Note: xar currently drops empty extended attributes (and any xar_prop_t with empty contents, actually). The empty # tests are commented out awaiting a day when this might be different. # def empty_xattr_empty_file(filename): # _test_xattr_on_file_with_contents(filename, "", xattrs=[("foo", "")]) def small_xattr_empty_file(filename): _test_xattr_on_file_with_contents(filename, "", xattrs=[("foo", "1234")]) def large_xattr_empty_file(filename): _test_xattr_on_file_with_contents(filename, "", xattrs=[("foo", _random_big_data(5000))]) # def empty_xattr_small_file(filename): # _test_xattr_on_file_with_contents(filename, "small.file.contents", xattrs=[("foo", "")]) def small_xattr_small_file(filename): _test_xattr_on_file_with_contents(filename, "small.file.contents", xattrs=[("foo", "1234")]) def large_xattr_small_file(filename): _test_xattr_on_file_with_contents(filename, "small.file.contents", xattrs=[("foo", _random_big_data(4567))]) # def empty_xattr_large_file(filename): # _test_xattr_on_file_with_contents(filename, _random_big_data(10000000), xattrs=[("foo", "")]) def small_xattr_large_file(filename): _test_xattr_on_file_with_contents(filename, _random_big_data(5000000), xattrs=[("foo", "1234")]) def large_xattr_large_file(filename): _test_xattr_on_file_with_contents(filename, _random_big_data(9876543), xattrs=[("foo", _random_big_data(6543))]) def multiple_xattrs(filename): _test_xattr_on_file_with_contents(filename, "", xattrs=[("foo", "bar"), ("baz", "1234"), ("quux", "more")]) # ("empty", "") def distribution_create(filename): try: _test_xattr_on_file_with_contents(filename, "dummy", xattrs=[("foo", "bar")], xar_create_flags=["--distribution"]) except MissingExtendedAttributeError: pass else: raise AssertionError("no error encountered") # Note: xar currently has no way to exclude a property on extraction. This test is commented out awaiting the day # when it can. # def distribution_extract(filename): # try: # _test_xattr_on_file_with_contents(filename, "dummy", xattrs=[("foo", "bar")], xar_extract_flags=["--distribution"]) # except MissingExtendedAttributeError: # pass # else: # raise AssertionError("no error encountered") TEST_CASES = (small_xattr_empty_file, large_xattr_empty_file, small_xattr_small_file, large_xattr_small_file, small_xattr_large_file, large_xattr_large_file, multiple_xattrs, distribution_create) if __name__ == "__main__": for case in TEST_CASES: try: case(case.func_name) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") xar-xar-498/xar/test/buffer.c000066400000000000000000000027741446633275300161770ustar00rootroot00000000000000#include #include #include #include #include #include int32_t err_callback(int32_t sev, int32_t err, xar_errctx_t ctx, void *usrctx) { printf("error callback invoked\n"); return 0; } int main(int argc, char *argv[]) { int fd; unsigned char *buffer; struct stat sb; ssize_t red; xar_t x; xar_file_t f, f2; if( argc < 2 ) { fprintf(stderr, "usage: %s \n", argv[0]); exit(1); } fd = open(argv[1], O_RDONLY); if( fd < 0 ) { fprintf(stderr, "Unable to open file %s\n", argv[1]); exit(2); } if( fstat(fd, &sb) < 0 ) { fprintf(stderr, "Unable to stat file %s\n", argv[1]); exit(3); } buffer = malloc(sb.st_size); if( buffer == NULL ) { fprintf(stderr, "Unable to allocate memory\n"); exit(4); } red = read(fd, buffer, sb.st_size); if( red <= 0 ) { fprintf(stderr, "Error reading from file\n"); exit(5); } if( red < sb.st_size ) fprintf(stderr, "Incomplete read\n"); x = xar_open("/tmp/test.xar", WRITE); if( x == NULL ) { fprintf(stderr, "Error creating xarchive\n"); exit(6); } xar_register_errhandler(x, err_callback, NULL); memset(&sb, 0, sizeof(sb)); sb.st_mode = S_IFDIR | S_IRWXU; f = xar_add_folder(x, NULL, "mydir", &sb); if( !f ) { fprintf(stderr, "Error adding parent to archive\n"); exit(7); } f2 = xar_add_frombuffer(x, f, "secondfile", buffer, red); if( !f ) { fprintf(stderr, "Error adding child to archive\n"); exit(8); } xar_close(x); close(fd); exit(0); } xar-xar-498/xar/test/checksums.py000077500000000000000000000203761446633275300171220ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import hashlib import os import os.path import re import shutil import struct import subprocess import util # # Utility Functions # def _get_numeric_value_from_header(archive_name, key): """ Dumps the header of the specified xar archive and extracts the header size from the output, in bytes. """ header = subprocess.check_output(["xar", "--dump-header", "-f", archive_name]) for line in header.splitlines(): matchdata = re.match("^(.+):\s+(.+)$", line) # magic: 0x78617221 (OK) assert matchdata, "unexpected output from `xar --dump-header`:\n{h}".format(h=header) if matchdata.groups()[0] == key: return int(matchdata.groups()[1]) raise AssertionError("no \"{k}\" found for archive \"{n}\":\n{h}".format(k=key, n=archive_name, h=header)) def _get_header_size(archive_name): return _get_numeric_value_from_header(archive_name, "size") def _get_toc_size(archive_name): return _get_numeric_value_from_header(archive_name, "Compressed TOC length") def _clobber_bytes_at(clobber_range, path): with open(path, "r+") as f: f.seek(clobber_range[0]) with open("/dev/random", "r") as r: random_bytes = r.read(len(clobber_range)) f.write(random_bytes) def _verify_extraction_failed(filename): with util.directory_created("extracted") as directory: try: with open("/dev/null", "w") as n: returncode = subprocess.call(["xar", "-x", "-C", directory, "-f", filename], stdout=n, stderr=n) assert returncode != 0, "xar reported success extracting an archive with a broken TOC" finally: if os.path.exists(directory): shutil.rmtree(directory) def _hex_digest_string(raw_digest): unpack_string = "B" * len(raw_digest) format_string = "%02x" * len(raw_digest) return format_string % struct.unpack(unpack_string, raw_digest) def _verify_header_checksum(filename, algorithm): header_size = _get_header_size(filename) toc_length = _get_toc_size(filename) with open(filename, "r") as f: f.seek(header_size) h = hashlib.new(algorithm, f.read(toc_length)) computed_digest = h.digest() # We intentionally ignore the TOC-specified offset. We should build a variant of this that uses the TOC # offset so we check both. stored_digest = f.read(len(computed_digest)) assert computed_digest == stored_digest, "Digests don't match: expected value {d1} != stored value {d2}".format(d1=_hex_digest_string(computed_digest), d2=_hex_digest_string(stored_digest)) # # Test Cases # def default_toc_checksum_validity(filename): with util.archive_created(filename, "/bin") as path: _verify_header_checksum(path, "sha1") def sha1_toc_checksum_validity(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha1") as path: _verify_header_checksum(path, "sha1") def sha256_toc_checksum_validity(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha256") as path: _verify_header_checksum(path, "sha256") def sha512_toc_checksum_validity(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha512") as path: _verify_header_checksum(path, "sha512") def broken_toc_default_checksum(filename): with util.archive_created(filename, "/bin") as path: # Mess up the archive toc_start = _get_header_size(path) _clobber_bytes_at(range(toc_start + 4, toc_start + 4 + 100), path) # Why did the original test specify 4? No idea. # Try to extract it _verify_extraction_failed(filename) def broken_toc_sha1_checksum(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha1") as path: # Mess up the archive toc_start = _get_header_size(path) _clobber_bytes_at(range(toc_start + 4, toc_start + 4 + 100), path) # Why did the original test specify 4? No idea. # Try to extract it _verify_extraction_failed(filename) def broken_toc_sha256_checksum(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha256") as path: # Mess up the archive toc_start = _get_header_size(path) _clobber_bytes_at(range(toc_start + 4, toc_start + 4 + 100), path) # Why did the original test specify 4? No idea. # Try to extract it _verify_extraction_failed(filename) def broken_toc_sha512_checksum(filename): with util.archive_created(filename, "/bin", "--toc-cksum", "sha512") as path: # Mess up the archive toc_start = _get_header_size(path) _clobber_bytes_at(range(toc_start + 4, toc_start + 4 + 100), path) # Why did the original test specify 4? No idea. # Try to extract it _verify_extraction_failed(filename) def broken_heap_default_checksum(filename): with util.archive_created(filename, "/bin") as path: # Mess up the archive toc_start = _get_header_size(path) toc_size = _get_toc_size(path) # Why 32? That's the size of the default sha256 checksum, which is stored before the heap. _clobber_bytes_at(range(toc_start + toc_size + 32, toc_start + toc_size + 32 + 100), path) # Try to extract it _verify_extraction_failed(filename) def default_checksum_algorithm(filename): with util.archive_created(filename, "/bin") as path: header = subprocess.check_output(["xar", "--dump-header", "-f", path]) found = False for line in header.splitlines(): matchdata = re.match("^Checksum algorithm:\s+(\d+)\s+\\((\w+)\\)$", line) if not matchdata: continue found = True algorithm = matchdata.groups()[1] assert algorithm == "SHA1", "unexpected checksum algorithm default: received {a}, expected SHA1".format(a=algorithm) assert found, "unexpected output from `xar --dump-header`:\n{h}".format(h=header) # Apparently, xar doesn't currently fail when given an invalid checksum algorithm. Something to fix later. # # def invalid_checksum_algorithm(filename): # try: # with util.archive_created(filename, "/bin", "--toc-cksum", "invalid-algorithm") as path: # raise AssertionError("xar succeeded when it should have failed") # except subprocess.CalledProcessError: # pass # It does fail for md5 explicitly, however def md5_toc_checksum_failure(filename): try: with open("/dev/null", "a") as devnull: with util.archive_created(filename, "/bin", "--toc-cksum", "md5", stderr=devnull) as path: raise AssertionError("xar succeeded when it should have failed") except subprocess.CalledProcessError: pass def md5_file_checksum_failure(filename): try: with open("/dev/null", "a") as devnull: with util.archive_created(filename, "/bin", "--file-cksum", "md5", stderr=devnull) as path: raise AssertionError("xar succeeded when it should have failed") except subprocess.CalledProcessError: pass def _verify_checksum_algorithm(filename, algorithm): additional_args = [] if algorithm: additional_args = ["--file-cksum", algorithm] else: algorithm = "sha1" with util.archive_created(filename, "/bin", *additional_args) as path: toc = subprocess.check_output(["xar", "--dump-toc=-", "-f", path]) found = False for line in toc.splitlines(): if ''.format(a=algorithm) in line or ''.format(a=algorithm) in line: break else: raise AssertionError("unexpected output from `xar --dump-toc=-`:\n{t}".format(t=toc)) def default_file_checksum_algorithm(filename): _verify_checksum_algorithm(filename, None) def sha1_file_checksum_algorithm(filename): _verify_checksum_algorithm(filename, "sha1") def sha256_file_checksum_algorithm(filename): _verify_checksum_algorithm(filename, "sha256") def sha512_file_checksum_algorithm(filename): _verify_checksum_algorithm(filename, "sha512") TEST_CASES = (default_toc_checksum_validity, sha1_toc_checksum_validity, sha256_toc_checksum_validity, sha512_toc_checksum_validity, broken_toc_default_checksum, broken_toc_sha1_checksum, broken_toc_sha256_checksum, broken_toc_sha512_checksum, broken_heap_default_checksum, default_checksum_algorithm, default_file_checksum_algorithm, sha1_file_checksum_algorithm, sha256_file_checksum_algorithm, sha512_file_checksum_algorithm, md5_toc_checksum_failure, md5_file_checksum_failure,) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") xar-xar-498/xar/test/compression.py000077500000000000000000000040731446633275300174720ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import cStringIO import os import os.path import subprocess import tempfile import util # # Utility Functions # def _check_compression(filename, *args, **kwargs): with util.archive_created(filename, "/bin", *args, **kwargs) as path: with util.directory_created("extracted") as directory: subprocess.check_call(["xar", "-x", "-f", path, "-C", directory]) util.assert_identical_directories("/bin", os.path.join(directory, "bin")) # # Test Cases # def no_compression(filename): _check_compression(filename, "--compression=none") def default_compression(filename): _check_compression(filename) def gzip_compression_long(filename): util.skip_if_no_compression_support("gzip") _check_compression(filename, "--compression=gzip") def gzip_compression_short(filename): util.skip_if_no_compression_support("gzip") _check_compression(filename, "-z") def bzip2_compression_long(filename): util.skip_if_no_compression_support("bzip2") _check_compression(filename, "--compression=bzip2") def bzip2_compression_short(filename): util.skip_if_no_compression_support("bzip2") _check_compression(filename, "-j") def lzma_compression_long(filename): util.skip_if_no_compression_support("lzma") _check_compression(filename, "--compression=lzma") def lzma_compression_short(filename): util.skip_if_no_compression_support("lzma") _check_compression(filename, "-a") TEST_CASES = (no_compression, default_compression, gzip_compression_long, bzip2_compression_long, lzma_compression_long, gzip_compression_short, bzip2_compression_short, lzma_compression_short) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") except util.TestCaseSkipError, e: print("SKIPPED: {f}: {m}".format(f=case.func_name, m=e.message)) xar-xar-498/xar/test/data.py000077500000000000000000000065331446633275300160450ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import contextlib import os import os.path import subprocess import util # # Utility Functions # @contextlib.contextmanager def _data_test(filename, *args, **kwargs): with util.directory_created("data_scratch") as directory: yield directory # Files are now created with util.archive_created("data.xar", "./data_scratch", *args, **kwargs) as path: _process_toc(path) with util.directory_created("data_extracted") as extracted: subprocess.check_call(["xar", "-x", "-f", path, "-C", extracted]) util.assert_identical_directories(directory, os.path.join(extracted, "data_scratch")) def _process_toc(archive_path): subprocess.check_call(["xar", "-f", archive_path, "--dump-toc=data_toc.xml"]) try: result = subprocess.check_output(["xsltproc", "-o", "-", os.path.realpath(os.path.join(__file__, "..", "data.xsl")), "data_toc.xml"]) assert result == "", "expected no data offset, but instead found:{o}".format(o=result) finally: os.unlink("data_toc.xml") def _zero_length(filename, *args, **kwargs): with _data_test(filename, *args, **kwargs) as directory: util.touch(os.path.join(directory, "empty")) # # Test Cases # def zero_length_default_compression(filename): _zero_length(filename) def zero_length_no_compression(filename): _zero_length(filename, "--compression=none") def zero_length_gzip_compression(filename): util.skip_if_no_compression_support("gzip") _zero_length(filename, "--compression=gzip") def zero_length_bzip2_compression(filename): util.skip_if_no_compression_support("bzip2") _zero_length(filename, "--compression=bzip2") def zero_length_lzma_compression(filename): util.skip_if_no_compression_support("lzma") _zero_length(filename, "--compression=lzma") def _mixed_length(filename, *args, **kwargs): with _data_test(filename, *args, **kwargs) as directory: util.touch(os.path.join(directory, "mixed_empty")) with open(os.path.join(directory, "mixed_small"), "w") as f: f.write("1234") def mixed_length_no_compression(filename): _mixed_length(filename, "--compression=none") def mixed_length_default_compression(filename): _mixed_length(filename) def mixed_length_gzip_compression(filename): util.skip_if_no_compression_support("gzip") _mixed_length(filename, "--compression=gzip") def mixed_length_bzip2_compression(filename): util.skip_if_no_compression_support("bzip2") _mixed_length(filename, "--compression=bzip2") def mixed_length_lzma_compression(filename): util.skip_if_no_compression_support("lzma") _mixed_length(filename, "--compression=lzma") TEST_CASES = (zero_length_default_compression, zero_length_no_compression, zero_length_gzip_compression, zero_length_bzip2_compression, zero_length_lzma_compression, mixed_length_no_compression, mixed_length_default_compression, mixed_length_gzip_compression, mixed_length_bzip2_compression, mixed_length_lzma_compression) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") except util.TestCaseSkipError, e: print("SKIPPED: {f}: {m}".format(f=case.func_name, m=e.message)) xar-xar-498/xar/test/data.xsl000066400000000000000000000003521446633275300162110ustar00rootroot00000000000000 xar-xar-498/xar/test/hardlink.py000077500000000000000000000051271446633275300167260ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import os.path import subprocess import util # # Utility Functions # def _assert_same_inodes(path1, path2): assert os.path.exists(path1), "missing hard-linked-file {p}".format(p=path1) assert os.path.exists(path1), "missing hard-linked-file {p}".format(p=path2) stat1 = os.lstat(path1) stat2 = os.lstat(path2) assert stat1.st_ino == stat2.st_ino, "inodes do not match for hard-linked files \"{p1}\" and \"{p2}\"".format(p1=path1, p2=path2) # # Test Cases # def hard_link_in_directory(filename): with util.directory_created("hardlink_scratch") as directory: util.touch(os.path.join(directory, "a")) os.link(os.path.join(directory, "a"), os.path.join(directory, "b")) with util.archive_created("hardlink_archive.xar", "hardlink_scratch") as path: with util.directory_created("hardlink_extracted") as extracted: subprocess.check_call(["xar", "-x", "-C", extracted, "-f", path]) _assert_same_inodes(os.path.join(extracted, "hardlink_scratch", "a"), os.path.join(extracted, "hardlink_scratch", "b")) def hard_link_in_cwd(filename): with util.directory_created("hardlink_scratch") as directory: with util.chdir(directory): util.touch("a") os.link("a", "b") with util.archive_created(os.path.join("..", "hardlink_archive.xar"), ".") as path: with util.directory_created(os.path.join("..", "hardlink_extracted")) as extracted: subprocess.check_call(["xar", "-x", "-C", extracted, "-f", path]) _assert_same_inodes(os.path.join(extracted, "a"), os.path.join(extracted, "b")) def hard_link_identical_files(filename): with util.directory_created("hardlink_scratch") as directory: with open(os.path.join(directory, "a"), "w") as f: f.write("1234samecontent") with open(os.path.join(directory, "b"), "w") as f: f.write("1234samecontent") with util.archive_created("hardlink_archive.xar", "hardlink_scratch", "--link-same") as path: with util.directory_created("hardlink_extracted") as extracted: subprocess.check_call(["xar", "-x", "-C", extracted, "-f", path]) _assert_same_inodes(os.path.join(extracted, "hardlink_scratch", "a"), os.path.join(extracted, "hardlink_scratch", "b")) TEST_CASES = (hard_link_in_directory, hard_link_in_cwd, hard_link_identical_files) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") xar-xar-498/xar/test/heap.py000077500000000000000000000050031446633275300160400ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import glob import os import os.path import re import shutil import subprocess import util # # Utility Functions # def _file_offsets_for_archive(path, xsl_path): subprocess.check_call(["xar", "--dump-toc=heap_toc.xml", "-f", path]) try: offsets = subprocess.check_output(["xsltproc", xsl_path, "heap_toc.xml"]) matches = [re.match("^(.+)\s([^\s]+)$", offset) for offset in offsets.splitlines()] offsets = [(match.groups()[0], int(match.groups()[1])) for match in matches] return offsets finally: os.unlink("heap_toc.xml") # # Test Cases # XSL_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "heap1.xsl") def normal_heap(filename): with util.directory_created("scratch") as directory: shutil.copy("/bin/ls", os.path.join(directory, "ls")) shutil.copy(os.path.join(directory, "ls"), os.path.join(directory, "foo")) with util.chdir(directory): with util.archive_created(os.path.join("..", "heap.xar"), ".") as path: # Verify file offsets are as we expect offsets = _file_offsets_for_archive(path, XSL_PATH) (f1, o1) = offsets[0] (f2, o2) = offsets[1] assert o1 < o2, "offset for first file \"{f1}\" ({o1}) greater than or equal to offset for last file \"{f2}\" ({o2})".format(f1=f1, o1=o1, f2=f2, o2=o2) # Make sure extraction goes all right with util.directory_created("extracted") as extracted: subprocess.check_call(["xar", "-x", "-f", path, "-C", extracted]) def coalesce_heap(filename): with util.directory_created("scratch") as directory: shutil.copy("/bin/ls", os.path.join(directory, "ls")) shutil.copy(os.path.join(directory, "ls"), os.path.join(directory, "foo")) with util.chdir(directory): with util.archive_created(os.path.join("..", "heap.xar"), ".", "--coalesce-heap") as path: # Verify file offsets are as we expect offsets = _file_offsets_for_archive(path, XSL_PATH) (f1, o1) = offsets[0] (f2, o2) = offsets[1] # Make sure extraction goes all right with util.directory_created("extracted") as extracted: subprocess.check_call(["xar", "-x", "-f", path, "-C", extracted]) TEST_CASES = (normal_heap, coalesce_heap) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") xar-xar-498/xar/test/heap1.xsl000066400000000000000000000007621446633275300163030ustar00rootroot00000000000000 xar-xar-498/xar/test/integrity.py000077500000000000000000000056221446633275300171500ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import os import os.path import subprocess import util # # Utility Functions # def _test_truncation(filename, path_to_be_archived, bytes_to_chop, *args): with util.archive_created(filename, path_to_be_archived) as path: with open("/dev/null", "w") as bitbucket: size = os.stat(path).st_size while size > 0: last_size = size size = max(0, size - bytes_to_chop) with open(path, "w+") as f: f.truncate(size) with util.directory_created("scratch") as directory: returncode = subprocess.call(["xar", "-x", "-f", path, "-C", directory], stderr=bitbucket) assert returncode != 0, "xar claimed to succeed when extracting a truncated archive" # # Test Cases # def large_uncompressed(filename): _test_truncation(filename, "/usr/share/man/man1", 1024 * 1024, "--compression=none") def large_default_compression(filename): _test_truncation(filename, "/usr/share/man/man1", 1024 * 1024) def large_gzip_compressed(filename): util.skip_if_no_compression_support("gzip") _test_truncation(filename, "/usr/share/man/man1", 1024 * 1024, "--compression=gzip") def large_bzip2_compressed(filename): util.skip_if_no_compression_support("bzip2") _test_truncation(filename, "/usr/share/man/man1", 1024 * 1024, "--compression=bzip2") def large_lzma_compressed(filename): util.skip_if_no_compression_support("lzma") _test_truncation(filename, "/usr/share/man/man1", 1024 * 1024, "--compression=lzma") # "small" variants use a non-base-2 size to try to catch issues that occur on uneven boundaries def small_uncompressed(filename): _test_truncation(filename, "/bin", 43651, "--compression=none") def small_default_compression(filename): _test_truncation(filename, "/bin", 43651) def small_gzip_compressed(filename): util.skip_if_no_compression_support("gzip") _test_truncation(filename, "/bin", 43651, "--compression=gzip") def small_bzip2_compressed(filename): util.skip_if_no_compression_support("bzip2") _test_truncation(filename, "/bin", 43651, "--compression=bzip2") def small_lzma_compressed(filename): util.skip_if_no_compression_support("lzma") _test_truncation(filename, "/bin", 43651, "--compression=lzma") TEST_CASES = (large_uncompressed, large_default_compression, large_gzip_compressed, large_bzip2_compressed, large_lzma_compressed, small_uncompressed, small_default_compression, small_gzip_compressed, small_bzip2_compressed, small_lzma_compressed) if __name__ == "__main__": for case in TEST_CASES: try: case("{f}.xar".format(f=case.func_name)) print("PASSED: {f}".format(f=case.func_name)) except (AssertionError, IOError, subprocess.CalledProcessError): import sys, os print("FAILED: {f}".format(f=case.func_name)) sys.excepthook(*sys.exc_info()) print("") except util.TestCaseSkipError, e: print("SKIPPED: {f}: {m}".format(f=case.func_name, m=e.message)) xar-xar-498/xar/test/util.py000066400000000000000000000110301446633275300160720ustar00rootroot00000000000000#!/usr/bin/env python import contextlib import hashlib import os import os.path import shutil import stat import subprocess import sys import xattr class TestCaseSkipError(Exception): pass def skip_if_no_compression_support(type): """ Raises TestCaseSkipError if the type is "lzma" and the test is running on darwin (OS X). In the future, we should add a hidden debugging flag to xar to determine valid compression types. This will skip incorrectly if a custom xar is used on OS X, or if a custom xar on another platform is built without bzip2 or lzma. """ if sys.platform == "darwin" and type == "lzma": raise TestCaseSkipError("{t} support not compiled in".format(t=type)) @contextlib.contextmanager def directory_created(directory_path): """ Creates the named directory and provides the path to the directory to the calling code. Automatically removes the directory when finished. Usage: with directory_created("foobar") as path: do_stuff_with_path """ os.mkdir(directory_path) try: yield os.path.realpath(directory_path) finally: if os.path.exists(directory_path): shutil.rmtree(directory_path) @contextlib.contextmanager def archive_created(archive_path, content_path, *extra_args, **extra_kwargs): """ Creates a named xar archive of the specified content path, returning the path to the archive. Automatically removes the archive when finished. Usage: with archive_created("/bin", "bin.xar") as path: do_stuff_with(path) """ cmd = ["xar", "-c", "-f", archive_path, content_path] if extra_args: cmd += list(extra_args) try: subprocess.check_call(cmd, **extra_kwargs) assert os.path.exists(archive_path), "failed to create archive \"{p}\" but xar did not report an error".format(p=archive_path) yield os.path.realpath(archive_path) finally: if os.path.exists(archive_path): os.unlink(archive_path) HASH_CHUNK_SIZE = 32768 def _md5_path(path): with open(path, "r") as f: h = hashlib.md5() while True: last = f.read(HASH_CHUNK_SIZE) if not last: break h.update(last) return h.digest() def assert_identical_directories(path1, path2): """ Verifies two directories have identical contents. Checks file type (via the high byte of the mode), size, atime, and mtime, but does not check other attributes like uid and gid, since they can be expected to change. """ seen = set([]) for file1 in os.listdir(path1): seen.add(file1) entry1 = os.path.join(path1, file1) entry2 = os.path.join(path2, file1) assert os.path.exists(entry2), "\"{f1}\" exists in \"{p1}\" but not \"{p2}\"".format(f1=file1, p1=path1, p2=path2) # Extended attributes xattr1 = xattr.xattr(entry1) xattr2 = xattr.xattr(entry2) assert set(xattr1.list()) == set(xattr2.list()), "list of extended attributes on \"{f1}\" ({l1}) differs from \"{f2}\" ({l2})".format(f1=entry1, l1=xattr1.list(), f2=entry2, l2=xattr2.list()) for attribute in xattr1.list(): assert xattr1.get(attribute) == xattr2.get(attribute), "extended attribute \"{a1}\" on \"{f1}\" doesn't match value from \"{f2}\"".format(a1=attribute, f1=entry1, f2=entry2) # Why do it this way? We want to lstat() instead of stat(), so we can't use os.path.isdir() and friends stat1 = os.lstat(entry1) stat2 = os.lstat(entry2) # Modes mode1 = stat1.st_mode mode2 = stat2.st_mode if stat.S_ISREG(mode1): assert stat.S_ISREG(mode2) if stat.S_ISDIR(mode1): assert stat.S_ISDIR(mode2) if stat.S_ISLNK(mode1): assert stat.S_ISLNK(mode2) if stat.S_ISCHR(mode1): assert stat.S_ISCHR(mode2) if stat.S_ISBLK(mode1): assert stat.S_ISBLK(mode2) if stat.S_ISFIFO(mode1): assert stat.S_ISFIFO(mode2) if stat.S_ISSOCK(mode1): assert stat.S_ISSOCK(mode2) # Sizes and the like assert stat1.st_size == stat2.st_size, "size mismatch for \"{e1}\" ({s1}) and \"{e2}\" ({s2})".format(e1=entry1, s1=stat1.st_size, e2=entry2, s2=stat2.st_size) assert stat1.st_mtime == stat2.st_mtime, "mtime mismatch for \"{e1}\" and \"{e2}\"".format(e1=entry1, e2=entry2) assert _md5_path(entry1) == _md5_path(entry2), "md5 hash mismatch for \"{e1}\" and \"{e2}\"".format(e1=entry1, e2=entry2) if os.path.isdir(entry1): assert_identical_directories(entry1, entry2) for file2 in os.listdir(path2): assert file2 in seen, "\"{f2}\" exists in \"{p2}\" but not \"{p1}\"".format(f2=file2, p1=path1, p2=path2) def touch(path): if not os.path.exists(path): with open(path, "w"): pass os.utime(path, None) @contextlib.contextmanager def chdir(*args, **kwargs): cwd = os.getcwd() os.chdir(*args, **kwargs) try: yield os.getcwd() finally: os.chdir(cwd) xar-xar-498/xar/test/validate.c000066400000000000000000000071051446633275300165100ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include off_t HeapOff = 0; static char* xar_format_md5(const unsigned char* m) { char* result = NULL; asprintf(&result, "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x", m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]); return result; } void heap_check(int fd, const char *name, const char *prop, off_t offset, off_t length, const char *csum) { char *buf; EVP_MD_CTX ctx; const EVP_MD *md; unsigned char md5str[EVP_MAX_MD_SIZE]; unsigned int len; ssize_t r; char *formattedmd5; fprintf(stderr, "Heap checking %s %s at offset: %" PRIu64 "\n", name, prop, HeapOff+offset); OpenSSL_add_all_digests(); md = EVP_get_digestbyname("md5"); if( md == NULL ) { fprintf(stderr, "No md5 digest in openssl\n"); exit(1); } EVP_DigestInit(&ctx, md); buf = malloc(length); if( !buf ) { fprintf(stderr, "Error allocating buffer\n"); exit(1); } if( lseek(fd, HeapOff+offset, SEEK_SET) < 0 ) { perror("lseek"); fprintf(stderr, "Error seeking in the heap to offet: %" PRIu64 "\n", HeapOff+offset); exit(1); } r = read(fd, buf, length); if( r != length ) { fprintf(stderr, "Error reading from the heap\n"); exit(1); } EVP_DigestUpdate(&ctx, buf, length); EVP_DigestFinal(&ctx, md5str, &len); formattedmd5 = xar_format_md5(md5str); if( strcmp(formattedmd5, csum) != 0 ) { fprintf(stderr, "%s %s checksum does not match\n", name, prop); } free(formattedmd5); free(buf); } void prop_check(int fd, xar_t x, xar_file_t f) { xar_iter_t i; const char *key, *value; const char *name = NULL; char *tmp; off_t offset = 0, length = 0; const char *origcsum = NULL; i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating new prop iter\n"); exit(1); } xar_prop_get(f, "name", &name); for( key = xar_prop_first(f, i); key; key = xar_prop_next(i) ) { asprintf(&tmp, "%s/offset", key); if( xar_prop_get(f, tmp, &value) == 0 ) { offset = strtoll(value, NULL, 10); } free(tmp); asprintf(&tmp, "%s/length", key); if( xar_prop_get(f, tmp, &value) == 0 ) { length = strtoll(value, NULL, 10); } free(tmp); asprintf(&tmp, "%s/archived-checksum", key); if( xar_prop_get(f, tmp, &value) == 0 ) { origcsum = value; } free(tmp); if( offset && length && origcsum ) { heap_check(fd, name, key, offset, length, origcsum); offset = 0; length = 0; origcsum = NULL; } } } int main(int argc, char *argv[]) { char *file = argv[1]; xar_t x; xar_iter_t ifile, iprop, iattr; xar_file_t f; const char *key; int fd; off_t off; xar_header_t hdr; x = xar_open(file, READ); if( !x ) { fprintf(stderr, "Error opening archive\n"); exit(1); } fd = open(file, O_RDONLY); if( fd < 0 ) { fprintf(stderr, "Error opening archive\n"); exit(1); } read(fd, &hdr, sizeof(hdr)); hdr.size = htons(hdr.size); hdr.toc_length_compressed = xar_ntoh64(hdr.toc_length_compressed); HeapOff = hdr.size + hdr.toc_length_compressed; ifile = xar_iter_new(); if( !ifile ) { fprintf(stderr, "Error creating file iterator"); exit(1); } for(f = xar_file_first(x, ifile); f; f = xar_file_next(ifile)) { prop_check(fd, x, f); } } xar-xar-498/xar/xar.spec.in000066400000000000000000000050641446633275300156510ustar00rootroot00000000000000Summary: The XAR project aims to provide an easily extensible archive format. Name: xar Version: @XAR_VERSION@ Release: 0 License: BSD Group: Applications/Archiving URL: http://code.google.com/p/%{name}/ Source: http://%{name}.googlecode.com/files/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root %ifos linux BuildRequires: libxml2-devel >= 2.6.11 BuildRequires: openssl-devel BuildRequires: bzip2-devel BuildRequires: zlib-devel BuildRequires: /usr/bin/awk %endif %description The XAR project aims to provide an easily extensible archive format. Important design decisions include an easily extensible XML table of contents for random access to archived files, storing the toc at the beginning of the archive to allow for efficient handling of streamed archives, the ability to handle files of arbitrarily large sizes, the ability to choose independent encodings for individual files in the archive, the ability to store checksums for individual files in both compressed and uncompressed form, and the ability to query the table of content's rich meta-data. %package devel Summary: Libraries and header files required for xar. Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel Libraries and header files required for xar. %prep %setup -q -n %{name}-%{version} %build %configure --disable-static %{__make} %{?_smp_mflags} %install %{__rm} -rf $RPM_BUILD_ROOT %{__make} install DESTDIR=%{buildroot} %clean %{__rm} -rf $RPM_BUILD_ROOT %ifos linux %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %endif %files %defattr(-,root,root,-) %doc LICENSE TODO %{_bindir}/%{name} %ifnos darwin %{_libdir}/lib%{name}.so.* %else %{_libdir}/lib%{name}.*.dylib %endif %{_mandir}/man1/xar.1* %files devel %defattr(-,root,root,-) %{_includedir}/%{name}/%{name}.h %ifnos darwin %{_libdir}/lib%{name}.so %else %{_libdir}/lib%{name}.dylib %endif %exclude %{_libdir}/lib%{name}.la %changelog * Wed Sep 12 2007 Anders F Bjorklund 1.5.1-0 - fixed spec, made darwin compatible - moved non-versioned lib from devel * Mon May 07 2007 Rob Braun 0:1.5-1 - 1.5 * Thu Feb 23 2006 Rob Braun - 0:1.2-1 - 1.4 * Mon Oct 24 2005 Rob Braun - 0:1.2-1 - 1.3 * Wed Sep 21 2005 Jason Corley - 0:1.1-1 - 1.1 - correct library version - add specific version to libxml requirements * Fri Sep 09 2005 Jason Corley - 0:1.0-1 - 1.0 * Sat Apr 23 2005 Jason Corley - 0:0.0.0-0.20050423.0 - Initial RPM release. xar-xar-498/xarsig/000077500000000000000000000000001446633275300142745ustar00rootroot00000000000000xar-xar-498/xarsig/xar-sig.c000066400000000000000000001253361446633275300160240ustar00rootroot00000000000000/* * Copyright (c) 2005 Rob Braun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Rob Braun nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * 03-Apr-2005 * DRI: Rob Braun */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef XARSIG_BUILDING_WITH_XAR #include "xar_internal.h" #else #include #endif // XARSIG_BUILDING_WITH_XAR #include "filetree.h" #include "util.h" #define SYMBOLIC 1 #define NUMERIC 2 // error codes for B&I #define E_NOSIG 60 #define E_SIGEXISTS 61 extern char **environ; static int Perms = 0; static int Local = 0; static char *Subdoc = NULL; static char *SubdocName = NULL; static char *Toccksum = NULL; static char *Filecksum = NULL; static char *Compression = NULL; static char *Rsize = NULL; static char *DataToSignDumpPath = NULL; static char *SigOffsetDumpPath = NULL; static char *LeafCertPath = NULL; static char *IntermediateCertPath = NULL; static char *RootCertPath = NULL; static int Err = 0; static int Verbose = 0; static int Coalesce = 0; static int LinkSame = 0; static int DoSign = 0; static long SigSize = 0; struct lnode { char *str; regex_t reg; struct lnode *next; }; struct __stack_element { struct __stack_element *prev; struct __stack_element *next; void *data; }; struct __stack { struct __stack_element *bottom; struct __stack_element *top; }; typedef struct __stack_element *stack_element; typedef struct __stack *stack; struct lnode *Exclude = NULL; struct lnode *Exclude_Tail = NULL; struct lnode *NoCompress = NULL; struct lnode *NoCompress_Tail = NULL; static int32_t err_callback(int32_t sev, int32_t err, xar_errctx_t ctx, void *usrctx); static int32_t signingCallback(xar_signature_t sig, void *context, uint8_t *data, uint32_t length, uint8_t **signed_data, uint32_t *signed_len); static void insert_cert(xar_signature_t sig, const char *cert_path); static void add_subdoc(xar_t x); static void _set_xarsig_opts_from_args(xar_t x) { // Update checksum algorithms before we start messing with the heap length in xar_signature_new() if( Toccksum ) xar_opt_set(x, XAR_OPT_TOCCKSUM, Toccksum); if( Filecksum ) xar_opt_set(x, XAR_OPT_FILECKSUM, Filecksum); if ( SigSize ) { xar_signature_t sig = xar_signature_new(x, "RSA", SigSize, &signingCallback, NULL); if ( LeafCertPath ) insert_cert(sig, LeafCertPath); if ( IntermediateCertPath ) insert_cert(sig, IntermediateCertPath); if ( RootCertPath ) insert_cert(sig, RootCertPath); } if( Compression ) xar_opt_set(x, XAR_OPT_COMPRESSION, Compression); if( Coalesce ) xar_opt_set(x, XAR_OPT_COALESCE, "true"); if( LinkSame ) xar_opt_set(x, XAR_OPT_LINKSAME, "true"); if ( Rsize != NULL ) xar_opt_set(x, XAR_OPT_RSIZE, Rsize); xar_register_errhandler(x, err_callback, NULL); if( Subdoc ) add_subdoc(x); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } } static void print_file(xar_file_t f) { if( Verbose ) { char *path = xar_get_path(f); printf("%s\n", path); free(path); } } static void add_subdoc(xar_t x) { xar_subdoc_t s; int fd; unsigned char *buf; unsigned int len; struct stat sb; if( SubdocName == NULL ) SubdocName = "subdoc"; s = xar_subdoc_new(x, (const char *)SubdocName); fd = open(Subdoc, O_RDONLY); if( fd < 0 ) return; fstat(fd, &sb); len = sb.st_size; buf = malloc(len+1); if( buf == NULL ) { close(fd); return; } memset(buf, 0, len+1); read(fd, buf, len); close(fd); xar_subdoc_copyin(s, buf, len); return; } static void extract_subdoc(xar_t x, const char *name) { xar_subdoc_t i; for( i = xar_subdoc_first(x); i; i = xar_subdoc_next(i) ) { const char *sname = xar_subdoc_name(i); unsigned char *sdoc; int fd, size; if( name && strcmp(name, sname) != 0 ) continue; xar_subdoc_copyout(i, &sdoc, (unsigned int *)&size); fd = open(Subdoc, O_WRONLY|O_CREAT|O_TRUNC, 0644); if( fd < 0 ) return; write(fd, sdoc, size); close(fd); free(sdoc); } return; } static void extract_data_to_sign(const char *filename) { xar_signature_t sig; off_t signatureOffset; FILE *file; xar_t x; int i; uint32_t dataToSignOffset = 0; uint32_t dataToSignSize = 0; char *buffer = NULL; const char *value; // find signature stub x = xar_open(filename, READ); if ( x == NULL ) { fprintf(stderr, "Could not open %s to extract data to sign!\n", filename); exit(1); } sig = xar_signature_first(x); if ( !sig ) { fprintf(stderr, "No signatures found to extract data from.\n"); exit(E_NOSIG); } // locate data to sign if( 0 != xar_prop_get_expect_notnull((xar_file_t)x, "checksum/offset" ,&value) ) { fprintf(stderr, "Could not locate checksum/offset in archive.\n"); exit(1); } dataToSignOffset = xar_get_heap_offset(x); dataToSignOffset += strtoull(value, (char **)NULL, 10); if( 0 != xar_prop_get_expect_notnull((xar_file_t)x, "checksum/size" ,&value) ) { fprintf(stderr, "Could not locate checksum/size in archive.\n"); exit(1); } dataToSignSize = strtoull(value, (char **)NULL, 10); // get signature offset (inject signature here) xar_signature_copy_signed_data(sig, NULL, NULL, NULL, NULL, &signatureOffset); signatureOffset += xar_get_heap_offset(x); xar_close(x); // now get data to be signed, using offset and size file = fopen(filename, "r"); if (!file) { fprintf(stderr, "Could not open %s for reading data to sign!\n", filename); exit(1); } fseek(file, dataToSignOffset, SEEK_SET); buffer = malloc(dataToSignSize); i = fread(buffer, dataToSignSize, 1, file); if (i != 1) { fprintf(stderr, "Failed to read data to sign from %s!\n", filename); exit(1); } fclose(file); // save data to sign file = fopen(DataToSignDumpPath, "w"); if (!file) { fprintf(stderr, "Could not open %s for saving data to sign!\n", DataToSignDumpPath); exit(1); } i = fwrite(buffer, dataToSignSize, 1, file); if (i != 1) { fprintf(stderr, "Failed to write data to sign to %s (fwrite() returned %i)!\n", DataToSignDumpPath, i); exit(1); } fclose(file); // save signature offset file = fopen(SigOffsetDumpPath, "w"); if (!file) { fprintf(stderr, "Could not open %s for saving signature offset!\n", SigOffsetDumpPath); exit(1); } i = fprintf(file, "%lli\n", signatureOffset); if (i < 0) { fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", SigOffsetDumpPath, i); exit(1); } fclose(file); free(buffer); } static void extract_certs(char *filename, char *cert_base_path) { xar_signature_t sig; xar_t x; int32_t count; int i; const uint8_t *cert_data; uint32_t cert_len; FILE *file; char *cert_path; // open xar, get signature x = xar_open(filename, READ); if ( x == NULL ) { fprintf(stderr, "Could not open %s to extract certificates!\n", filename); exit(1); } sig = xar_signature_first(x); if ( !sig ) { fprintf(stderr, "No signatures found to extract data from.\n"); exit(E_NOSIG); } // iterate through all certificates associated with that signature, write them to disk count = xar_signature_get_x509certificate_count(sig); if (!count) { fprintf(stderr, "Signature bears no certificates. Odd.\n"); exit(1); } for (i=0; ibottom = s->top = NULL; return s; } void stack_free(stack s) { free(s); } void stack_push(stack s, void *data) { stack_element e = malloc(sizeof(struct __stack_element)); e->data = data; if (s->top) { s->top->next = e; e->prev = s->top; } else { s->top = s->bottom = e; e->prev = NULL; } e->next = NULL; s->top = e; } void *stack_pop(stack s) { if (!s->top) return NULL; void *ret = s->top->data; stack_element temp = s->top; s->top = s->top->prev; free(temp); if (s->top) s->top->next = NULL; else s->bottom = NULL; return ret; } /* replace_sign: rip out all current signatures and certs and insert a new pair Since libxar is currently not capable of doing this directly, we have to create a new xar archive, copy all the files and options from the current archive, and sign the new archive */ static void replace_sign(const char *filename) { xar_t old_xar, new_xar; xar_signature_t sig; char *parent_path = xar_safe_dirname(filename); if ( parent_path == NULL ) { fprintf(stderr, "Failed to get dirname_r of: %s.\n", filename); exit(1); } char *new_xar_path; if (asprintf(&new_xar_path, "%s/xar.XXXXXX", parent_path) == -1) { fprintf(stderr, "Failed to create temporary xar path.\n"); free(parent_path); exit(1); } free(parent_path); new_xar_path = mktemp(new_xar_path); int err; pid_t pid; char **argv; int status; // open the first archive old_xar = xar_open(filename, READ); if ( old_xar == NULL ) { fprintf(stderr, "Could not open archive %s!\n", filename); unlink(new_xar_path); exit(1); } // use command-line arguments to set xar opts; the copy operation below won't work unless they're set in the first place! _set_xarsig_opts_from_args(old_xar); // open the second archive new_xar = xar_open(new_xar_path, WRITE); if( !new_xar ) { fprintf(stderr, "Error creating new archive %s\n", new_xar_path); unlink(new_xar_path); exit(1); } // copy options char *opts[7] = {XAR_OPT_TOCCKSUM, XAR_OPT_FILECKSUM, XAR_OPT_COMPRESSION, XAR_OPT_COALESCE, XAR_OPT_LINKSAME, XAR_OPT_RSIZE, XAR_OPT_OWNERSHIP}; int i; const char *opt; for (i=0; i<7; i++) { opt = xar_opt_get(old_xar, opts[i]); if (opt) xar_opt_set(new_xar, opts[i], opt); } // install new signature and new certs in new_xar sig = xar_signature_new(new_xar, "RSA", SigSize, &signingCallback, NULL); if ( LeafCertPath ) insert_cert(sig, LeafCertPath); if ( IntermediateCertPath ) insert_cert(sig, IntermediateCertPath); if ( RootCertPath ) insert_cert(sig, RootCertPath); // skip copy subdocs for now since we don't use them yet // copy files xar_iter_t iter = xar_iter_new(); xar_file_t f = xar_file_first(old_xar, iter); // xar_file_next iterates the archive depth-first, i.e. all children are enumerated before the siblings. stack s_new = stack_new(); stack s_old = stack_new(); xar_file_t last_copied = NULL, last_added; xar_iter_t loopIter = xar_iter_new(); xar_file_t current_xar_file; for (current_xar_file = xar_file_first(old_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { printf("old_xar -> %s (parent: %s)\n",xar_get_path(current_xar_file),XAR_FILE(current_xar_file)->parent?xar_get_path(XAR_FILE(current_xar_file)->parent):"(nil)"); } do { // parent is the parent in the new archive! // 3 cases: // 1. the file has no parent. Happens for every file at the top level of the archive. // 2. the file's parent is the last file we added. Happens while descending down a path // 3. the file's parent is one of the ancestors of the last file (and not NULL, that would be case 1) // that means we either go back up the tree and add a sibling of one of the ancestors, or we add a // sibling on the same level const char *unsafe_name; char* name; xar_prop_get(f, "name", &unsafe_name); // filename, without any path info if (!unsafe_name || xar_is_safe_filename(unsafe_name, &name) < 0) { fprintf(stderr, "Error creating new archive %s. '%s' is not safe.\n", new_xar_path, unsafe_name); unlink(new_xar_path); exit(1); } if (!XAR_FILE(f)->parent) { // case 1 printf("root: %s\n",xar_get_path(f)); last_added = xar_add_from_archive(new_xar, NULL, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else if (f->parent == last_copied) { // case 2 printf("child: %s -> %s\n",xar_get_path(f->parent),xar_get_path(f)); last_added = xar_add_from_archive(new_xar, last_added, name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } else { // case 3 printf("searching for parent: %s ?\n",xar_get_path(f)); while (XAR_FILE(f)->parent != XAR_FILE(s_old->top->data)->parent) { printf("popping: %s\n",xar_get_path(XAR_FILE(s_old->top->data))); stack_pop(s_new); stack_pop(s_old); } printf("found: %s -> %s\n",xar_get_path(XAR_FILE(s_new->top->data)),xar_get_path(f)); stack_pop(s_new); stack_pop(s_old); last_added = xar_add_from_archive(new_xar, (xar_file_t)(s_new->top->data), name, old_xar, f); last_copied = f; stack_push(s_new, (void *)last_added); stack_push(s_old, (void *)last_copied); } free(name); } while ((f = xar_file_next(iter))); loopIter = xar_iter_new(); for (current_xar_file = xar_file_first(new_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter)) { char * current_path = xar_get_path(current_xar_file); printf("new_xar -> %s\n",current_path); } xar_iter_free(iter); stack_free(s_new); stack_free(s_old); if( xar_close(new_xar) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } xar_close(old_xar); // write signature offset to file (have to re-open so xar_close can figure out the correct offset) new_xar = xar_open(new_xar_path, READ); if( !new_xar ) { fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path); unlink(new_xar_path); exit(1); } if (extract_sig_offset(new_xar, SigOffsetDumpPath)) { xar_close(new_xar); unlink(new_xar_path); exit(1); } xar_close(new_xar); // delete old archive, move new in its place unlink(filename); argv = calloc(sizeof(char *), 4); argv[0] = "cp"; argv[1] = new_xar_path; argv[2] = (char *)filename; err = posix_spawn(&pid, "/bin/cp", NULL, NULL, argv, environ); free(argv); if (err) { fprintf(stderr, "Could not copy new archive to final location (posix_spawn(3) failed with %d)\n", errno); unlink(new_xar_path); exit(1); } do { err = waitpid(pid, &status, 0); if (err == pid) { if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { fprintf(stderr, "Could not copy new archive to final location (cp(1) exited %d)\n", WEXITSTATUS(status)); unlink(new_xar_path); exit(1); } break; } } else { fprintf(stderr, "Could not copy new archive to final location (waidpid(2) failed with %d)\n", errno); unlink(new_xar_path); exit(1); } } while (1); // Delete the tmp archive unlink(new_xar_path); } /* belated_sign Prepare a previously unsigned archive for signing by creating a signature placeholder and inserting the certificates. Since libxar is currently not capable of doing this directly, we have to create a new xar archive, copy all the files and options from the current archive, and sign the new archive */ static void belated_sign(const char *filename) { xar_t x = xar_open(filename, READ); if ( x == NULL ) { fprintf(stderr, "Could not open archive %s!\n", filename); exit(1); } xar_signature_t sig = xar_signature_first(x); if ( sig ) { fprintf(stderr, "Archive has already been signed. Use --replace-sign instead.\n"); exit(E_SIGEXISTS); } xar_close(x); replace_sign(filename); } static int32_t signingCallback(xar_signature_t sig, void *context, uint8_t *data, uint32_t length, uint8_t **signed_data, uint32_t *signed_len) { // save data to file for later signature if (DataToSignDumpPath) { FILE *file = fopen(DataToSignDumpPath, "w"); if (!file) { fprintf(stderr, "Could not open %s for saving data to sign!\n", DataToSignDumpPath); exit(1); } int i = fwrite(data, length, 1, file); if (i != 1) { fprintf(stderr, "Failed to write data to sign to %s (fwrite() returned %i)!\n", DataToSignDumpPath, i); exit(1); } fclose(file); } // now return blank placeholder data *signed_data = (uint8_t *)malloc(SigSize); memset(*signed_data, 0, SigSize); strncpy((char *)*signed_data, "helloworld", 10); // debug *signed_len = SigSize; return 0; // no error } static void insert_cert(xar_signature_t sig, const char *cert_path) { struct stat *s = malloc(sizeof(struct stat)); if (stat(cert_path, s) == -1) { fprintf(stderr, "Could not stat() certificate file %s (errno == %i)\n", cert_path, errno); exit(1); } void *cert = malloc(s->st_size); FILE *file = fopen(cert_path, "r"); if (!file) { fprintf(stderr, "Could not open %s for reading certificate!\n", cert_path); exit(1); } int i = fread(cert, s->st_size, 1, file); if (i != 1) { fprintf(stderr, "Failed to read certificate from %s!\n", cert_path); exit(1); } fclose(file); xar_signature_add_x509certificate(sig, cert, s->st_size); free(s); free(cert); } static void inject_signature(const char *xar_path, const char *sig_path) { // since there is no API to insert a signature other than during signingCallback time, we have to // inject it by editing the raw file int buffer_size = 1024; void *buffer = malloc(buffer_size); FILE *sig, *xar; off_t signedDataOffset; xar_t x; int i; printf("inject_signature(%s, %s)",xar_path,sig_path); // open xar via the API first to determine the signature offset x = xar_open(xar_path, READ); if ( x == NULL ) { fprintf(stderr, "Could not open xar archive %s to get signature offset!\n", xar_path); exit(1); } signedDataOffset = get_sig_offset(x); xar_close(x); // then re-open xar and signature files raw... sig = fopen(sig_path, "r"); if (!sig) { fprintf(stderr, "Could not open %s for reading signature!\n", sig_path); exit(1); } xar = fopen(xar_path, "r+"); if (!xar) { fprintf(stderr, "Could not open xar archive %s for injecting signature!\n", xar_path); exit(1); } // ...and inject the signature fseek(xar, signedDataOffset, SEEK_SET); do { i = fread(buffer, 1, buffer_size, sig); if (ferror(sig)) { fprintf(stderr, "Failed to read signature from %s!\n", sig_path); exit(1); } fwrite(buffer, 1, i, xar); } while (!feof(sig)); fclose(sig); fclose(xar); free(buffer); } static int archive(const char *filename, int arglen, char *args[]) { xar_t x; FTS *fts; FTSENT *ent; int flags; struct lnode *i; const char *default_compression; x = xar_open(filename, WRITE); if( !x ) { fprintf(stderr, "Error creating archive %s\n", filename); exit(1); } _set_xarsig_opts_from_args(x); default_compression = strdup(xar_opt_get(x, XAR_OPT_COMPRESSION)); if( !default_compression ) default_compression = strdup(XAR_OPT_VAL_GZIP); flags = FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR; if( Local ) flags |= FTS_XDEV; fts = fts_open(args, flags, NULL); if( !fts ) { fprintf(stderr, "Error traversing file tree\n"); exit(1); } while( (ent = fts_read(fts)) ) { xar_file_t f; int exclude_match = 1; int nocompress_match = 1; if( ent->fts_info == FTS_DP ) continue; if( strcmp(ent->fts_path, "/") == 0 ) continue; if( strcmp(ent->fts_path, ".") == 0 ) continue; for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", ent->fts_path); continue; } for( i = NoCompress; i; i=i->next ) { nocompress_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0); if( !nocompress_match ) { xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE); break; } } f = xar_add(x, ent->fts_path); if( !f ) { fprintf(stderr, "Error adding file %s\n", ent->fts_path); } else { print_file(f); } if( !nocompress_match ) xar_opt_set(x, XAR_OPT_COMPRESSION, default_compression); } fts_close(fts); if( xar_close(x) != 0 ) { fprintf(stderr, "Error creating the archive\n"); if( !Err ) Err = 42; } free((char *)default_compression); for( i = Exclude; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } for( i = NoCompress; i; ) { struct lnode *tmp; regfree(&i->reg); tmp = i; i = i->next; free(tmp); } if ( SigOffsetDumpPath ) { x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error re-opening archive %s\n", filename); exit(1); } if (extract_sig_offset(x, SigOffsetDumpPath)) exit(1); } return Err; } static int extract(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; int files_extracted = 0; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_register_errhandler(x, err_callback, NULL); if( Perms == SYMBOLIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC); } if( Perms == NUMERIC ) { xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC); } if ( Rsize != NULL ) { xar_opt_set(x, XAR_OPT_RSIZE, Rsize); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { int matched = 0; int exclude_match = 1; struct lnode *i; char *path = xar_get_path(f); if( args[0] ) { int i; for(i = 0; args[i]; i++) { if( strcmp(path, args[i]) == 0 ) { matched = 1; break; } } } else { matched = 1; } for( i = Exclude; i; i=i->next ) { exclude_match = regexec(&i->reg, path, 0, NULL, 0); if( !exclude_match ) break; } if( !exclude_match ) { if( Verbose ) printf("Excluding %s\n", path); free(path); continue; } if( matched ) { files_extracted++; print_file(f); xar_extract(x, f); } free(path); } if( args[0] && (files_extracted == 0) ) { fprintf(stderr, "No files matched extraction criteria.\n"); Err = 3; } if( Subdoc ) extract_subdoc(x, NULL); xar_iter_free(i); if( xar_close(x) != 0 ) { fprintf(stderr, "Error extracting the archive\n"); if( !Err ) Err = 42; } return Err; } static int list_subdocs(const char *filename) { xar_t x; xar_subdoc_t s; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } for(s = xar_subdoc_first(x); s; s = xar_subdoc_next(s)) { printf("%s\n", xar_subdoc_name(s)); } xar_close(x); return Err; } static int list(const char *filename, int arglen, char *args[]) { xar_t x; xar_iter_t i; xar_file_t f; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } i = xar_iter_new(); if( !i ) { fprintf(stderr, "Error creating xar iterator\n"); exit(1); } for(f = xar_file_first(x, i); f; f = xar_file_next(i)) { print_file(f); } xar_iter_free(i); xar_close(x); return Err; } static int dumptoc(const char *filename, const char* tocfile) { xar_t x; x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_serialize(x, tocfile); xar_close(x); return Err; } static int dump_header(const char *filename) { int fd; xar_header_t xh; if(filename == NULL) fd = 0; else { fd = open(filename, O_RDONLY); if( fd < 0 ) { perror("open"); exit(1); } } if( read(fd, &xh, sizeof(xh)) < sizeof(xh) ) { fprintf(stderr, "error reading header\n"); exit(1); } printf("magic: 0x%x ", ntohl(xh.magic)); if( ntohl(xh.magic) != XAR_HEADER_MAGIC ) printf("(BAD)\n"); else printf("(OK)\n"); printf("size: %d\n", ntohs(xh.size)); printf("version: %d\n", ntohs(xh.version)); printf("Compressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_compressed)); printf("Uncompressed TOC length: %" PRId64 "\n", xar_ntoh64(xh.toc_length_uncompressed)); printf("Checksum algorithm: %d ", ntohl(xh.cksum_alg)); switch( ntohl(xh.cksum_alg) ) { case XAR_CKSUM_NONE: printf("(unsupported (none))\n"); break; case XAR_CKSUM_SHA1: printf("(SHA1)\n"); break; case XAR_CKSUM_SHA256: printf("(SHA256)\n"); break; case XAR_CKSUM_SHA512: printf("(SHA512)\n"); break; #ifdef XAR_SUPOPRT_MD5 case XAR_CKSUM_MD5: printf("(MD5)\n"); break; #else case XAR_CKSUM_MD5: printf("(unsupported (MD5))\n"); break; #endif // XAR_SUPPORT_MD5 default: printf("(unknown)\n"); break; }; return 0; } static int32_t err_callback(int32_t sev, int32_t err, xar_errctx_t ctx, void *usrctx) { xar_file_t f; const char *str; int e; f = xar_err_get_file(ctx); str = xar_err_get_string(ctx); e = xar_err_get_errno(ctx); switch(sev) { case XAR_SEVERITY_DEBUG: case XAR_SEVERITY_INFO: break; case XAR_SEVERITY_WARNING: printf("%s\n", str); break; case XAR_SEVERITY_NORMAL: if( (err = XAR_ERR_ARCHIVE_CREATION) && f ) print_file(f); break; case XAR_SEVERITY_NONFATAL: case XAR_SEVERITY_FATAL: Err = 2; printf("Error while "); if( err == XAR_ERR_ARCHIVE_CREATION ) printf("creating"); if( err == XAR_ERR_ARCHIVE_EXTRACTION ) printf("extracting"); printf(" archive"); if( f ) { const char *file = xar_get_path(f); if( file ) printf(":(%s)", file); free((char *)file); } if( str ) printf(": %s", str); if( err ) printf(" (%s)", strerror(e)); if( sev == XAR_SEVERITY_NONFATAL ) { printf(" - ignored"); printf("\n"); } else { printf("\n"); exit(1); } break; } return 0; } static void usage(const char *prog) { fprintf(stderr, "Usage: %s -[ctx][v] -f ...\n", prog); fprintf(stderr, "\t-c Creates an archive\n"); fprintf(stderr, "\t-x Extracts an archive\n"); fprintf(stderr, "\t-t Lists an archive\n"); fprintf(stderr, "\t--sign Creates a placeholder signature and saves\n"); fprintf(stderr, "\t the data to sign to disk. Works with -c or -f, requires\n"); fprintf(stderr, "\t --sig-size, --leaf-cert-loc and \n"); fprintf(stderr, "\t --intermediate-cert-loc to be set. Setting\n"); fprintf(stderr, "\t --data-to-sign and --sig-offset is optional.\n"); fprintf(stderr, "\t Fails with error code %i if the archive has already\n", E_SIGEXISTS); fprintf(stderr, "\t been signed.\n"); fprintf(stderr, "\t--replace-sign Rips out existing signature(s) and makes a new one.\n"); fprintf(stderr, "\t Same required parameter set as --sign, \n"); fprintf(stderr, "\t but -f instead of -c.\n"); fprintf(stderr, "\t--extract-data-to-sign Extracts data to be signed from an\n"); fprintf(stderr, "\t existing archive. Requires --data-to-sign\n"); fprintf(stderr, "\t and --sig-offset (and -f) to be set.\n"); fprintf(stderr, "\t--extract-certs Extracts all certificates into the\n"); fprintf(stderr, "\t specified directory, naming them 'cert1', 'cert2' etc.\n"); fprintf(stderr, "\t Requires -f.\n"); fprintf(stderr, "\t--inject-sig After extracting the data to be signed and\n"); fprintf(stderr, "\t doing the signing externally, injects.\n"); fprintf(stderr, "\t the signature. Requires -f\n"); fprintf(stderr, "\t-f Specifies an archive to operate on [REQUIRED!]\n"); fprintf(stderr, "\t-v Print filenames as they are archived\n"); fprintf(stderr, "\t-n name Provides a name for a subdocument\n"); fprintf(stderr, "\t-s On extract, specifies the file to extract\n"); fprintf(stderr, "\t subdocuments to.\n"); fprintf(stderr, "\t On archival, specifies an xml file to add\n"); fprintf(stderr, "\t as a subdocument.\n"); fprintf(stderr, "\t-l On archival, stay on the local device.\n"); fprintf(stderr, "\t-p On extract, set ownership based on symbolic\n"); fprintf(stderr, "\t names, if possible.\n"); fprintf(stderr, "\t-P On extract, set ownership based on uid/gid.\n"); fprintf(stderr, "\t--toc-cksum Specifies the hashing algorithm to use for\n"); fprintf(stderr, "\t xml header verification.\n"); #ifdef XAR_SUPPORT_MD5 fprintf(stderr, "\t Valid values: none, md5, sha1, sha256, and sha512\n"); #else fprintf(stderr, "\t Valid values: none, sha1, sha256, and sha512\n"); #endif // XAR_SUPPORT_MD5 fprintf(stderr, "\t Default: sha1\n"); fprintf(stderr, "\t--file-cksum Specifies the hashing algorithm to use for\n"); fprintf(stderr, "\t xml header verification.\n"); #ifdef XAR_SUPPORT_MD5 fprintf(stderr, "\t Valid values: none, md5, sha1, sha256, and sha512\n"); #else fprintf(stderr, "\t Valid values: none, sha1, sha256, and sha512\n"); #endif // XAR_SUPPORT_MD5 fprintf(stderr, "\t Default: sha1\n"); fprintf(stderr, "\t--dump-toc= Has xar dump the xml header into the\n"); fprintf(stderr, "\t specified file.\n"); fprintf(stderr, "\t--dump-header Prints out the xar binary header information\n"); fprintf(stderr, "\t--compression Specifies the compression type to use.\n"); fprintf(stderr, "\t Valid values: none, gzip, bzip2\n"); fprintf(stderr, "\t Default: gzip\n"); fprintf(stderr, "\t--list-subdocs List the subdocuments in the xml header\n"); fprintf(stderr, "\t--extract-subdoc=name Extracts the specified subdocument\n"); fprintf(stderr, "\t to a document in cwd named .xml\n"); fprintf(stderr, "\t--exclude POSIX regular expression of files to \n"); fprintf(stderr, "\t ignore while archiving.\n"); fprintf(stderr, "\t--rsize Specifies the size of the buffer used\n"); fprintf(stderr, "\t for read IO operations in bytes.\n"); fprintf(stderr, "\t--coalesce-heap When archived files are identical, only store one copy\n"); fprintf(stderr, "\t This option creates an archive which\n"); fprintf(stderr, "\t is not streamable\n"); fprintf(stderr, "\t--link-same Hardlink identical files\n"); fprintf(stderr, "\t--no-compress POSIX regular expression of files\n"); fprintf(stderr, "\t not to archive, but not compress.\n"); fprintf(stderr, "\t--sig-size n Size (in bytes) of the signature placeholder\n"); fprintf(stderr, "\t to generate.\n"); fprintf(stderr, "\t--data-to-sign=file Path where to dump the data to be signed.\n"); fprintf(stderr, "\t--sig-offset=file Path where to dump the signature's offset\n"); fprintf(stderr, "\t within the xar.\n"); fprintf(stderr, "\t--leaf-cert-loc=file Location of the leaf certificate\n"); fprintf(stderr, "\t--intermediate-cert-loc=file Location of the intermediate certificate\n"); fprintf(stderr, "\t--root-cert-loc=file Location of the root certificate\n"); fprintf(stderr, "\t--version Print xar's version number\n"); return; } static void print_version() { printf("xar %s\n", XAR_VERSION); } int main(int argc, char *argv[]) { char *filename = NULL; char *sig_path = NULL; char *cert_path = NULL; char command = 0, c; char **args; const char *tocfile = NULL; int arglen, i, err; xar_t x; int loptind = 0; int required_dash_f = 0; /* This release requires us to use -f */ struct lnode *tmp; long int longtmp; struct stat stat_struct; struct option o[] = { {"toc-cksum", 1, 0, 1}, {"file-cksum", 1, 0, 22}, // note out-of-order argument number {"dump-toc", 1, 0, 'd'}, {"compression", 1, 0, 2}, {"list-subdocs", 0, 0, 3}, {"help", 0, 0, 'h'}, {"version", 0, 0, 4}, {"dump-header", 0, 0, 5}, {"extract-subdoc", 1, 0, 6}, {"exclude", 1, 0, 7}, {"rsize", 1, 0, 8}, {"coalesce-heap", 0, 0, 9}, {"link-same", 0, 0, 10}, {"no-compress", 1, 0, 11}, {"sig-size", 1, 0, 12}, {"data-to-sign", 1, 0, 13}, {"sig-offset", 1, 0, 14}, {"leaf-cert-loc", 1, 0, 15}, {"intermediate-cert-loc", 1, 0, 16}, {"extract-data-to-sign", 0, 0, 17}, {"sign", 0, 0, 18}, {"replace-sign", 0, 0, 19}, {"inject-sig", 1, 0, 20}, {"extract-certs", 1, 0, 21}, {"root-cert-loc", 1, 0, 23}, { 0, 0, 0, 0} }; if( argc < 2 ) { usage(argv[0]); exit(1); } while( (c = getopt_long(argc, argv, "xcvtf:hpPln:s:d:v", o, &loptind)) != -1 ) { switch(c) { case 1 : if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA256) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA512) != 0) && (strcmp(optarg, XAR_OPT_VAL_MD5) != 0) ) { usage(argv[0]); exit(1); } Toccksum = optarg; break; case 22: if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA256) != 0) && (strcmp(optarg, XAR_OPT_VAL_SHA512) != 0) && (strcmp(optarg, XAR_OPT_VAL_MD5) != 0) ) { usage(argv[0]); exit(1); } Filecksum = optarg; break; case 2 : if( !optarg ) { usage(argv[0]); exit(1); } if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) && (strcmp(optarg, XAR_OPT_VAL_GZIP) != 0) && (strcmp(optarg, XAR_OPT_VAL_BZIP) != 0) ) { usage(argv[0]); exit(1); } Compression = optarg; break; case 3 : if( command && (command != 3) ) { fprintf(stderr, "Conflicting commands specified\n"); exit(1); } command = 3; break; case 4 : print_version(); exit(0); case 'd': if( !optarg ) { usage(argv[0]); exit(1); } tocfile = optarg; command = 'd'; break; case 5 : command = 5; break; case 6 : SubdocName = optarg; asprintf(&Subdoc, "%s.xml", SubdocName); if( !command ) command = 6; break; case 7 : tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( Exclude == NULL ) { Exclude = tmp; Exclude_Tail = tmp; } else { Exclude_Tail->next = tmp; Exclude_Tail = tmp; } break; case 8 : if ( !optarg ) { usage(argv[0]); exit(1); } longtmp = strtol(optarg, NULL, 10); if( (((longtmp == LONG_MIN) || (longtmp == LONG_MAX)) && (errno == ERANGE)) || (longtmp < 1) ) { fprintf(stderr, "Invalid rsize value: %s\n", optarg); exit(5); } Rsize = optarg; break; case 9 : Coalesce = 1; break; case 10 : LinkSame = 1; break; case 11 : tmp = malloc(sizeof(struct lnode)); tmp->str = optarg; tmp->next = NULL; err = regcomp(&tmp->reg, tmp->str, REG_NOSUB); if( err ) { char errstr[1024]; regerror(err, &tmp->reg, errstr, sizeof(errstr)); printf("Error with regular expression %s: %s\n", tmp->str, errstr); exit(1); } if( NoCompress == NULL ) { NoCompress = tmp; NoCompress_Tail = tmp; } else { NoCompress_Tail->next = tmp; NoCompress_Tail = tmp; } break; case 12 : if( !optarg ) { usage(argv[0]); exit(1); } SigSize = strtol(optarg, (char **)NULL, 10); break; case 13 : if( !optarg ) { usage(argv[0]); exit(1); } DataToSignDumpPath = optarg; break; case 14 : if( !optarg ) { usage(argv[0]); exit(1); } SigOffsetDumpPath = optarg; break; case 15 : if( !optarg ) { usage(argv[0]); exit(1); } LeafCertPath = optarg; break; case 16 : if( !optarg ) { usage(argv[0]); exit(1); } IntermediateCertPath = optarg; break; case 17 : // extract-data-to-sign command = 'e'; break; case 18 : // sign DoSign = 1; break; case 19 : // replace-sign command = 'r'; break; case 20 : // inject signature if( !optarg ) { usage(argv[0]); exit(1); } sig_path = optarg; command = 'i'; break; case 21 : // extract-certs if( !optarg ) { usage(argv[0]); exit(1); } cert_path = optarg; stat(cert_path, &stat_struct); if (!(stat_struct.st_mode & S_IFDIR)) { usage(argv[0]); fprintf(stderr, "%s is not a directory.\n", cert_path); exit(1); } command = 'j'; break; case 23 : if( !optarg ) { usage(argv[0]); exit(1); } RootCertPath = optarg; break; case 'c': case 'x': case 't': if( command && (command != 's') ) { usage(argv[0]); fprintf(stderr, "Conflicting command flags: %c and %c specified\n", c, command); exit(1); } if( c == 't' ) Verbose++; command = c; break; case 'f': required_dash_f = 1; filename = optarg; break; case 'p': Perms = SYMBOLIC; break; case 'P': Perms = NUMERIC; break; case 'l': Local = 1; break; case 'n': SubdocName = optarg; break; case 's': Subdoc = optarg; if( !command ) command = 's'; break; case 'v': Verbose++; break; case 'h': default: usage(argv[0]); exit(1); } } if (! required_dash_f) { usage(argv[0]); fprintf(stderr, "\n -f option is REQUIRED\n"); exit(1); } // extract-data-to-sign if ( (command == 'e') && ((!filename) || (!DataToSignDumpPath) || (!SigOffsetDumpPath)) ) { usage(argv[0]); exit(1); } if ( DoSign ) { // XXX: should we require RootCertPath as well? if ( ( !SigSize || !LeafCertPath || !IntermediateCertPath ) || ((command != 'c') && (!filename)) ) { usage(argv[0]); exit(1); } if (!command) command = 'n'; } if (command == 'r') { /*if ( !SigSize || !LeafCertPath || !IntermediateCertPath || !filename) { usage(argv[0]); exit(1); } xar_t x = xar_open(filename, READ); if ( x == NULL ) { fprintf(stderr, "Could not open archive %s!\n", filename); exit(1); } xar_signature_t sig = xar_signature_first(x); if ( !sig ) { fprintf(stderr, "No signature found to replace.\n"); exit(E_NOSIG); } xar_close(x);*/ } if ((command == 'i') && ((!filename) || (!sig_path))) { usage(argv[0]); exit(1); } if ((command == 'j') && (!filename)) { usage(argv[0]); exit(1); } switch(command) { case 5 : return dump_header(filename); case 3 : return list_subdocs(filename); case 'c': if( optind == argc ) { usage(argv[0]); fprintf(stderr, "No files to operate on.\n"); exit(1); } arglen = argc - optind; args = malloc(sizeof(char*) * (arglen+1)); memset(args, 0, sizeof(char*) * (arglen+1)); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); return archive(filename, arglen, args); case 'd': if( !tocfile ) { usage(argv[0]); exit(1); } return dumptoc(filename, tocfile); case 'x': arglen = argc - optind; args = malloc(sizeof(char*) * (arglen+1)); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); args[i] = NULL; return extract(filename, arglen, args); case 't': arglen = argc - optind; args = malloc(sizeof(char*) * (arglen+1)); for( i = 0; i < arglen; i++ ) args[i] = strdup(argv[optind + i]); return list(filename, arglen, args); case 6 : case 's': x = xar_open(filename, READ); if( !x ) { fprintf(stderr, "Error opening xar archive: %s\n", filename); exit(1); } xar_register_errhandler(x, err_callback, NULL); extract_subdoc(x, SubdocName); xar_close(x); exit(Err); break; case 'e': extract_data_to_sign(filename); exit(Err); case 'r': replace_sign(filename); exit(Err); case 'i': inject_signature(filename, sig_path); exit(Err); case 'n': belated_sign(filename); exit(Err); case 'j': extract_certs(filename, cert_path); exit(Err); default: usage(argv[0]); fprintf(stderr, "Unrecognized command.\n"); exit(1); } /* unreached */ exit(0); }