]> git.sven.stormbind.net Git - sven/fuse-exfat.git/commitdiff
Imported Upstream version 1.2.4 upstream/1.2.4
authorSven Hoexter <sven@timegate.de>
Sat, 25 Jun 2016 12:12:02 +0000 (14:12 +0200)
committerSven Hoexter <sven@timegate.de>
Sat, 25 Jun 2016 12:12:02 +0000 (14:12 +0200)
26 files changed:
ChangeLog
Makefile.am
Makefile.in
README
configure
configure.ac
fuse/Makefile.am
fuse/Makefile.in
fuse/main.c
fuse/mount.exfat-fuse.8
libexfat/Makefile.am
libexfat/Makefile.in
libexfat/byteorder.h
libexfat/cluster.c
libexfat/compiler.h
libexfat/exfat.h
libexfat/exfatfs.h
libexfat/io.c
libexfat/log.c
libexfat/lookup.c
libexfat/mount.c
libexfat/node.c
libexfat/platform.h
libexfat/time.c
libexfat/utf.c
libexfat/utils.c

index 05cd191e38a23154ae4cbd23ee3c2096b3d75532..78268258bc6092c644e4ad2da24e4d94f6294e12 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+1.2.4 (2016-06-03)
+
+* Fixed wrong files names hashes when upper case table is compressed.
+* Man pages are now installed by default.
+* Commas and backslashes in device names are now escaped.
+
 1.2.3 (2015-12-19)
 
 * Fixed clusters loss when file renaming replaces target.
index 4a50b0b3f5ff080b7895fa9c638a4524edd8d821..4a045321efd666f0b089bab511a55782e8ee45f7 100644 (file)
@@ -3,7 +3,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
index d5593ce955649f38505874cfe61d5a224974aec4..55986d231b1900100607a08eb5d22b5b2e5ca83b 100644 (file)
@@ -19,7 +19,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
diff --git a/README b/README
index 8f2fe85cb9a9689824098855ce027a9bc8a93f7b..500d72234ab2037b78c908b71f7b07ccf0bf8640 100644 (file)
--- a/README
+++ b/README
@@ -7,7 +7,6 @@ Supported operating systems:
 
 * GNU/Linux
 * Mac OS X 10.5 or later
-* FreeBSD
 * OpenBSD
 
 Most GNU/Linux distributions already have fuse-exfat and exfat-utils in their repositories, so you can just install and use them. The next chapter describes how to compile them from source.
@@ -15,40 +14,56 @@ Most GNU/Linux distributions already have fuse-exfat and exfat-utils in their re
 Compiling
 ---------
 
-To build this project under GNU/Linux you need to install the following packages:
+To build this project on GNU/Linux you need to install the following packages:
 
-* pkg-config
+* [pkg-config][7]
 * fuse-devel (or libfuse-dev)
-* gcc
-* make
+* [gcc][8]
+* [make][9]
+
+On Mac OS X:
+
+* pkg-config
+* [OSXFUSE][10]
+* [Xcode][11] (legacy versions include autotools but their versions are too old)
+
+On OpenBSD:
+
 
 Get the source code, change directory and compile:
 
-    ./configure --prefix=/usr
+    ./configure
     make
 
-Then install driver and utilities:
+Then install driver and utilities (from root):
 
-    sudo make install
+    make install
 
-You can remove them using this command:
+You can remove them using this command (from root):
 
-    sudo make uninstall
+    make uninstall
 
 Mounting
 --------
 
-Modern GNU/Linux distributions will mount exFAT volumes automatically—util-linux-ng 2.18 (was renamed to util-linux in 2.19) is required for this. Anyway, you can mount manually (you will need root privileges):
+Modern GNU/Linux distributions (with [util-linux][12] 2.18 or later) will mount exFAT volumes automatically. Anyway, you can mount manually (from root):
 
-    sudo mount.exfat-fuse /dev/sdXn /mnt/exfat
+    mount.exfat-fuse /dev/spec /mnt/exfat
 
-where /dev/sdXn is the partition special file, /mnt/exfat is a mountpoint.
+where /dev/spec is the [device file][13], /mnt/exfat is a mountpoint.
 
 Feedback
 --------
 
 If you have any questions, issues, suggestions, bug reports, etc. please create an [issue][3]. Pull requests are also welcome!
 
-[1]: http://en.wikipedia.org/wiki/ExFAT
-[2]: http://en.wikipedia.org/wiki/Filesystem_in_Userspace
+[1]: https://en.wikipedia.org/wiki/ExFAT
+[2]: https://en.wikipedia.org/wiki/Filesystem_in_Userspace
 [3]: https://github.com/relan/exfat/issues
+[7]: http://www.freedesktop.org/wiki/Software/pkg-config/
+[8]: https://gcc.gnu.org/
+[9]: https://www.gnu.org/software/make/
+[10]: https://osxfuse.github.io/
+[11]: https://en.wikipedia.org/wiki/Xcode
+[12]: https://www.kernel.org/pub/linux/utils/util-linux/
+[13]: https://en.wikipedia.org/wiki/Device_file
index afda1d26bbe43a76f259d80e9095e911bdbf16ff..d6ecc42bbe2f8f0f708339638dd9e09a89ae24a2 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Free exFAT implementation 1.2.3.
+# Generated by GNU Autoconf 2.69 for Free exFAT implementation 1.2.4.
 #
 # Report bugs to <relan@users.noreply.github.com>.
 #
@@ -579,8 +579,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='Free exFAT implementation'
 PACKAGE_TARNAME='fuse-exfat'
-PACKAGE_VERSION='1.2.3'
-PACKAGE_STRING='Free exFAT implementation 1.2.3'
+PACKAGE_VERSION='1.2.4'
+PACKAGE_STRING='Free exFAT implementation 1.2.4'
 PACKAGE_BUGREPORT='relan@users.noreply.github.com'
 PACKAGE_URL='https://github.com/relan/exfat'
 
@@ -1238,7 +1238,7 @@ 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 Free exFAT implementation 1.2.3 to adapt to many kinds of systems.
+\`configure' configures Free exFAT implementation 1.2.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1304,7 +1304,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Free exFAT implementation 1.2.3:";;
+     short | recursive ) echo "Configuration of Free exFAT implementation 1.2.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1403,7 +1403,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Free exFAT implementation configure 1.2.3
+Free exFAT implementation configure 1.2.4
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1458,7 +1458,7 @@ cat >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 Free exFAT implementation $as_me 1.2.3, which was
+It was created by Free exFAT implementation $as_me 1.2.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2321,7 +2321,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='fuse-exfat'
- VERSION='1.2.3'
+ VERSION='1.2.4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4839,7 +4839,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Free exFAT implementation $as_me 1.2.3, which was
+This file was extended by Free exFAT implementation $as_me 1.2.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4906,7 +4906,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Free exFAT implementation config.status 1.2.3
+Free exFAT implementation config.status 1.2.4
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 43e31e4b855bade50338be19d0b611f32f8b537c..4395817aa9abcc9cb0e00617da8290181031dd39 100644 (file)
@@ -3,7 +3,7 @@
 #      Autoconf source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
 #
 
 AC_INIT([Free exFAT implementation],
-       [1.2.3],
+       [1.2.4],
        [relan@users.noreply.github.com],
        [fuse-exfat],
        [https://github.com/relan/exfat])
-AM_INIT_AUTOMAKE([1.11.2 -Wall -Werror foreign subdir-objects no-installman])
+AM_INIT_AUTOMAKE([1.11.2 -Wall -Werror foreign subdir-objects])
 AC_PROG_CC
 AC_PROG_CC_C99
 AC_PROG_RANLIB
index ce36b351597cc6f1317468694612a1aa5067a30a..8f69cf4b73a7a33257c5a294825862587c287c4c 100644 (file)
@@ -3,7 +3,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
index caece23dea07e49aef155094bf759889f722f493..8af78768f3c677f48eaa4e44d8df90b4873975f5 100644 (file)
@@ -19,7 +19,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
@@ -119,7 +119,7 @@ mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/libexfat/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
 PROGRAMS = $(sbin_PROGRAMS)
 am_mount_exfat_fuse_OBJECTS = mount_exfat_fuse-main.$(OBJEXT)
 mount_exfat_fuse_OBJECTS = $(am_mount_exfat_fuse_OBJECTS)
@@ -433,7 +433,6 @@ mount_exfat_fuse-main.obj: main.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='main.c' object='mount_exfat_fuse-main.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mount_exfat_fuse_CPPFLAGS) $(CPPFLAGS) $(mount_exfat_fuse_CFLAGS) $(CFLAGS) -c -o mount_exfat_fuse-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
-
 install-man8: $(dist_man8_MANS)
        @$(NORMAL_INSTALL)
        @list1='$(dist_man8_MANS)'; \
@@ -560,9 +559,9 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(MANS)
 installdirs:
-       for dir in "$(DESTDIR)$(sbindir)"; do \
+       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: install-am
@@ -617,7 +616,7 @@ info: info-am
 
 info-am:
 
-install-data-am:
+install-data-am: install-man
 
 install-dvi: install-dvi-am
 
@@ -663,7 +662,7 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-sbinPROGRAMS
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS
        @$(NORMAL_INSTALL)
        $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
 uninstall-man: uninstall-man8
index aad082b68f21265f21686cdab57097ecafc60b4d..bc0faf3e773a80bfd828c51c49d5f036b5c8567b 100644 (file)
@@ -3,7 +3,7 @@
        FUSE-based exFAT implementation. Requires FUSE 2.6 or later.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -427,6 +427,36 @@ static char* add_option(char* options, const char* name, const char* value)
        return options;
 }
 
+static void escape(char* escaped, const char* orig)
+{
+       do
+       {
+               if (*orig == ',' || *orig == '\\')
+                       *escaped++ = '\\';
+       }
+       while ((*escaped++ = *orig++));
+}
+
+static char* add_fsname_option(char* options, const char* spec)
+{
+       /* escaped string cannot be more than twice as big as the original one */
+       char* escaped = malloc(strlen(spec) * 2 + 1);
+
+       if (escaped == NULL)
+       {
+               free(options);
+               exfat_error("failed to allocate escaped string for %s", spec);
+               return NULL;
+       }
+
+       /* on some platforms (e.g. Android, Solaris) device names can contain
+          commas */
+       escape(escaped, spec);
+       options = add_option(options, "fsname", escaped);
+       free(escaped);
+       return options;
+}
+
 static char* add_user_option(char* options)
 {
        struct passwd* pw;
@@ -458,7 +488,7 @@ static char* add_blksize_option(char* options, long cluster_size)
 
 static char* add_fuse_options(char* options, const char* spec)
 {
-       options = add_option(options, "fsname", spec);
+       options = add_fsname_option(options, spec);
        if (options == NULL)
                return NULL;
        options = add_user_option(options);
@@ -508,7 +538,7 @@ int main(int argc, char* argv[])
                        break;
                case 'V':
                        free(mount_options);
-                       puts("Copyright (C) 2010-2015  Andrew Nayenko");
+                       puts("Copyright (C) 2010-2016  Andrew Nayenko");
                        return 0;
                case 'v':
                        break;
index 38586ca45dd3bb686e9db316d4526ff707b8e376..602ddc9867ec2ba6a382a286f0647c653ab34fb8 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2010-2015  Andrew Nayenko
+.\" Copyright (C) 2010-2016  Andrew Nayenko
 .\"
 .TH EXFAT-FUSE 8 "July 2010"
 .SH NAME
index f9067e98c5a33ee085e9297c34628b1422b914c4..102d89d6b14a3aa6e7bd75b36df9fc1cab093c27 100644 (file)
@@ -3,7 +3,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
index 6603fde74739bf03f45fb5d52d2b00935a98c3c7..f10c73aa6e9fa24aa9bd29f153fe130011db08de 100644 (file)
@@ -19,7 +19,7 @@
 #      Automake source.
 #
 #      Free exFAT implementation.
-#      Copyright (C) 2010-2015  Andrew Nayenko
+#      Copyright (C) 2010-2016  Andrew Nayenko
 #
 #      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
index 472cb487cd838cc88d356032726b723a121bf7a5..e417ad6a3fb424a2728e74e3625784321a75268c 100644 (file)
@@ -3,7 +3,7 @@
        Endianness stuff. exFAT uses little-endian byte order.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index fc3657b53f62e0ba101d6ed2be35b36ca87f8d38..13bc6ce90616b679a379c1f4e3d4ff47471a85d9 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index 1a4742e56f3fa6ae0d4474bdf3139f90ad59d154..b590d01902637271a774da3f798427a6ee18e1bd 100644 (file)
@@ -4,7 +4,7 @@
        showstopper.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index 97d3692b0a08decd527a9850dfab37cdf0a38aab..75cb6e674ca415151e6ce7c74fefbc65b2e6b6c6 100644 (file)
@@ -4,7 +4,7 @@
        implementation.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -97,8 +97,7 @@ struct exfat
 {
        struct exfat_dev* dev;
        struct exfat_super_block* sb;
-       le16_t* upcase;
-       size_t upcase_chars;
+       uint16_t* upcase;
        struct exfat_node* root;
        struct
        {
index eca2cacea15613b11a53b623691f2decccee091e..c155312e15ed928430fc6cf24ced8aadd38a6dbd 100644 (file)
@@ -3,7 +3,7 @@
        Definitions of structures and constants used in exFAT file system.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -99,6 +99,8 @@ struct exfat_entry_bitmap                     /* allocated clusters bitmap */
 PACKED;
 STATIC_ASSERT(sizeof(struct exfat_entry_bitmap) == 32);
 
+#define EXFAT_UPCASE_CHARS 0x10000
+
 struct exfat_entry_upcase                      /* upper case translation table */
 {
        uint8_t type;                                   /* EXFAT_ENTRY_UPCASE */
index 3d7aaad2e903db2f2dbacd56d8bac62816560f46..60f28e2b88ac42740fc709fe4fb8e0673ae2f035 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
 #include <sys/ioctl.h>
 #endif
 #include <sys/mount.h>
-#ifdef USE_UBLIO
-#include <sys/uio.h>
-#include <ublio.h>
-#endif
 
 struct exfat_dev
 {
        int fd;
        enum exfat_mode mode;
        off_t size; /* in bytes */
-#ifdef USE_UBLIO
-       off_t pos;
-       ublio_filehandle_t ufh;
-#endif
 };
 
 static int open_ro(const char* spec)
@@ -82,9 +74,6 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode)
 {
        struct exfat_dev* dev;
        struct stat stbuf;
-#ifdef USE_UBLIO
-       struct ublio_param up;
-#endif
 
        dev = malloc(sizeof(struct exfat_dev));
        if (dev == NULL)
@@ -222,24 +211,6 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode)
                }
        }
 
-#ifdef USE_UBLIO
-       memset(&up, 0, sizeof(struct ublio_param));
-       up.up_blocksize = 256 * 1024;
-       up.up_items = 64;
-       up.up_grace = 32;
-       up.up_priv = &dev->fd;
-
-       dev->pos = 0;
-       dev->ufh = ublio_open(&up);
-       if (dev->ufh == NULL)
-       {
-               close(dev->fd);
-               free(dev);
-               exfat_error("failed to initialize ublio");
-               return NULL;
-       }
-#endif
-
        return dev;
 }
 
@@ -247,13 +218,6 @@ int exfat_close(struct exfat_dev* dev)
 {
        int rc = 0;
 
-#ifdef USE_UBLIO
-       if (ublio_close(dev->ufh) != 0)
-       {
-               exfat_error("failed to close ublio");
-               rc = -EIO;
-       }
-#endif
        if (close(dev->fd) != 0)
        {
                exfat_error("failed to close device: %s", strerror(errno));
@@ -267,13 +231,6 @@ int exfat_fsync(struct exfat_dev* dev)
 {
        int rc = 0;
 
-#ifdef USE_UBLIO
-       if (ublio_fsync(dev->ufh) != 0)
-       {
-               exfat_error("ublio fsync failed");
-               rc = -EIO;
-       }
-#endif
        if (fsync(dev->fd) != 0)
        {
                exfat_error("fsync failed: %s", strerror(errno));
@@ -294,56 +251,29 @@ off_t exfat_get_size(const struct exfat_dev* dev)
 
 off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence)
 {
-#ifdef USE_UBLIO
-       /* XXX SEEK_CUR will be handled incorrectly */
-       return dev->pos = lseek(dev->fd, offset, whence);
-#else
        return lseek(dev->fd, offset, whence);
-#endif
 }
 
 ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size)
 {
-#ifdef USE_UBLIO
-       ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos);
-       if (result >= 0)
-               dev->pos += size;
-       return result;
-#else
        return read(dev->fd, buffer, size);
-#endif
 }
 
 ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size)
 {
-#ifdef USE_UBLIO
-       ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos);
-       if (result >= 0)
-               dev->pos += size;
-       return result;
-#else
        return write(dev->fd, buffer, size);
-#endif
 }
 
 ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size,
                off_t offset)
 {
-#ifdef USE_UBLIO
-       return ublio_pread(dev->ufh, buffer, size, offset);
-#else
        return pread(dev->fd, buffer, size, offset);
-#endif
 }
 
 ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size,
                off_t offset)
 {
-#ifdef USE_UBLIO
-       return ublio_pwrite(dev->ufh, buffer, size, offset);
-#else
        return pwrite(dev->fd, buffer, size, offset);
-#endif
 }
 
 ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
index fd8982bff7430901114ea4bbea428240c8a822bb..e37b0d8d6f5dfe89dba9bf26bfdeedd1b1fb0066 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index d5bb3899bd152ed16b07ed725a1fa3090249f833..30b64108df127d8b112de346fa019cf1e51b36d7 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -61,10 +61,7 @@ struct exfat_node* exfat_readdir(struct exfat* ef, struct exfat_iterator* it)
 
 static int compare_char(struct exfat* ef, uint16_t a, uint16_t b)
 {
-       if (a >= ef->upcase_chars || b >= ef->upcase_chars)
-               return (int) a - (int) b;
-
-       return (int) le16_to_cpu(ef->upcase[a]) - (int) le16_to_cpu(ef->upcase[b]);
+       return (int) ef->upcase[a] - (int) ef->upcase[b];
 }
 
 static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b)
index 0d6ce9ead7514b08283d1e0fe8f58b6edcec3fdc..b1ce6543884d3155b4552863781e3c79c4c2bba2 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -376,5 +376,4 @@ void exfat_unmount(struct exfat* ef)
        ef->sb = NULL;
        free(ef->upcase);
        ef->upcase = NULL;
-       ef->upcase_chars = 0;
 }
index 4dd4dc6a4c6085a8a8f3622609951451aa7b2d87..fa04e257709eb8d5e949c74ab22d19c8738fd000 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -227,6 +227,26 @@ static bool check_node(const struct exfat_node* node, uint16_t actual_checksum,
        return true;
 }
 
+static void decompress_upcase(uint16_t* output, const le16_t* source,
+               size_t size)
+{
+       size_t si;
+       size_t oi;
+
+       for (oi = 0; oi < EXFAT_UPCASE_CHARS; oi++)
+               output[oi] = oi;
+
+       for (si = 0, oi = 0; si < size && oi < EXFAT_UPCASE_CHARS; si++)
+       {
+               uint16_t ch = le16_to_cpu(source[si]);
+
+               if (ch == 0xffff && si + 1 < size)      /* indicates a run */
+                       oi += le16_to_cpu(source[++si]);
+               else
+                       output[oi++] = ch;
+       }
+}
+
 /*
  * Reads one entry in directory at position pointed by iterator and fills
  * node structure.
@@ -247,6 +267,8 @@ static int readdir(struct exfat* ef, const struct exfat_node* parent,
        uint16_t reference_checksum = 0;
        uint16_t actual_checksum = 0;
        uint64_t valid_size = 0;
+       uint64_t upcase_size = 0;
+       le16_t* upcase_comp = NULL;
 
        *node = NULL;
 
@@ -371,33 +393,48 @@ static int readdir(struct exfat* ef, const struct exfat_node* parent,
                                                le32_to_cpu(upcase->start_cluster));
                                goto error;
                        }
-                       if (le64_to_cpu(upcase->size) == 0 ||
-                               le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
-                               le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
+                       upcase_size = le64_to_cpu(upcase->size);
+                       if (upcase_size == 0 ||
+                               upcase_size > EXFAT_UPCASE_CHARS * sizeof(uint16_t) ||
+                               upcase_size % sizeof(uint16_t) != 0)
                        {
                                exfat_error("bad upcase table size (%"PRIu64" bytes)",
-                                               le64_to_cpu(upcase->size));
+                                               upcase_size);
                                goto error;
                        }
-                       ef->upcase = malloc(le64_to_cpu(upcase->size));
-                       if (ef->upcase == NULL)
+                       upcase_comp = malloc(upcase_size);
+                       if (upcase_comp == NULL)
                        {
                                exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
-                                               le64_to_cpu(upcase->size));
+                                               upcase_size);
                                rc = -ENOMEM;
                                goto error;
                        }
-                       ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
 
-                       if (exfat_pread(ef->dev, ef->upcase, le64_to_cpu(upcase->size),
+                       /* read compressed upcase table */
+                       if (exfat_pread(ef->dev, upcase_comp, upcase_size,
                                        exfat_c2o(ef, le32_to_cpu(upcase->start_cluster))) < 0)
                        {
+                               free(upcase_comp);
                                exfat_error("failed to read upper case table "
                                                "(%"PRIu64" bytes starting at cluster %#x)",
-                                               le64_to_cpu(upcase->size),
+                                               upcase_size,
                                                le32_to_cpu(upcase->start_cluster));
                                goto error;
                        }
+
+                       /* decompress upcase table */
+                       ef->upcase = calloc(EXFAT_UPCASE_CHARS, sizeof(uint16_t));
+                       if (ef->upcase == NULL)
+                       {
+                               free(upcase_comp);
+                               exfat_error("failed to allocate decompressed upcase table");
+                               rc = -ENOMEM;
+                               goto error;
+                       }
+                       decompress_upcase(ef->upcase, upcase_comp,
+                                       upcase_size / sizeof(uint16_t));
+                       free(upcase_comp);
                        break;
 
                case EXFAT_ENTRY_BITMAP:
index 99fe507af3c429ec83768196ece1435a4727c564..4c5a0df59d42a9b3add8a6a888088a0e9a2aeae9 100644 (file)
@@ -4,7 +4,7 @@
        same kernel can use different libc implementations.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index 45c4aff65d605f7081c2d060b96bf0d786a4ea00..7d2becdae68871c756731e94471f71295a14d351 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index 6f14882e8a4694f98820d61d718c3fcceb653ce9..98ae52dbebc19445048025e39304ce719584581d 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
index 388f360d975af01cfd479a64e5220fbf0f18e53d..0d3b809218c37acd4c347bfd86614dd97997b49f 100644 (file)
@@ -3,7 +3,7 @@
        exFAT file system implementation library.
 
        Free exFAT implementation.
-       Copyright (C) 2010-2015  Andrew Nayenko
+       Copyright (C) 2010-2016  Andrew Nayenko
 
        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
@@ -124,8 +124,7 @@ le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name)
                uint16_t c = le16_to_cpu(name[i]);
 
                /* convert to upper case */
-               if (c < ef->upcase_chars)
-                       c = le16_to_cpu(ef->upcase[c]);
+               c = ef->upcase[c];
 
                hash = ((hash << 15) | (hash >> 1)) + (c & 0xff);
                hash = ((hash << 15) | (hash >> 1)) + (c >> 8);