--- old/usr/src/cmd/ntfsprogs/ntfscmp.c	2014-07-17 16:13:37.468930177 +0200
+++ /dev/null	2014-07-17 16:13:37.000000000 +0200
@@ -1,1005 +0,0 @@
-/**
- * ntfscmp - Part of the Linux-NTFS project.
- *
- * Copyright (c) 2005-2006 Szabolcs Szakacsits
- * Copyright (c) 2005      Anton Altaparmakov
- * Copyright (c) 2007      Yura Pakhuchiy
- *
- * This utility compare two NTFS volumes.
- *
- * This program 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 (in the main directory of the Linux-NTFS
- * distribution in the file COPYING); if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "compat.h"
-#include "utils.h"
-#include "mst.h"
-#include "version.h"
-#include "support.h"
-
-static const char *EXEC_NAME = "ntfscmp";
-
-static const char *invalid_ntfs_msg =
-"Apparently device '%s' doesn't have a valid NTFS.\n"
-"Maybe you selected the wrong partition? Or the whole disk instead of a\n"
-"partition (e.g. /dev/hda, not /dev/hda1)?\n";
-
-static const char *corrupt_volume_msg =
-"Apparently you have a corrupted NTFS. Please run the filesystem checker\n"
-"on Windows by invoking chkdsk /f. Don't forget the /f (force) parameter,\n"
-"it's important! You probably also need to reboot Windows to take effect.\n";
-
-static const char *hibernated_volume_msg =
-"Apparently the NTFS partition is hibernated. Windows must be resumed and\n"
-"turned off properly\n";
-
-
-static struct {
-	int debug;
-	int show_progress;
-	int verbose;
-	char *vol1;
-	char *vol2;
-} opt;
-
-
-#define NTFS_PROGBAR		0x0001
-#define NTFS_PROGBAR_SUPPRESS	0x0002
-
-struct progress_bar {
-	u64 start;
-	u64 stop;
-	int resolution;
-	int flags;
-	float unit;
-};
-
-/* WARNING: don't modify the text, external tools grep for it */
-#define ERR_PREFIX   "ERROR"
-#define PERR_PREFIX  ERR_PREFIX "(%d): "
-#define NERR_PREFIX  ERR_PREFIX ": "
-
-__attribute__((format(printf, 2, 3)))
-static void perr_printf(int newline, const char *fmt, ...)
-{
-	va_list ap;
-	int eo = errno;
-
-	fprintf(stdout, PERR_PREFIX, eo);
-	va_start(ap, fmt);
-	vfprintf(stdout, fmt, ap);
-	va_end(ap);
-	fprintf(stdout, ": %s", strerror(eo));
-	if (newline)
-		fprintf(stdout, "\n");
-	fflush(stdout);
-	fflush(stderr);
-}
-
-#define perr_print(...)     perr_printf(0, __VA_ARGS__)
-#define perr_println(...)   perr_printf(1, __VA_ARGS__)
-
-__attribute__((format(printf, 1, 2)))
-static void err_printf(const char *fmt, ...)
-{
-	va_list ap;
-
-	fprintf(stdout, NERR_PREFIX);
-	va_start(ap, fmt);
-	vfprintf(stdout, fmt, ap);
-	va_end(ap);
-	fflush(stdout);
-	fflush(stderr);
-}
-
-/**
- * err_exit
- *
- * Print and error message and exit the program.
- */
-__attribute__((noreturn))
-__attribute__((format(printf, 1, 2)))
-static int err_exit(const char *fmt, ...)
-{
-	va_list ap;
-
-	fprintf(stdout, NERR_PREFIX);
-	va_start(ap, fmt);
-	vfprintf(stdout, fmt, ap);
-	va_end(ap);
-	fflush(stdout);
-	fflush(stderr);
-	exit(1);
-}
-
-/**
- * perr_exit
- *
- * Print and error message and exit the program
- */
-__attribute__((noreturn))
-__attribute__((format(printf, 1, 2)))
-static int perr_exit(const char *fmt, ...)
-{
-	va_list ap;
-	int eo = errno;
-
-	fprintf(stdout, PERR_PREFIX, eo);
-	va_start(ap, fmt);
-	vfprintf(stdout, fmt, ap);
-	va_end(ap);
-	printf(": %s\n", strerror(eo));
-	fflush(stdout);
-	fflush(stderr);
-	exit(1);
-}
-
-/**
- * usage - Print a list of the parameters to the program
- *
- * Print a list of the parameters and options for the program.
- *
- * Return:  none
- */
-__attribute__((noreturn))
-static void usage(void)
-{
-
-	printf("\nUsage: %s [OPTIONS] DEVICE1 DEVICE2\n"
-		"    Compare two NTFS volumes and tell the differences.\n"
-		"\n"
-		"    -P, --no-progress-bar  Don't show progress bar\n"
-		"    -v, --verbose          More output\n"
-		"    -h, --help             Display this help\n"
-#ifdef DEBUG
-		"    -d, --debug            Show debug information\n"
-#endif
-		"\n", EXEC_NAME);
-	printf("%s%s", ntfs_bugs, ntfs_home);
-	exit(1);
-}
-
-
-static void parse_options(int argc, char **argv)
-{
-	static const char *sopt = "-dhPv";
-	static const struct option lopt[] = {
-#ifdef DEBUG
-		{ "debug",		no_argument,	NULL, 'd' },
-#endif
-		{ "help",		no_argument,	NULL, 'h' },
-		{ "no-progress-bar",	no_argument,	NULL, 'P' },
-		{ "verbose",		no_argument,	NULL, 'v' },
-		{ NULL, 0, NULL, 0 }
-	};
-
-	int c;
-
-	memset(&opt, 0, sizeof(opt));
-	opt.show_progress = 1;
-
-	while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
-		switch (c) {
-		case 1:	/* A non-option argument */
-			if (!opt.vol1) {
-				opt.vol1 = argv[optind - 1];
-			} else if (!opt.vol2) {
-				opt.vol2 = argv[optind - 1];
-			} else {
-				err_printf("Too many arguments!\n");
-				usage();
-			}
-			break;
-#ifdef DEBUG
-		case 'd':
-			opt.debug++;
-			break;
-#endif
-		case 'h':
-		case '?':
-			usage();
-		case 'P':
-			opt.show_progress = 0;
-			break;
-		case 'v':
-			opt.verbose++;
-			break;
-		default:
-			err_printf("Unknown option '%s'.\n", argv[optind - 1]);
-			usage();
-			break;
-		}
-	}
-
-	if (opt.vol1 == NULL || opt.vol2 == NULL) {
-		err_printf("You must specify exactly 2 volumes.\n");
-		usage();
-	}
-
-	/* Redirect stderr to stdout, note fflush()es are essential! */
-	fflush(stdout);
-	fflush(stderr);
-	if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
-		perror("Failed to redirect stderr to stdout");
-		exit(1);
-	}
-	fflush(stdout);
-	fflush(stderr);
-
-#ifdef DEBUG
-	 if (!opt.debug)
-		if (!freopen("/dev/null", "w", stderr))
-			perr_exit("Failed to redirect stderr to /dev/null");
-#endif
-}
-
-static ntfs_attr_search_ctx *attr_get_search_ctx(ntfs_inode *ni)
-{
-	ntfs_attr_search_ctx *ret;
-
-	if ((ret = ntfs_attr_get_search_ctx(ni, NULL)) == NULL)
-		perr_println("ntfs_attr_get_search_ctx");
-
-	return ret;
-}
-
-static void progress_init(struct progress_bar *p, u64 start, u64 stop, int flags)
-{
-	p->start = start;
-	p->stop = stop;
-	p->unit = 100.0 / (stop - start);
-	p->resolution = 100;
-	p->flags = flags;
-}
-
-static void progress_update(struct progress_bar *p, u64 current)
-{
-	float percent;
-
-	if (!(p->flags & NTFS_PROGBAR))
-		return;
-	if (p->flags & NTFS_PROGBAR_SUPPRESS)
-		return;
-
-	/* WARNING: don't modify the texts, external tools grep for them */
-	percent = p->unit * current;
-	if (current != p->stop) {
-		if ((current - p->start) % p->resolution)
-			return;
-		printf("%6.2f percent completed\r", percent);
-	} else
-		printf("100.00 percent completed\n");
-	fflush(stdout);
-}
-
-static u64 inumber(ntfs_inode *ni)
-{
-	if (ni->nr_extents >= 0)
-		return ni->mft_no;
-
-	return ni->u.base_ni->mft_no;
-}
-
-static int inode_close(ntfs_inode *ni)
-{
-	if (ni == NULL)
-		return 0;
-
-	if (ntfs_inode_close(ni)) {
-		perr_println("ntfs_inode_close: inode %llu", inumber(ni));
-		return -1;
-	}
-	return 0;
-}
-
-static inline s64 get_nr_mft_records(ntfs_volume *vol)
-{
-	return vol->mft_na->initialized_size >> vol->mft_record_size_bits;
-}
-
-#define  NTFSCMP_OK				0
-#define  NTFSCMP_INODE_OPEN_ERROR		1
-#define  NTFSCMP_INODE_OPEN_IO_ERROR		2
-#define  NTFSCMP_INODE_OPEN_ENOENT_ERROR	3
-#define  NTFSCMP_EXTENSION_RECORD		4
-#define  NTFSCMP_INODE_CLOSE_ERROR		5
-
-static const char *ntfscmp_errs[] = {
-	"OK",
-	"INODE_OPEN_ERROR",
-	"INODE_OPEN_IO_ERROR",
-	"INODE_OPEN_ENOENT_ERROR",
-	"EXTENSION_RECORD",
-	"INODE_CLOSE_ERROR",
-	""
-};
-
-
-static const char *err2string(int err)
-{
-	return ntfscmp_errs[err];
-}
-
-static const char *pret2str(void *p)
-{
-	if (p == NULL)
-		return "FAILED";
-	return "OK";
-}
-
-static int inode_open(ntfs_volume *vol, MFT_REF mref, ntfs_inode **ni)
-{
-	*ni = ntfs_inode_open(vol, mref);
-	if (*ni == NULL) {
-		if (errno == EIO)
-			return NTFSCMP_INODE_OPEN_IO_ERROR;
-		if (errno == ENOENT)
-			return NTFSCMP_INODE_OPEN_ENOENT_ERROR;
-
-		perr_println("Reading inode %lld failed", mref);
-		return NTFSCMP_INODE_OPEN_ERROR;
-	}
-
-	if ((*ni)->mrec->base_mft_record) {
-
-		if (inode_close(*ni) != 0)
-			return NTFSCMP_INODE_CLOSE_ERROR;
-
-		return NTFSCMP_EXTENSION_RECORD;
-	}
-
-	return NTFSCMP_OK;
-}
-
-static ntfs_inode *base_inode(ntfs_attr_search_ctx *ctx)
-{
-	if (ctx->base_ntfs_ino)
-		return ctx->base_ntfs_ino;
-
-	return ctx->ntfs_ino;
-}
-
-static void print_inode(u64 inum)
-{
-	printf("Inode %llu ", inum);
-}
-
-static void print_inode_ni(ntfs_inode *ni)
-{
-	print_inode(inumber(ni));
-}
-
-static void print_attribute_type(ATTR_TYPES atype)
-{
-	printf("attribute 0x%x", atype);
-}
-
-static void print_attribute_name(char *name)
-{
-	if (name)
-		printf(":%s", name);
-}
-
-#define	GET_ATTR_NAME(a) \
-	((ntfschar *)(((u8 *)(a)) + le16_to_cpu((a)->name_offset))), \
-	((a)->name_length)
-
-static void free_name(char **name)
-{
-	if (*name) {
-		free(*name);
-		*name = NULL;
-	}
-}
-
-static char *get_attr_name(u64 mft_no,
-			   ATTR_TYPES atype,
-			   const ntfschar *uname,
-			   const int uname_len)
-{
-	char *name = NULL;
-	int name_len;
-
-	if (atype == AT_END)
-		return NULL;
-
-	name_len = ntfs_ucstombs(uname, uname_len, &name, 0);
-	if (name_len < 0) {
-		perr_print("ntfs_ucstombs");
-		print_inode(mft_no);
-		print_attribute_type(atype);
-		puts("");
-		exit(1);
-
-	} else if (name_len > 0)
-		return name;
-
-	free_name(&name);
-	return NULL;
-}
-
-static char *get_attr_name_na(ntfs_attr *na)
-{
-	return get_attr_name(inumber(na->ni), na->type, na->name, na->name_len);
-}
-
-static char *get_attr_name_ctx(ntfs_attr_search_ctx *ctx)
-{
-	u64 mft_no = inumber(ctx->ntfs_ino);
-	ATTR_TYPES atype = ctx->attr->type;
-
-	return get_attr_name(mft_no, atype, GET_ATTR_NAME(ctx->attr));
-}
-
-static void print_attribute(ATTR_TYPES atype, char *name)
-{
-	print_attribute_type(atype);
-	print_attribute_name(name);
-	printf(" ");
-}
-
-static void print_na(ntfs_attr *na)
-{
-	char *name = get_attr_name_na(na);
-	print_inode_ni(na->ni);
-	print_attribute(na->type, name);
-	free_name(&name);
-}
-
-static void print_attribute_ctx(ntfs_attr_search_ctx *ctx)
-{
-	char *name = get_attr_name_ctx(ctx);
-	print_attribute(ctx->attr->type, name);
-	free_name(&name);
-}
-
-static void print_ctx(ntfs_attr_search_ctx *ctx)
-{
-	char *name = get_attr_name_ctx(ctx);
-	print_inode_ni(base_inode(ctx));
-	print_attribute(ctx->attr->type, name);
-	free_name(&name);
-}
-
-static void print_differ(ntfs_attr *na)
-{
-	print_na(na);
-	printf("content:   DIFFER\n");
-}
-
-static int cmp_buffer(u8 *buf1, u8 *buf2, long long int size, ntfs_attr *na)
-{
-	if (memcmp(buf1, buf2, size)) {
-		print_differ(na);
-		return -1;
-	}
-	return 0;
-}
-
-struct cmp_ia {
-	INDEX_ALLOCATION *ia;
-	INDEX_ALLOCATION *tmp_ia;
-	u8 *bitmap;
-	u8 *byte;
-	s64 bm_size;
-};
-
-static int setup_cmp_ia(ntfs_attr *na, struct cmp_ia *cia)
-{
-	cia->bitmap = ntfs_attr_readall(na->ni, AT_BITMAP, na->name,
-					na->name_len, &cia->bm_size);
-	if (!cia->bitmap) {
-		perr_println("Failed to readall BITMAP");
-		return -1;
-	}
-	cia->byte = cia->bitmap;
-
-	cia->tmp_ia = cia->ia = ntfs_malloc(na->data_size);
-	if (!cia->tmp_ia)
-		goto free_bm;
-
-	if (ntfs_attr_pread(na, 0, na->data_size, cia->ia) != na->data_size) {
-		perr_println("Failed to pread INDEX_ALLOCATION");
-		goto free_ia;
-	}
-
-	return 0;
-free_ia:
-	free(cia->ia);
-free_bm:
-	free(cia->bitmap);
-	return -1;
-}
-
-static void cmp_index_allocation(ntfs_attr *na1, ntfs_attr *na2)
-{
-	struct cmp_ia cia1, cia2;
-	int bit, ret1, ret2;
-	u32 ib_size;
-
-	if (setup_cmp_ia(na1, &cia1))
-		return;
-	if (setup_cmp_ia(na2, &cia2))
-		return;
-	/*
-	 *  FIXME: ia can be the same even if the bitmap sizes are different.
-	 */
-	if (cia1.bm_size != cia1.bm_size)
-		goto out;
-
-	if (cmp_buffer(cia1.bitmap, cia2.bitmap, cia1.bm_size, na1))
-		goto out;
-
-	if (cmp_buffer((u8 *)cia1.ia, (u8 *)cia2.ia, 0x18, na1))
-		goto out;
-
-	ib_size = le32_to_cpu(cia1.ia->index.allocated_size) + 0x18;
-
-	bit = 0;
-	while ((u8 *)cia1.tmp_ia < (u8 *)cia1.ia + na1->data_size) {
-		if (*cia1.byte & (1 << bit)) {
-			ret1 = ntfs_mst_post_read_fixup((NTFS_RECORD *)
-					cia1.tmp_ia, ib_size);
-			ret2 = ntfs_mst_post_read_fixup((NTFS_RECORD *)
-					cia2.tmp_ia, ib_size);
-			if (ret1 != ret2) {
-				print_differ(na1);
-				goto out;
-			}
-
-			if (ret1 == -1)
-				continue;
-
-			if (cmp_buffer(((u8 *)cia1.tmp_ia) + 0x18,
-					((u8 *)cia2.tmp_ia) + 0x18,
-					le32_to_cpu(cia1.ia->
-					index.index_length), na1))
-				goto out;
-		}
-
-		cia1.tmp_ia = (INDEX_ALLOCATION *)((u8 *)cia1.tmp_ia + ib_size);
-		cia2.tmp_ia = (INDEX_ALLOCATION *)((u8 *)cia2.tmp_ia + ib_size);
-
-		bit++;
-		if (bit > 7) {
-			bit = 0;
-			cia1.byte++;
-		}
-	}
-out:
-	free(cia1.ia);
-	free(cia2.ia);
-	free(cia1.bitmap);
-	free(cia2.bitmap);
-	return;
-}
-
-static void cmp_attribute_data(ntfs_attr *na1, ntfs_attr *na2)
-{
-	s64 pos;
-	s64 count1 = 0, count2;
-	u8  buf1[NTFS_BUF_SIZE];
-	u8  buf2[NTFS_BUF_SIZE];
-
-	for (pos = 0; pos <= na1->data_size; pos += count1) {
-
-		count1 = ntfs_attr_pread(na1, pos, NTFS_BUF_SIZE, buf1);
-		count2 = ntfs_attr_pread(na2, pos, NTFS_BUF_SIZE, buf2);
-
-		if (count1 != count2) {
-			print_na(na1);
-			printf("abrupt length:   %lld  !=  %lld ",
-			       na1->data_size, na2->data_size);
-			printf("(count: %lld  !=  %lld)", count1, count2);
-			puts("");
-			return;
-		}
-
-		if (count1 == -1) {
-			err_printf("%s read error: ", "cmp_attribute_data");
-			print_na(na1);
-			printf("len = %lld, pos = %lld\n", na1->data_size, pos);
-			exit(1);
-		}
-
-		if (count1 == 0) {
-
-			if (pos + count1 == na1->data_size)
-				return; /* we are ready */
-
-			err_printf("%s read error before EOF: ", "cmp_attribute_data");
-			print_na(na1);
-			printf("%lld  !=  %lld\n", pos + count1, na1->data_size);
-			exit(1);
-		}
-
-		if (cmp_buffer(buf1, buf2, count1, na1))
-			return;
-	}
-
-	err_printf("%s read overrun: ", "cmp_attribute_data");
-	print_na(na1);
-	err_printf("(len = %lld, pos = %lld, count = %lld)\n",
-		  na1->data_size, pos, count1);
-	exit(1);
-}
-
-static int cmp_attribute_header(ATTR_RECORD *a1, ATTR_RECORD *a2)
-{
-	u32 header_size = offsetof(ATTR_RECORD, u.res.resident_end);
-
-	if (a1->non_resident != a2->non_resident)
-		return 1;
-
-	if (a1->non_resident) {
-		/*
-		 * FIXME: includes paddings which are not handled by ntfsinfo!
-		 */
-		header_size = le32_to_cpu(a1->length);
-	}
-
-	return memcmp(a1, a2, header_size);
-}
-
-static void cmp_attribute(ntfs_attr_search_ctx *ctx1,
-			  ntfs_attr_search_ctx *ctx2)
-{
-	ATTR_RECORD *a1 = ctx1->attr;
-	ATTR_RECORD *a2 = ctx2->attr;
-	ntfs_attr *na1, *na2;
-
-	if (cmp_attribute_header(a1, a2)) {
-		print_ctx(ctx1);
-		printf("header:    DIFFER\n");
-	}
-
-	na1 = ntfs_attr_open(base_inode(ctx1), a1->type, GET_ATTR_NAME(a1));
-	na2 = ntfs_attr_open(base_inode(ctx2), a2->type, GET_ATTR_NAME(a2));
-
-	if ((!na1 && na2) || (na1 && !na2)) {
-		print_ctx(ctx1);
-		printf("open:   %s  !=  %s\n", pret2str(na1), pret2str(na2));
-		goto close_attribs;
-	}
-
-	if (na1 == NULL)
-		goto close_attribs;
-
-	if (na1->data_size != na2->data_size) {
-		print_na(na1);
-		printf("length:   %lld  !=  %lld\n", na1->data_size, na2->data_size);
-		goto close_attribs;
-	}
-
-	if (ntfs_inode_badclus_bad(inumber(ctx1->ntfs_ino), ctx1->attr) == 1) {
-		/*
-		 * If difference exists then it's already reported at the
-		 * attribute header since the mapping pairs must differ.
-		 */
-		return;
-	}
-
-	if (na1->type == AT_INDEX_ALLOCATION)
-		cmp_index_allocation(na1, na2);
-	else
-		cmp_attribute_data(na1, na2);
-
-close_attribs:
-	ntfs_attr_close(na1);
-	ntfs_attr_close(na2);
-}
-
-static void vprint_attribute(ATTR_TYPES atype, char  *name)
-{
-	if (!opt.verbose)
-		return;
-
-	printf("0x%x", atype);
-	if (name)
-		printf(":%s", name);
-	printf(" ");
-}
-
-static void print_attributes(ntfs_inode *ni,
-			     ATTR_TYPES atype1,
-			     ATTR_TYPES atype2,
-			     char  *name1,
-			     char  *name2)
-{
-	if (!opt.verbose)
-		return;
-
-	printf("Walking inode %llu attributes: ", inumber(ni));
-	vprint_attribute(atype1, name1);
-	vprint_attribute(atype2, name2);
-	printf("\n");
-}
-
-static int new_name(ntfs_attr_search_ctx *ctx, char *prev_name)
-{
-	int ret = 0;
-	char *name = get_attr_name_ctx(ctx);
-
-	if (prev_name && name) {
-		if (strcmp(prev_name, name) != 0)
-			ret = 1;
-	} else if (prev_name || name)
-		ret = 1;
-
-	free_name(&name);
-	return ret;
-
-}
-
-static int new_attribute(ntfs_attr_search_ctx *ctx,
-			 ATTR_TYPES prev_atype,
-			 char *prev_name)
-{
-	if (!prev_atype && !prev_name)
-		return 1;
-
-	if (!ctx->attr->non_resident)
-		return 1;
-
-	if (prev_atype != ctx->attr->type)
-		return 1;
-
-	if (new_name(ctx, prev_name))
-		return 1;
-
-	if (opt.verbose) {
-		print_inode(base_inode(ctx)->mft_no);
-		print_attribute_ctx(ctx);
-		printf("record %llu lowest_vcn %lld:    SKIPPED\n",
-			ctx->ntfs_ino->mft_no, ctx->attr->u.nonres.lowest_vcn);
-	}
-
-	return 0;
-}
-
-static void set_prev(char **prev_name, ATTR_TYPES *prev_atype,
-		     char *name, ATTR_TYPES atype)
-{
-	free_name(prev_name);
-	if (name) {
-		*prev_name = strdup(name);
-		if (!*prev_name)
-			perr_exit("strdup error");
-	}
-
-	*prev_atype = atype;
-}
-
-static void set_cmp_attr(ntfs_attr_search_ctx *ctx, ATTR_TYPES *atype, char **name)
-{
-	*atype = ctx->attr->type;
-
-	free_name(name);
-	*name = get_attr_name_ctx(ctx);
-}
-
-static int next_attr(ntfs_attr_search_ctx *ctx, ATTR_TYPES *atype, char **name,
-		     int *err)
-{
-	int ret;
-
-	ret = ntfs_attrs_walk(ctx);
-	*err = errno;
-	if (ret) {
-		*atype = AT_END;
-		free_name(name);
-	} else
-		set_cmp_attr(ctx, atype, name);
-
-	return ret;
-}
-
-static int cmp_attributes(ntfs_inode *ni1, ntfs_inode *ni2)
-{
-	int ret = -1;
-	int old_ret1, ret1 = 0, ret2 = 0;
-	int errno1 = 0, errno2 = 0;
-	char  *prev_name = NULL, *name1 = NULL, *name2 = NULL;
-	ATTR_TYPES old_atype1, prev_atype = 0, atype1, atype2;
-	ntfs_attr_search_ctx *ctx1, *ctx2;
-
-	if (!(ctx1 = attr_get_search_ctx(ni1)))
-		return -1;
-	if (!(ctx2 = attr_get_search_ctx(ni2)))
-		goto out;
-
-	set_cmp_attr(ctx1, &atype1, &name1);
-	set_cmp_attr(ctx2, &atype2, &name2);
-
-	while (1) {
-
-		old_atype1 = atype1;
-		old_ret1 = ret1;
-		if (!ret1 && (le32_to_cpu(atype1) <= le32_to_cpu(atype2) ||
-				ret2))
-			ret1 = next_attr(ctx1, &atype1, &name1, &errno1);
-		if (!ret2 && (le32_to_cpu(old_atype1) >= le32_to_cpu(atype2) ||
-					old_ret1))
-			ret2 = next_attr(ctx2, &atype2, &name2, &errno2);
-
-		print_attributes(ni1, atype1, atype2, name1, name2);
-
-		if (ret1 && ret2) {
-			if (errno1 != errno2) {
-				print_inode_ni(ni1);
-				printf("attribute walk (errno):   %d  !=  %d\n",
-				       errno1, errno2);
-			}
-			break;
-		}
-
-		if (ret2 || le32_to_cpu(atype1) < le32_to_cpu(atype2)) {
-			if (new_attribute(ctx1, prev_atype, prev_name)) {
-				print_ctx(ctx1);
-				printf("presence:   EXISTS   !=   MISSING\n");
-				set_prev(&prev_name, &prev_atype, name1,
-						atype1);
-			}
-
-		} else if (ret1 || le32_to_cpu(atype1) > le32_to_cpu(atype2)) {
-			if (new_attribute(ctx2, prev_atype, prev_name)) {
-				print_ctx(ctx2);
-				printf("presence:   MISSING  !=  EXISTS \n");
-				set_prev(&prev_name, &prev_atype, name2, atype2);
-			}
-
-		} else /* atype1 == atype2 */ {
-			if (new_attribute(ctx1, prev_atype, prev_name)) {
-				cmp_attribute(ctx1, ctx2);
-				set_prev(&prev_name, &prev_atype, name1, atype1);
-			}
-		}
-	}
-
-	free_name(&prev_name);
-	ret = 0;
-	ntfs_attr_put_search_ctx(ctx2);
-out:
-	ntfs_attr_put_search_ctx(ctx1);
-	return ret;
-}
-
-static int cmp_inodes(ntfs_volume *vol1, ntfs_volume *vol2)
-{
-	u64 inode;
-	int ret1, ret2;
-	ntfs_inode *ni1, *ni2;
-	struct progress_bar progress;
-	int pb_flags = 0;	/* progress bar flags */
-	u64 nr_mft_records, nr_mft_records2;
-
-	if (opt.show_progress)
-		pb_flags |= NTFS_PROGBAR;
-
-	nr_mft_records  = get_nr_mft_records(vol1);
-	nr_mft_records2 = get_nr_mft_records(vol2);
-
-	if (nr_mft_records != nr_mft_records2) {
-
-		printf("Number of mft records:   %lld  !=  %lld\n",
-		       nr_mft_records, nr_mft_records2);
-
-		if (nr_mft_records > nr_mft_records2)
-			nr_mft_records = nr_mft_records2;
-	}
-
-	progress_init(&progress, 0, nr_mft_records - 1, pb_flags);
-	progress_update(&progress, 0);
-
-	for (inode = 0; inode < nr_mft_records; inode++) {
-
-		ret1 = inode_open(vol1, (MFT_REF)inode, &ni1);
-		ret2 = inode_open(vol2, (MFT_REF)inode, &ni2);
-
-		if (ret1 != ret2) {
-			print_inode(inode);
-			printf("open:   %s  !=  %s\n",
-			       err2string(ret1), err2string(ret2));
-			goto close_inodes;
-		}
-
-		if (ret1 != NTFSCMP_OK)
-			goto close_inodes;
-
-		if (cmp_attributes(ni1, ni2) != 0) {
-			inode_close(ni1);
-			inode_close(ni2);
-			return -1;
-		}
-close_inodes:
-		if (inode_close(ni1) != 0)
-			return -1;
-		if (inode_close(ni2) != 0)
-			return -1;
-
-		progress_update(&progress, inode);
-	}
-	return 0;
-}
-
-static ntfs_volume *mount_volume(const char *volume)
-{
-	unsigned long mntflag;
-	ntfs_volume *vol = NULL;
-
-	if (ntfs_check_if_mounted(volume, &mntflag)) {
-		perr_println("Failed to check '%s' mount state", volume);
-		printf("Probably /etc/mtab is missing. It's too risky to "
-		       "continue. You might try\nan another Linux distro.\n");
-		exit(1);
-	}
-	if (mntflag & NTFS_MF_MOUNTED) {
-		if (!(mntflag & NTFS_MF_READONLY))
-			err_exit("Device '%s' is mounted read-write. "
-				 "You must 'umount' it first.\n", volume);
-	}
-
-	vol = ntfs_mount(volume, NTFS_MNT_RDONLY);
-	if (vol == NULL) {
-
-		int err = errno;
-
-		perr_println("Opening '%s' as NTFS failed", volume);
-		if (err == EINVAL)
-			printf(invalid_ntfs_msg, volume);
-		else if (err == EIO)
-			puts(corrupt_volume_msg);
-		else if (err == EPERM)
-			puts(hibernated_volume_msg);
-		exit(1);
-	}
-
-	return vol;
-}
-
-int main(int argc, char **argv)
-{
-	ntfs_volume *vol1;
-	ntfs_volume *vol2;
-
-	printf("%s v%s (libntfs %s)\n", EXEC_NAME, VERSION,
-			ntfs_libntfs_version());
-
-	parse_options(argc, argv);
-
-	utils_set_locale();
-
-	vol1 = mount_volume(opt.vol1);
-        vol2 = mount_volume(opt.vol2);
-
-	if (cmp_inodes(vol1, vol2) != 0)
-		exit(1);
-
-	ntfs_umount(vol1, FALSE);
-	ntfs_umount(vol2, FALSE);
-
-	exit(0);
-}
-
