Beispiel #1
0
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;
}
Beispiel #2
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);
		return strtoll(opt, NULL, 0);
	} else {
		return -1;
	}
}
Beispiel #3
0
Datei: hash.c Projekt: aosm/xar
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);
			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);
		free(hash);
	}

	if(*context) {
		free(*context);
		*context = NULL;
	}

	return result;
}
Beispiel #4
0
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;
}
Beispiel #5
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;
	
	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;
		}
	}
	
	tmpp = xar_prop_pget(p, "offset");
	if( tmpp )
		opt = xar_prop_getvalue(tmpp);
	
	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);
			}
		}
	}
	
	opt = NULL;
	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;
		}
	}
	
	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);
	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;
}
Beispiel #6
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;
	void *inbuf;
	const char *opt;
	xar_prop_t tmpp;

	memset(modulecontext, 0, sizeof(void*)*modulecount);

	opt = xar_opt_get(x, "rsize");
	if( !opt ) {
		def_bsize = 4096;
	} else {
		def_bsize = strtol(opt, NULL, 0);
		if( ((def_bsize == LONG_MAX) || (def_bsize == LONG_MIN)) && (errno == ERANGE) ) {
			def_bsize = 4096;
		}
	}

	opt = NULL;
	tmpp = xar_prop_pget(p, "offset");
	if( tmpp )
		opt = xar_prop_getvalue(tmpp);
	if( !opt ) {
		wcb(x, f, NULL, 0, context);
		return 0;
	} else {
		seekoff = strtoll(opt, NULL, 0);
		if( ((seekoff == LLONG_MAX) || (seekoff == LLONG_MIN)) && (errno == ERANGE) ) {
			return -1;
		}
	}

	seekoff += XAR(x)->toc_count + sizeof(xar_header_t);
	if( XAR(x)->fd > 1 ) {
		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 = read(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);
					}
					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);
			}
		}
	}

	opt = NULL;
	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;
		}
	}

	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 )
					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 )
						return -1;
				}
			}

			wcb(x, f, inbuf, bsize, context);
		}
		
		free(inbuf);
		bsize = def_bsize;
		inbuf = malloc(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;
}
Beispiel #7
0
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, off, i;
	size_t bsize, rsize;
	int64_t readsize=0, writesize=0, inc = 0;
	void *inbuf;
	char *tmpstr = NULL;
	const char *opt, *csum;
	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);

	opt = xar_opt_get(x, XAR_OPT_RSIZE);
	if( !opt ) {
		bsize = 4096;
	} else {
		bsize = strtol(opt, NULL, 0);
		if( ((bsize == LONG_MAX) || (bsize == LONG_MIN)) && (errno == ERANGE) ) {
			bsize = 4096;
		}
	}

	r = 1;
	while(r != 0) {
		inbuf = malloc(bsize);
		if( !inbuf )
			return -1;

		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]));
		}

		off = 0;
		if( rsize != 0 ) {
			do {
				r = write(XAR(x)->heap_fd, inbuf+off, rsize-off);
				if( (r < 0) && (errno != EINTR) )
					return -1;
				off += r;
				writesize += r;
			} while( off < rsize );
		}
		XAR(x)->heap_offset += off;
		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);
	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 {
		xmlHashAddEntry(XAR(x)->csum_hash, BAD_CAST(csum), XAR_FILE(f));
	}

	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;
}
Beispiel #8
0
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;
}
Beispiel #9
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 = dirname(tmp);
		statfs(bname, &sfs);
		free(tmp);
	}
	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;
		xar_attrcopy_from_heap(x, f, p, xar_linuxattr_write, &context);

	}

#endif
	return 0;
}