diff -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 <sys/types.h>
 #include <stdint.h>
+#include <sys/stat.h>
 
 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <zlib.h>
+#include <openssl/evp.h>
+
+#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 <bbraun@opendarwin.org>
+ */
+
+#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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <zlib.h>
-#include <openssl/evp.h>
-
-#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 <bbraun@opendarwin.org>
- */
-
-#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_ */
