update to newest exfat changes
diff --git a/exfat/dump/dumpexfat.8 b/exfat/dump/dumpexfat.8
index 36fb28a..7fea065 100644
--- a/exfat/dump/dumpexfat.8
+++ b/exfat/dump/dumpexfat.8
@@ -13,7 +13,7 @@
 .B \-u
 ]
 [
-.B \-v
+.B \-V
 ]
 .I device
 
@@ -33,7 +33,7 @@
 Dump ranges of used sectors starting from 0 and separated with spaces. May be
 useful for backup tools.
 .TP
-.BI \-v
+.BI \-V
 Print version and copyright.
 
 .SH EXIT CODES
diff --git a/exfat/dump/main.c b/exfat/dump/main.c
index fa80903..8650d51 100644
--- a/exfat/dump/main.c
+++ b/exfat/dump/main.c
@@ -140,13 +140,13 @@
 
 static void usage(const char* prog)
 {
-	fprintf(stderr, "Usage: %s [-s] [-u] [-v] <device>\n", prog);
+	fprintf(stderr, "Usage: %s [-s] [-u] [-V] <device>\n", prog);
 	exit(1);
 }
 
 int main(int argc, char* argv[])
 {
-	char** pp;
+	int opt;
 	const char* spec = NULL;
 	bool sb_only = false;
 	bool used_sectors = false;
@@ -154,24 +154,26 @@
 	printf("dumpexfat %u.%u.%u\n",
 			EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);
 
-	for (pp = argv + 1; *pp; pp++)
+	while ((opt = getopt(argc, argv, "suV")) != -1)
 	{
-		if (strcmp(*pp, "-s") == 0)
-			sb_only = true;
-		else if (strcmp(*pp, "-u") == 0)
-			used_sectors = true;
-		else if (strcmp(*pp, "-v") == 0)
+		switch (opt)
 		{
+		case 's':
+			sb_only = true;
+			break;
+		case 'u':
+			used_sectors = true;
+			break;
+		case 'V':
 			puts("Copyright (C) 2011-2013  Andrew Nayenko");
 			return 0;
-		}
-		else if (spec == NULL)
-			spec = *pp;
-		else
+		default:
 			usage(argv[0]);
+		}
 	}
-	if (spec == NULL)
+	if (argc - optind != 1)
 		usage(argv[0]);
+	spec = argv[optind];
 
 	if (sb_only)
 		return dump_sb(spec);
diff --git a/exfat/exfat-fuse/main.c b/exfat/exfat-fuse/main.c
index 0023b9d..53ce2fe 100644
--- a/exfat/exfat-fuse/main.c
+++ b/exfat/exfat-fuse/main.c
@@ -92,7 +92,7 @@
 	struct exfat_node* node;
 	struct exfat_iterator it;
 	int rc;
-	char name[EXFAT_NAME_MAX + 1];
+	char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
 
 	exfat_debug("[%s] %s", __func__, path);
 
@@ -118,7 +118,7 @@
 	}
 	while ((node = exfat_readdir(&ef, &it)))
 	{
-		exfat_get_name(node, name, EXFAT_NAME_MAX);
+		exfat_get_name(node, name, sizeof(name) - 1);
 		exfat_debug("[%s] %s: %s, %"PRId64" bytes, cluster 0x%x", __func__,
 				name, IS_CONTIGUOUS(*node) ? "contiguous" : "fragmented",
 				node->size, node->start_cluster);
@@ -242,14 +242,24 @@
 	return 0;
 }
 
-#ifdef __APPLE__
 static int fuse_exfat_chmod(const char* path, mode_t mode)
 {
+	const mode_t VALID_MODE_MASK = S_IFREG | S_IFDIR |
+			S_IRWXU | S_IRWXG | S_IRWXO;
+
 	exfat_debug("[%s] %s 0%ho", __func__, path, mode);
-	/* make OS X utilities happy */
+	if (mode & ~VALID_MODE_MASK)
+		return -EPERM;
 	return 0;
 }
-#endif
+
+static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid)
+{
+	exfat_debug("[%s] %s %u:%u", __func__, path, uid, gid);
+	if (uid != ef.uid || gid != ef.gid)
+		return -EPERM;
+	return 0;
+}
 
 static int fuse_exfat_statfs(const char* path, struct statvfs* sfs)
 {
@@ -292,7 +302,7 @@
 
 static void usage(const char* prog)
 {
-	fprintf(stderr, "Usage: %s [-d] [-o options] [-v] <device> <dir>\n", prog);
+	fprintf(stderr, "Usage: %s [-d] [-o options] [-V] <device> <dir>\n", prog);
 	exit(1);
 }
 
@@ -311,9 +321,8 @@
 	.mkdir		= fuse_exfat_mkdir,
 	.rename		= fuse_exfat_rename,
 	.utimens	= fuse_exfat_utimens,
-#ifdef __APPLE__
 	.chmod		= fuse_exfat_chmod,
-#endif
+	.chown		= fuse_exfat_chown,
 	.statfs		= fuse_exfat_statfs,
 	.init		= fuse_exfat_init,
 	.destroy	= fuse_exfat_destroy,
@@ -398,7 +407,7 @@
 	int debug = 0;
 	struct fuse_chan* fc = NULL;
 	struct fuse* fh = NULL;
-	char** pp;
+	int opt;
 
 	printf("FUSE exfat %u.%u.%u\n",
 			EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);
@@ -410,40 +419,39 @@
 		return 1;
 	}
 
-	for (pp = argv + 1; *pp; pp++)
+	while ((opt = getopt(argc, argv, "dno:Vv")) != -1)
 	{
-		if (strcmp(*pp, "-o") == 0)
+		switch (opt)
 		{
-			pp++;
-			if (*pp == NULL)
-				usage(argv[0]);
-			mount_options = add_option(mount_options, *pp, NULL);
+		case 'd':
+			debug = 1;
+			break;
+		case 'n':
+			break;
+		case 'o':
+			mount_options = add_option(mount_options, optarg, NULL);
 			if (mount_options == NULL)
 				return 1;
-		}
-		else if (strcmp(*pp, "-d") == 0)
-			debug = 1;
-		else if (strcmp(*pp, "-v") == 0)
-		{
+			break;
+		case 'V':
 			free(mount_options);
 			puts("Copyright (C) 2010-2013  Andrew Nayenko");
 			return 0;
-		}
-		else if (spec == NULL)
-			spec = *pp;
-		else if (mount_point == NULL)
-			mount_point = *pp;
-		else
-		{
+		case 'v':
+			break;
+		default:
 			free(mount_options);
 			usage(argv[0]);
+			break;
 		}
 	}
-	if (spec == NULL || mount_point == NULL)
+	if (argc - optind != 2)
 	{
 		free(mount_options);
 		usage(argv[0]);
 	}
+	spec = argv[optind];
+	mount_point = argv[optind + 1];
 
 	if (exfat_mount(&ef, spec, mount_options) != 0)
 	{
diff --git a/exfat/exfat-fuse/mount.exfat-fuse.8 b/exfat/exfat-fuse/mount.exfat-fuse.8
index 83d2e63..b7e9d56 100644
--- a/exfat/exfat-fuse/mount.exfat-fuse.8
+++ b/exfat/exfat-fuse/mount.exfat-fuse.8
@@ -9,10 +9,16 @@
 .B \-d
 ]
 [
+.B \-n
+]
+[
 .B \-o
 .I options
 ]
 [
+.B \-V
+]
+[
 .B \-v
 ]
 .I device dir
@@ -21,7 +27,7 @@
 .B mount.exfat-fuse
 is a free exFAT file system implementation with write support. exFAT is a
 simple file system created by Microsoft. It is intended to replace FAT32
-removing some of it's limitations. exFAT is a standard FS for SDXC memory
+removing some of its limitations. exFAT is a standard FS for SDXC memory
 cards.
 
 .SH COMMAND LINE OPTIONS
@@ -30,13 +36,19 @@
 .BI \-d
 Enable debug logging and do not detach from shell.
 .TP
+.BI \-n
+Ignored.
+.TP
 .BI \-o " options"
 File system specific options. For more details see
 .B FILE SYSTEM OPTIONS
 section below.
 .TP
-.BI \-v
+.BI \-V
 Print version and copyright.
+.TP
+.BI \-v
+Ignored.
 
 .SH FILE SYSTEM OPTIONS
 .TP
diff --git a/exfat/fsck/exfatfsck.8 b/exfat/fsck/exfatfsck.8
index 985500c..40d7c85 100644
--- a/exfat/fsck/exfatfsck.8
+++ b/exfat/fsck/exfatfsck.8
@@ -7,7 +7,7 @@
 .SH SYNOPSIS
 .B exfatfsck
 [
-.B \-v
+.B \-V
 ]
 .I device
 
@@ -19,7 +19,7 @@
 .SH COMMAND LINE OPTIONS
 Command line options available:
 .TP
-.BI \-v
+.BI \-V
 Print version and copyright.
 
 .SH EXIT CODES
diff --git a/exfat/fsck/main.c b/exfat/fsck/main.c
index 9eefd74..e865641 100644
--- a/exfat/fsck/main.c
+++ b/exfat/fsck/main.c
@@ -23,6 +23,7 @@
 #include <exfat.h>
 #include <exfatfs.h>
 #include <inttypes.h>
+#include <unistd.h>
 
 #define exfat_debug(format, ...)
 
@@ -39,18 +40,18 @@
 	{
 		if (CLUSTER_INVALID(c))
 		{
-			char name[EXFAT_NAME_MAX + 1];
+			char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
 
-			exfat_get_name(node, name, EXFAT_NAME_MAX);
+			exfat_get_name(node, name, sizeof(name) - 1);
 			exfat_error("file `%s' has invalid cluster 0x%x", name, c);
 			rc = 1;
 			break;
 		}
 		if (BMAP_GET(ef->cmap.chunk, c - EXFAT_FIRST_DATA_CLUSTER) == 0)
 		{
-			char name[EXFAT_NAME_MAX + 1];
+			char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
 
-			exfat_get_name(node, name, EXFAT_NAME_MAX);
+			exfat_get_name(node, name, sizeof(name) - 1);
 			exfat_error("cluster 0x%x of file `%s' is not allocated", c, name);
 			rc = 1;
 		}
@@ -76,7 +77,7 @@
 		return;
 
 	path_length = strlen(path);
-	entry_path = malloc(path_length + 1 + EXFAT_NAME_MAX);
+	entry_path = malloc(path_length + 1 + UTF8_BYTES(EXFAT_NAME_MAX) + 1);
 	if (entry_path == NULL)
 	{
 		exfat_error("out of memory");
@@ -95,7 +96,8 @@
 	}
 	while ((node = exfat_readdir(ef, &it)))
 	{
-		exfat_get_name(node, entry_path + path_length + 1, EXFAT_NAME_MAX);
+		exfat_get_name(node, entry_path + path_length + 1,
+				UTF8_BYTES(EXFAT_NAME_MAX));
 		exfat_debug("%s: %s, %"PRIu64" bytes, cluster %u", entry_path,
 				IS_CONTIGUOUS(*node) ? "contiguous" : "fragmented",
 				node->size, node->start_cluster);
@@ -124,33 +126,34 @@
 
 static void usage(const char* prog)
 {
-	fprintf(stderr, "Usage: %s [-v] <device>\n", prog);
+	fprintf(stderr, "Usage: %s [-V] <device>\n", prog);
 	exit(1);
 }
 
 int main(int argc, char* argv[])
 {
-	char** pp;
+	int opt;
 	const char* spec = NULL;
 	struct exfat ef;
 
 	printf("exfatfsck %u.%u.%u\n",
 			EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);
 
-	for (pp = argv + 1; *pp; pp++)
+	while ((opt = getopt(argc, argv, "V")) != -1)
 	{
-		if (strcmp(*pp, "-v") == 0)
+		switch (opt)
 		{
+		case 'V':
 			puts("Copyright (C) 2011-2013  Andrew Nayenko");
 			return 0;
-		}
-		else if (spec == NULL)
-			spec = *pp;
-		else
+		default:
 			usage(argv[0]);
+			break;
+		}
 	}
-	if (spec == NULL)
+	if (argc - optind != 1)
 		usage(argv[0]);
+	spec = argv[optind];
 
 	if (exfat_mount(&ef, spec, "ro") != 0)
 		return 1;
diff --git a/exfat/label/exfatlabel.8 b/exfat/label/exfatlabel.8
index 429f3cc..dd2ef1c 100644
--- a/exfat/label/exfatlabel.8
+++ b/exfat/label/exfatlabel.8
@@ -7,7 +7,7 @@
 .SH SYNOPSIS
 .B exfatlabel
 [
-.B \-v
+.B \-V
 ]
 .I device
 [
@@ -35,7 +35,7 @@
 .SH COMMAND LINE OPTIONS
 Command line options available:
 .TP
-.BI \-v
+.BI \-V
 Print version and copyright.
 
 .SH EXIT CODES
diff --git a/exfat/label/main.c b/exfat/label/main.c
index 8a429d5..5595035 100644
--- a/exfat/label/main.c
+++ b/exfat/label/main.c
@@ -29,7 +29,7 @@
 	int rc = 0;
 
 	for (pp = argv + 1; *pp; pp++)
-		if (strcmp(*pp, "-v") == 0)
+		if (strcmp(*pp, "-V") == 0)
 		{
 			printf("exfatlabel %u.%u.%u\n", EXFAT_VERSION_MAJOR,
 					EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);
@@ -39,7 +39,7 @@
 
 	if (argc != 2 && argc != 3)
 	{
-		fprintf(stderr, "Usage: %s [-v] <device> [label]\n", argv[0]);
+		fprintf(stderr, "Usage: %s [-V] <device> [label]\n", argv[0]);
 		return 1;
 	}
 
diff --git a/exfat/libexfat/exfat.h b/exfat/libexfat/exfat.h
index 3e4223e..a6a9f70 100644
--- a/exfat/libexfat/exfat.h
+++ b/exfat/libexfat/exfat.h
@@ -46,6 +46,7 @@
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define DIV_ROUND_UP(x, d) (((x) + (d) - 1) / (d))
 #define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d))
+#define UTF8_BYTES(c) ((c) * 6) /* UTF-8 character can occupy up to 6 bytes */
 
 #define BMAP_GET(bitmap, index) \
 	(((uint8_t*) bitmap)[(index) / 8] & (1u << ((index) % 8)))
@@ -98,8 +99,7 @@
 		bool dirty;
 	}
 	cmap;
-	char label[EXFAT_ENAME_MAX * 6 + 1]; /* a character can occupy up to
-											6 bytes in UTF-8 */
+	char label[UTF8_BYTES(EXFAT_ENAME_MAX) + 1];
 	void* zero_cluster;
 	int dmask, fmask;
 	uid_t uid;
diff --git a/exfat/libexfat/node.c b/exfat/libexfat/node.c
index c2ee0da..f89b573 100644
--- a/exfat/libexfat/node.c
+++ b/exfat/libexfat/node.c
@@ -44,8 +44,8 @@
 {
 	if (--node->references < 0)
 	{
-		char buffer[EXFAT_NAME_MAX + 1];
-		exfat_get_name(node, buffer, EXFAT_NAME_MAX);
+		char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+		exfat_get_name(node, buffer, sizeof(buffer) - 1);
 		exfat_bug("reference counter of `%s' is below zero", buffer);
 	}
 
@@ -293,9 +293,9 @@
 				*/
 				if (real_size != (*node)->size)
 				{
-					char buffer[EXFAT_NAME_MAX + 1];
+					char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
 
-					exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
+					exfat_get_name(*node, buffer, sizeof(buffer) - 1);
 					exfat_error("`%s' real size does not equal to size "
 							"(%"PRIu64" != %"PRIu64")", buffer,
 							real_size, (*node)->size);
@@ -303,9 +303,9 @@
 				}
 				if (actual_checksum != reference_checksum)
 				{
-					char buffer[EXFAT_NAME_MAX + 1];
+					char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
 
-					exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
+					exfat_get_name(*node, buffer, sizeof(buffer) - 1);
 					exfat_error("`%s' has invalid checksum (0x%hx != 0x%hx)",
 							buffer, actual_checksum, reference_checksum);
 					goto error;
@@ -389,7 +389,7 @@
 				goto error;
 			}
 			if (utf16_to_utf8(ef->label, label->name,
-						sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
+						sizeof(ef->label) - 1, EXFAT_ENAME_MAX) != 0)
 				goto error;
 			break;
 
@@ -493,8 +493,8 @@
 	node->flags &= ~EXFAT_ATTRIB_CACHED;
 	if (node->references != 0)
 	{
-		char buffer[EXFAT_NAME_MAX + 1];
-		exfat_get_name(node, buffer, EXFAT_NAME_MAX);
+		char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+		exfat_get_name(node, buffer, sizeof(buffer) - 1);
 		exfat_warn("non-zero reference counter (%d) for `%s'",
 				node->references, buffer);
 	}
@@ -1051,5 +1051,6 @@
 
 	exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
 			co2o(ef, cluster, offset));
+	strcpy(ef->label, label);
 	return 0;
 }
diff --git a/exfat/mkfs/main.c b/exfat/mkfs/main.c
index 97e465a..12bb838 100644
--- a/exfat/mkfs/main.c
+++ b/exfat/mkfs/main.c
@@ -188,14 +188,14 @@
 {
 	fprintf(stderr, "Usage: %s [-i volume-id] [-n label] "
 			"[-p partition-first-sector] "
-			"[-s sectors-per-cluster] [-v] <device>\n", prog);
+			"[-s sectors-per-cluster] [-V] <device>\n", prog);
 	exit(1);
 }
 
 int main(int argc, char* argv[])
 {
 	const char* spec = NULL;
-	char** pp;
+	int opt;
 	int spc_bits = -1;
 	const char* volume_label = NULL;
 	uint32_t volume_serial = 0;
@@ -205,53 +205,38 @@
 	printf("mkexfatfs %u.%u.%u\n",
 			EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH);
 
-	for (pp = argv + 1; *pp; pp++)
+	while ((opt = getopt(argc, argv, "i:n:p:s:V")) != -1)
 	{
-		if (strcmp(*pp, "-s") == 0)
+		switch (opt)
 		{
-			pp++;
-			if (*pp == NULL)
-				usage(argv[0]);
-			spc_bits = logarithm2(atoi(*pp));
+		case 'i':
+			volume_serial = strtol(optarg, NULL, 16);
+			break;
+		case 'n':
+			volume_label = optarg;
+			break;
+		case 'p':
+			first_sector = strtoll(optarg, NULL, 10);
+			break;
+		case 's':
+			spc_bits = logarithm2(atoi(optarg));
 			if (spc_bits < 0)
 			{
-				exfat_error("invalid option value: `%s'", *pp);
+				exfat_error("invalid option value: `%s'", optarg);
 				return 1;
 			}
-		}
-		else if (strcmp(*pp, "-n") == 0)
-		{
-			pp++;
-			if (*pp == NULL)
-				usage(argv[0]);
-			volume_label = *pp;
-		}
-		else if (strcmp(*pp, "-i") == 0)
-		{
-			pp++;
-			if (*pp == NULL)
-				usage(argv[0]);
-			volume_serial = strtol(*pp, NULL, 16);
-		}
-		else if (strcmp(*pp, "-p") == 0)
-		{
-			pp++;
-			if (*pp == NULL)
-				usage(argv[0]);
-			first_sector = strtoll(*pp, NULL, 10);
-		}
-		else if (strcmp(*pp, "-v") == 0)
-		{
+			break;
+		case 'V':
 			puts("Copyright (C) 2011-2013  Andrew Nayenko");
 			return 0;
-		}
-		else if (spec == NULL)
-			spec = *pp;
-		else
+		default:
 			usage(argv[0]);
+			break;
+		}
 	}
-	if (spec == NULL)
+	if (argc - optind != 1)
 		usage(argv[0]);
+	spec = argv[optind];
 
 	dev = exfat_open(spec, EXFAT_MODE_RW);
 	if (dev == NULL)
diff --git a/exfat/mkfs/mkexfatfs.8 b/exfat/mkfs/mkexfatfs.8
index 7d3ffec..5f6ba3d 100644
--- a/exfat/mkfs/mkexfatfs.8
+++ b/exfat/mkfs/mkexfatfs.8
@@ -23,7 +23,7 @@
 .I sectors-per-cluster
 ]
 [
-.B \-v
+.B \-V
 ]
 .I device
 
@@ -55,7 +55,7 @@
 32 KB if volume size is from 256 MB to 32 GB,
 128 KB if volume size is 32 GB or larger.
 .TP
-.BI \-v
+.BI \-V
 Print version and copyright.
 
 .SH EXIT CODES