From d8cd1f1d844a65544c33588e4c3283d3278493ee Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Fri, 28 Oct 2022 14:27:46 +0200 Subject: [PATCH 01/16] Add information regarding the new release --- debian/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/changelog b/debian/changelog index 975af37..0397c17 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ exfatprogs (1.2.0-1) UNRELEASED; urgency=medium * New upstream release. + + New utilitiy exfat2img to dump exFAT metadata. + + fsck.exfat is now able to repair certain corruptions. * Update Standards-Version to 4.6.1 - no changes required. * Rewrite the package short and long description. -- 2.39.2 From 4b71556f7e9a6894569b56e0cf8e239eb0e82833 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Fri, 28 Oct 2022 14:35:46 +0200 Subject: [PATCH 02/16] Newline at the end of debian/control --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index ce7deae..b0f02d4 100644 --- a/debian/control +++ b/debian/control @@ -23,4 +23,4 @@ Description: exFAT file system utilities - dump.exfat to show on-disk information of an exFAT filesystem The tools included in this package are the exfatprogs maintained by Samsung engineers, who provided Linux exFAT - support. \ No newline at end of file + support. -- 2.39.2 From a07179352304f9368e1f9c1f74c5cb3f3563cc24 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Fri, 28 Oct 2022 14:47:43 +0200 Subject: [PATCH 03/16] Another description update to add exfat2img --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index b0f02d4..4d41a5c 100644 --- a/debian/control +++ b/debian/control @@ -21,6 +21,7 @@ Description: exFAT file system utilities - fsck.exfat to check and repair an exFAT filesystem - tune.exfat to print and edit the volume label or serial - dump.exfat to show on-disk information of an exFAT filesystem + - exfat2img to dump exFAT metadata The tools included in this package are the exfatprogs - maintained by Samsung engineers, who provided Linux exFAT + maintained by Samsung and LG engineers, who provided Linux exFAT support. -- 2.39.2 From 5ee0e9dd44384f343be444806ded9e35b5cde8a7 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Fri, 28 Oct 2022 14:48:11 +0200 Subject: [PATCH 04/16] releasing package exfatprogs version 1.2.0-1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0397c17..4824b1f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -exfatprogs (1.2.0-1) UNRELEASED; urgency=medium +exfatprogs (1.2.0-1) unstable; urgency=medium * New upstream release. + New utilitiy exfat2img to dump exFAT metadata. @@ -6,7 +6,7 @@ exfatprogs (1.2.0-1) UNRELEASED; urgency=medium * Update Standards-Version to 4.6.1 - no changes required. * Rewrite the package short and long description. - -- Sven Hoexter Sat, 22 Jan 2022 20:11:07 +0100 + -- Sven Hoexter Fri, 28 Oct 2022 14:48:05 +0200 exfatprogs (1.1.3-1) unstable; urgency=medium -- 2.39.2 From 0a7a8b470671035ad0c2d8dc0d7714d06921273d Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 23 May 2023 13:59:09 +0200 Subject: [PATCH 05/16] New upstream version 1.2.1 --- Makefile.in | 2 +- NEWS | 7 ++++++ configure | 20 ++++++++--------- exfat2img/exfat2img.c | 2 +- fsck/fsck.c | 50 ++++++++++++++++++++++++++++++++++++++---- fsck/repair.c | 1 + fsck/repair.h | 2 +- include/exfat_dir.h | 1 + include/libexfat.h.rej | 9 -------- include/version.h | 2 +- include/version.h.rej | 9 -------- lib/exfat_dir.c | 7 +++--- lib/libexfat.c | 4 ++-- manpages/fsck.exfat.8 | 2 +- 14 files changed, 76 insertions(+), 42 deletions(-) delete mode 100644 include/libexfat.h.rej delete mode 100644 include/version.h.rej diff --git a/Makefile.in b/Makefile.in index 76de3b7..e1c0b64 100644 --- a/Makefile.in +++ b/Makefile.in @@ -198,7 +198,7 @@ am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing COPYING NEWS build-aux/compile \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/config.guess build-aux/config.sub \ build-aux/install-sh build-aux/ltmain.sh build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) diff --git a/NEWS b/NEWS index f845397..f371d62 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +exfatprogs 1.2.1 - released 2023-05-17 +====================================== + +CHANGES : + * fsck.exfat: Repair zero size directory. + * fsck.exfat: Four small clean-ups. + exfatprogs 1.2.0 - released 2022-10-28 ====================================== diff --git a/configure b/configure index 436be7a..c2938e9 100755 --- 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 exfatprogs 1.2.0. +# Generated by GNU Autoconf 2.69 for exfatprogs 1.2.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='exfatprogs' PACKAGE_TARNAME='exfatprogs' -PACKAGE_VERSION='1.2.0' -PACKAGE_STRING='exfatprogs 1.2.0' +PACKAGE_VERSION='1.2.1' +PACKAGE_STRING='exfatprogs 1.2.1' PACKAGE_BUGREPORT='linkinjeon@kernel.org' PACKAGE_URL='https://github.com/exfatprogs/exfatprogs' @@ -1325,7 +1325,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 exfatprogs 1.2.0 to adapt to many kinds of systems. +\`configure' configures exfatprogs 1.2.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1396,7 +1396,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of exfatprogs 1.2.0:";; + short | recursive ) echo "Configuration of exfatprogs 1.2.1:";; esac cat <<\_ACEOF @@ -1508,7 +1508,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -exfatprogs configure 1.2.0 +exfatprogs configure 1.2.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1786,7 +1786,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 exfatprogs $as_me 1.2.0, which was +It was created by exfatprogs $as_me 1.2.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2654,7 +2654,7 @@ fi # Define the identity of the package. PACKAGE='exfatprogs' - VERSION='1.2.0' + VERSION='1.2.1' cat >>confdefs.h <<_ACEOF @@ -13256,7 +13256,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 exfatprogs $as_me 1.2.0, which was +This file was extended by exfatprogs $as_me 1.2.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13323,7 +13323,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="\\ -exfatprogs config.status 1.2.0 +exfatprogs config.status 1.2.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/exfat2img/exfat2img.c b/exfat2img/exfat2img.c index 81e86d2..be1f0f3 100644 --- a/exfat2img/exfat2img.c +++ b/exfat2img/exfat2img.c @@ -754,7 +754,7 @@ static ssize_t read_stream(int fd, void *buf, size_t len) } else if (ret == 0) { return 0; } - buf += (size_t)ret; + buf = (char *)buf + (size_t)ret; read_len += (size_t)ret; } return read_len; diff --git a/fsck/fsck.c b/fsck/fsck.c index 219d723..cd9ee9a 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -103,21 +103,31 @@ static void usage(char *name) }) static int check_clus_chain(struct exfat_de_iter *de_iter, - struct exfat_inode *node) + struct exfat_inode *node) { struct exfat *exfat = de_iter->exfat; struct exfat_dentry *stream_de; - clus_t clus, prev, next; + clus_t clus, prev, next, new_clus; uint64_t count, max_count; + int err; clus = node->first_clus; prev = EXFAT_EOF_CLUSTER; count = 0; max_count = DIV_ROUND_UP(node->size, exfat->clus_size); - if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) + if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) { + /* locate a cluster for the empty dir if the dir starts with EXFAT_FREE_CLUSTER */ + if (node->attr & ATTR_SUBDIR) { + if (repair_file_ask(de_iter, node, + ER_DE_FIRST_CLUS, + "size %#" PRIx64 ", but the first cluster %#x", + node->size, node->first_clus)) + goto allocate_cluster; + return -EINVAL; + } return 0; - + } /* the first cluster is wrong */ if ((node->size == 0 && node->first_clus != EXFAT_FREE_CLUSTER) || (node->size > 0 && !exfat_heap_clus(exfat, node->first_clus))) { @@ -215,6 +225,38 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, } return 0; +allocate_cluster: + exfat_de_iter_get_dirty(de_iter, 1, &stream_de); + err = exfat_find_free_cluster(exfat, exfat->start_clu, &new_clus); + if (err) { + exfat->start_clu = EXFAT_FIRST_CLUSTER; + exfat_err("failed to find a free cluster\n"); + return -ENOSPC; + } + exfat->start_clu = new_clus; + + if (exfat_set_fat(exfat, new_clus, EXFAT_EOF_CLUSTER)) + return -EIO; + + /* zero out the new cluster */ + if (exfat_write(exfat->blk_dev->dev_fd, exfat->zero_cluster, + exfat->clus_size, exfat_c2o(exfat, new_clus)) != + (ssize_t)exfat->clus_size) { + exfat_err("failed to fill new cluster with zeroes\n"); + return -EIO; + } + + /* modify the number of cluster form 0 to 1 */ + count = 1; + stream_de->stream_start_clu = cpu_to_le32(new_clus); + stream_de->stream_size = cpu_to_le64(count * exfat->clus_size); + stream_de->stream_valid_size = cpu_to_le64(count * exfat->clus_size); + stream_de->dentry.stream.flags |= EXFAT_SF_CONTIGUOUS; + node->first_clus = new_clus; + node->size = count * exfat->clus_size; + node->is_contiguous = true; + exfat_bitmap_set(exfat->alloc_bitmap, new_clus); + return 1; truncate_file: node->size = count * exfat->clus_size; if (!exfat_heap_clus(exfat, prev)) diff --git a/fsck/repair.c b/fsck/repair.c index 92b1c3f..ab46f85 100644 --- a/fsck/repair.c +++ b/fsck/repair.c @@ -61,6 +61,7 @@ static struct exfat_repair_problem problems[] = { {ER_FILE_LARGER_SIZE, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, {ER_FILE_DUPLICATED_CLUS, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, {ER_FILE_ZERO_NOFAT, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}, + {ER_DE_FIRST_CLUS, ERF_PREEN_YES, ERP_FIX, 0, 0, 0} }; static struct exfat_repair_problem *find_problem(er_problem_code_t prcode) diff --git a/fsck/repair.h b/fsck/repair.h index dc3cc50..ea89747 100644 --- a/fsck/repair.h +++ b/fsck/repair.h @@ -23,7 +23,7 @@ #define ER_FILE_LARGER_SIZE 0x00002005 #define ER_FILE_DUPLICATED_CLUS 0x00002006 #define ER_FILE_ZERO_NOFAT 0x00002007 - +#define ER_DE_FIRST_CLUS 0x00002008 typedef unsigned int er_problem_code_t; struct exfat_fsck; diff --git a/include/exfat_dir.h b/include/exfat_dir.h index 3bc5b51..12e1546 100644 --- a/include/exfat_dir.h +++ b/include/exfat_dir.h @@ -75,6 +75,7 @@ int exfat_update_file_dentry_set(struct exfat *exfat, int exfat_build_file_dentry_set(struct exfat *exfat, const char *name, unsigned short attr, struct exfat_dentry **dentry_set, int *dentry_count); +int exfat_find_free_cluster(struct exfat *exfat, clus_t start, clus_t *new_clu); int exfat_add_dentry_set(struct exfat *exfat, struct exfat_dentry_loc *loc, struct exfat_dentry *dset, int dcount, bool need_next_loc); diff --git a/include/libexfat.h.rej b/include/libexfat.h.rej deleted file mode 100644 index 63c0a8b..0000000 --- a/include/libexfat.h.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/include/libexfat.h b/include/libexfat.h (rejected hunks) -@@ -35,6 +35,7 @@ - #define VOLUME_LABEL_BUFFER_SIZE (VOLUME_LABEL_MAX_LEN*MB_LEN_MAX+1) - - /* Upcase tabel macro */ -+#define EXFAT_UPCASE_TABLE_CHARS (0x10000) - #define EXFAT_UPCASE_TABLE_SIZE (5836) - - /* Flags for tune.exfat and exfatlabel */ diff --git a/include/version.h b/include/version.h index b0348d6..f0b250c 100644 --- a/include/version.h +++ b/include/version.h @@ -5,6 +5,6 @@ #ifndef _VERSION_H -#define EXFAT_PROGS_VERSION "1.2.0" +#define EXFAT_PROGS_VERSION "1.2.1" #endif /* !_VERSION_H */ diff --git a/include/version.h.rej b/include/version.h.rej deleted file mode 100644 index e7c2573..0000000 --- a/include/version.h.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/include/version.h b/include/version.h (rejected hunks) -@@ -6,6 +6,6 @@ - #ifndef _VERSION_H - - #define EXFAT_PROGS_VERSION "1.1.2" --#define WEBOS_EXFAT_PROGS_VERSION "webos-1.1.2-8" -+#define WEBOS_EXFAT_PROGS_VERSION "webos-1.1.2-9" - - #endif /* !_VERSION_H */ diff --git a/lib/exfat_dir.c b/lib/exfat_dir.c index 499b672..7c145f4 100644 --- a/lib/exfat_dir.c +++ b/lib/exfat_dir.c @@ -35,10 +35,11 @@ static ssize_t write_block(struct exfat_de_iter *iter, unsigned int block) unsigned int i; desc = &iter->buffer_desc[block & 0x01]; - device_offset = exfat_c2o(exfat, desc->p_clus) + desc->offset; for (i = 0; i < iter->read_size / iter->write_size; i++) { if (desc->dirty[i]) { + device_offset = exfat_c2o(exfat, desc->p_clus) + + desc->offset; if (exfat_write(exfat->blk_dev->dev_fd, desc->buffer + i * iter->write_size, iter->write_size, @@ -677,7 +678,7 @@ int exfat_update_file_dentry_set(struct exfat *exfat, return 0; } -static int find_free_cluster(struct exfat *exfat, +int exfat_find_free_cluster(struct exfat *exfat, clus_t start, clus_t *new_clu) { clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) + @@ -804,7 +805,7 @@ static int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode, if ((need_dset && !inode->dentry_set) || inode->is_contiguous) return -EINVAL; - err = find_free_cluster(exfat, exfat->start_clu, new_clu); + err = exfat_find_free_cluster(exfat, exfat->start_clu, new_clu); if (err) { exfat->start_clu = EXFAT_FIRST_CLUSTER; exfat_err("failed to find an free cluster\n"); diff --git a/lib/libexfat.c b/lib/libexfat.c index d7c1df1..4fd4ac6 100644 --- a/lib/libexfat.c +++ b/lib/libexfat.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "exfat_ondisk.h" #include "libexfat.h" @@ -748,8 +749,7 @@ off_t exfat_s2o(struct exfat *exfat, off_t sect) off_t exfat_c2o(struct exfat *exfat, unsigned int clus) { - if (clus < EXFAT_FIRST_CLUSTER) - return ~0L; + assert(clus >= EXFAT_FIRST_CLUSTER); return exfat_s2o(exfat, le32_to_cpu(exfat->bs->bsx.clu_offset) + ((off_t)(clus - EXFAT_FIRST_CLUSTER) << diff --git a/manpages/fsck.exfat.8 b/manpages/fsck.exfat.8 index 3b247d5..5faecf0 100644 --- a/manpages/fsck.exfat.8 +++ b/manpages/fsck.exfat.8 @@ -42,7 +42,7 @@ Files share the same cluster. Cluster chains for files except one are broken. .IP - Start cluster number is invalid. The cluster number and file size are changed to 0. .IP - -Checksum value of direcotry entry set is invalid. Directory entry set is deleted. +Checksum value of directory entry set is invalid. Directory entry set is deleted. .IP - Bad hash value of a file name. The hash value is changed properly. .IP - -- 2.39.2 From 3a6fd7518cc609ae77a32da611722235f7347e56 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 23 May 2023 14:01:26 +0200 Subject: [PATCH 06/16] New upstream release. + fsck.exfat improvements --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 4824b1f..5e8bf10 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +exfatprogs (1.2.1-1) UNRELEASED; urgency=medium + + * New upstream release. + + fsck.exfat improvements + + -- Sven Hoexter Tue, 23 May 2023 14:01:04 +0200 + exfatprogs (1.2.0-1) unstable; urgency=medium * New upstream release. -- 2.39.2 From d55449a5065eb32b4de032dc773b80bdf5f81ef7 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 23 May 2023 14:02:26 +0200 Subject: [PATCH 07/16] Update debian/watch to query the GitHub API for release information. --- debian/changelog | 1 + debian/watch | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 5e8bf10..f684c9e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ exfatprogs (1.2.1-1) UNRELEASED; urgency=medium * New upstream release. + fsck.exfat improvements + * Update debian/watch to query the GitHub API for release information. -- Sven Hoexter Tue, 23 May 2023 14:01:04 +0200 diff --git a/debian/watch b/debian/watch index 6076b3c..08fea01 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,5 @@ version=4 -opts=pgpsigurlmangle=s/$/.asc/ https://github.com/exfatprogs/exfatprogs/releases .*/exfatprogs-(\d\S*)\.tar\.xz \ No newline at end of file +opts="searchmode=plain,\ +filenamemangle=s%v?@ANY_VERSION@%@PACKAGE@-$1.tar.xz%" \ +https://api.github.com/repos/exfatprogs/exfatprogs/releases?per_page=50 \ +https://api.github.com/repos/[^/]+/[^/]+/tarball/v?@ANY_VERSION@ \ No newline at end of file -- 2.39.2 From 7e6ecccec986f0d4fd1e501b10d425195b9b47c9 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 23 May 2023 14:04:14 +0200 Subject: [PATCH 08/16] Update Standards-Version to 4.6.2 - no changes required. --- debian/changelog | 1 + debian/control | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index f684c9e..a06bf58 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ exfatprogs (1.2.1-1) UNRELEASED; urgency=medium * New upstream release. + fsck.exfat improvements * Update debian/watch to query the GitHub API for release information. + * Update Standards-Version to 4.6.2 - no changes required. -- Sven Hoexter Tue, 23 May 2023 14:01:04 +0200 diff --git a/debian/control b/debian/control index 4d41a5c..9e60239 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: otherosfs Priority: optional Maintainer: Sven Hoexter Build-Depends: debhelper-compat (= 13), pkg-config -Standards-Version: 4.6.1 +Standards-Version: 4.6.2 Rules-Requires-Root: no Homepage: https://github.com/exfatprogs/exfatprogs Vcs-Git: https://git.sven.stormbind.net/exfatprogs.git -- 2.39.2 From 276470e770d5f6587772c5cb3c92b0bee8473bed Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 23 May 2023 14:09:16 +0200 Subject: [PATCH 09/16] releasing package exfatprogs version 1.2.1-1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index a06bf58..61f21af 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,11 @@ -exfatprogs (1.2.1-1) UNRELEASED; urgency=medium +exfatprogs (1.2.1-1) experimental; urgency=medium * New upstream release. + fsck.exfat improvements * Update debian/watch to query the GitHub API for release information. * Update Standards-Version to 4.6.2 - no changes required. - -- Sven Hoexter Tue, 23 May 2023 14:01:04 +0200 + -- Sven Hoexter Tue, 23 May 2023 14:08:51 +0200 exfatprogs (1.2.0-1) unstable; urgency=medium -- 2.39.2 From 886d82128d1a4bb2e6c9d2630c3dbcfa553d99fb Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Wed, 14 Jun 2023 17:28:58 +0200 Subject: [PATCH 10/16] Remove conflicts on exfat-utils, that is now only available in oldstable. --- debian/changelog | 7 +++++++ debian/control | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 61f21af..179413b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +exfatprogs (1.2.1-2) UNRELEASED; urgency=medium + + * Remove conflicts on exfat-utils, that is now only available in + oldstable. + + -- Sven Hoexter Wed, 14 Jun 2023 17:26:21 +0200 + exfatprogs (1.2.1-1) experimental; urgency=medium * New upstream release. diff --git a/debian/control b/debian/control index 9e60239..59624d7 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,6 @@ Vcs-Browser: https://git.sven.stormbind.net/?p=sven/exfatprogs.git Package: exfatprogs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Conflicts: exfat-utils Description: exFAT file system utilities Tools to manage extended file allocation table filesystem. This package provides tools to create, check, dump and label -- 2.39.2 From 888f30735a8cca30b8d3f2a9e4de6211f0f9d821 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Wed, 14 Jun 2023 17:30:23 +0200 Subject: [PATCH 11/16] releasing package exfatprogs version 1.2.1-2 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 179413b..400b2ac 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -exfatprogs (1.2.1-2) UNRELEASED; urgency=medium +exfatprogs (1.2.1-2) unstable; urgency=medium * Remove conflicts on exfat-utils, that is now only available in oldstable. - -- Sven Hoexter Wed, 14 Jun 2023 17:26:21 +0200 + -- Sven Hoexter Wed, 14 Jun 2023 17:30:10 +0200 exfatprogs (1.2.1-1) experimental; urgency=medium -- 2.39.2 From 18d68918e6789c8e26d7a44751192f58787e3cd6 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Wed, 14 Jun 2023 17:41:52 +0200 Subject: [PATCH 12/16] Update debian/copyright. Drop year from my own copyright line. --- debian/changelog | 6 ++++++ debian/copyright | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 400b2ac..77ff19e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +exfatprogs (1.2.1-3) UNRELEASED; urgency=medium + + * Update debian/copyright. Drop year from my own copyright line. + + -- Sven Hoexter Wed, 14 Jun 2023 17:39:59 +0200 + exfatprogs (1.2.1-2) unstable; urgency=medium * Remove conflicts on exfat-utils, that is now only available in diff --git a/debian/copyright b/debian/copyright index 65cb319..1f9e1a9 100644 --- a/debian/copyright +++ b/debian/copyright @@ -34,7 +34,7 @@ License: The Debian packaging is: - Copyright (C) 2020-2021 Sven Hoexter + Copyright (C) Sven Hoexter and is licensed under the GPL version 2 or later, see "/usr/share/common-licenses/GPL-2". -- 2.39.2 From fa2bead8d3f2203fb7b22d801443109a52808490 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Sun, 29 Oct 2023 11:39:59 +0100 Subject: [PATCH 13/16] New upstream version 1.2.2 --- Makefile.in | 17 +-- NEWS | 17 +++ aclocal.m4 | 189 ++++++++++++++------------- build-aux/compile | 13 +- build-aux/depcomp | 8 +- build-aux/install-sh | 36 ++---- build-aux/ltmain.sh | 217 +++++++++---------------------- build-aux/missing | 16 +-- configure | 230 ++++++++++++++++----------------- dump/Makefile.in | 34 ++--- dump/dump.c | 1 + exfat2img/Makefile.in | 34 ++--- exfat2img/exfat2img.c | 2 +- fsck/Makefile.in | 38 ++---- fsck/fsck.c | 283 +++++++++++++---------------------------- fsck/fsck.h | 2 + fsck/repair.c | 139 +++++++++++++++++++- fsck/repair.h | 7 +- include/exfat_dir.h | 23 +++- include/exfat_ondisk.h | 9 ++ include/libexfat.h | 18 ++- include/version.h | 2 +- label/Makefile.in | 34 ++--- lib/Makefile.in | 57 +++------ lib/exfat_dir.c | 78 ++++++++---- lib/libexfat.c | 163 ++++++++++++++++++++++++ m4/libtool.m4 | 27 ++-- manpages/mkfs.exfat.8 | 20 +++ manpages/tune.exfat.8 | 12 ++ mkfs/Makefile.in | 38 ++---- mkfs/mkfs.c | 56 ++++++-- tune/Makefile.in | 34 ++--- tune/tune.c | 19 ++- 33 files changed, 1022 insertions(+), 851 deletions(-) diff --git a/Makefile.in b/Makefile.in index e1c0b64..01a27d7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -168,7 +168,7 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir distdir-am dist dist-all distcheck + cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, @@ -198,7 +198,7 @@ am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing COPYING NEWS build-aux/compile \ - build-aux/config.guess build-aux/config.sub \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ build-aux/install-sh build-aux/ltmain.sh build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -409,8 +409,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -593,10 +593,7 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ diff --git a/NEWS b/NEWS index f371d62..055343a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,20 @@ +exfatprogs 1.2.2 - released 2023-10-26 +====================================== + +CHANGES : + * exfat2img: Allow dumps for read-only devices. + * fsck.exfat: Revert Repairing zero size directory. + +NEW FEATURES : + * fsck.exfat: Repair duplicated filename. + * mkfs.exfat: Add the option "q" to print only error messages. + * mkfs.exfat: Add the option "U" to set volume GUID. + * tune.exfat: Add the option "U" / "-u" to set or print volume GUID. + +BUG FIXES: + * fsck.exfat: Fix some out-of-bounds memory accesses. + * fsck.exfat: Change not to delete volume GUID directory entry. + exfatprogs 1.2.1 - released 2023-05-17 ====================================== diff --git a/aclocal.m4 b/aclocal.m4 index 9f28080..3610979 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.16' +[am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.1], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.1])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,12 +332,13 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. + # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -345,41 +346,49 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - AS_CASE([$CONFIG_FILES], - [*\'*], [eval set x "$CONFIG_FILES"], - [*], [set x $CONFIG_FILES]) + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf + for mf do # Strip MF so we end up with the name of the file. - am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`AS_DIRNAME(["$am_mf"])` - am_filepart=`AS_BASENAME(["$am_mf"])` - AM_RUN_LOG([cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles]) || am_rc=$? + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done - if test $am_rc -ne 0; then - AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking).]) - fi - AS_UNSET([am_dirpart]) - AS_UNSET([am_filepart]) - AS_UNSET([am_mf]) - AS_UNSET([am_rc]) - rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -388,17 +397,18 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking is enabled. -# This creates each '.Po' and '.Plo' makefile fragment that we'll need in -# order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -485,8 +495,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -553,7 +563,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -595,7 +605,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -616,7 +626,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -637,7 +647,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -645,42 +655,49 @@ AC_SUBST([am__leading_dot])]) # AM_MAKE_INCLUDE() # ----------------- -# Check whether make has an 'include' directive that can support all -# the idioms we need for our automatic dependency tracking code. +# Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], -[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) -cat > confinc.mk << 'END' +[am_make=${MAKE-make} +cat > confinc << 'END' am__doit: - @echo this is the am__doit target >confinc.out + @echo this is the am__doit target .PHONY: am__doit END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) - AS_CASE([$?:`cat confinc.out 2>/dev/null`], - ['0:this is the am__doit target'], - [AS_CASE([$s], - [BSD], [am__include='.include' am__quote='"'], - [am__include='include' am__quote=''])]) - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -AC_MSG_RESULT([${_am_result}]) -AC_SUBST([am__include])]) -AC_SUBST([am__quote])]) +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -719,7 +736,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -748,7 +765,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -795,7 +812,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -814,7 +831,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -895,7 +912,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -955,7 +972,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -983,7 +1000,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1002,7 +1019,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/build-aux/compile b/build-aux/compile index 99e5052..a85b723 100755 --- a/build-aux/compile +++ b/build-aux/compile @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2018-03-07.03; # UTC +scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2018-03-07.03; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -255,8 +255,7 @@ EOF echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ - icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -340,9 +339,9 @@ exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/build-aux/depcomp b/build-aux/depcomp index 65cbf70..b39f98f 100755 --- a/build-aux/depcomp +++ b/build-aux/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2018-03-07.03; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # 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 @@ -16,7 +16,7 @@ scriptversion=2018-03-07.03; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,7 +783,7 @@ exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff --git a/build-aux/install-sh b/build-aux/install-sh index 8175c64..59990a1 100755 --- a/build-aux/install-sh +++ b/build-aux/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2018-03-11.20; # UTC +scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -271,18 +271,15 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename. + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dstbase=`basename "$src"` - case $dst in - */) dst=$dst$dstbase;; - *) dst=$dst/$dstbase;; - esac + dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` @@ -291,11 +288,6 @@ do fi fi - case $dstdir in - */) dstdirslash=$dstdir;; - *) dstdirslash=$dstdir/;; - esac - obsolete_mkdir_used=false if test $dstdir_status != 0; then @@ -332,16 +324,14 @@ do # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) - # Note that $RANDOM variable is not portable (e.g. dash); Use it - # here however when possible just to lower collision chance. + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p' feature. + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 @@ -444,8 +434,8 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=${dstdirslash}_inst.$$_ - rmtmp=${dstdirslash}_rm.$$_ + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -510,9 +500,9 @@ do done # Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh index 0cb7f90..a736cf9 100644 --- a/build-aux/ltmain.sh +++ b/build-aux/ltmain.sh @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-14" +VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 @@ -387,7 +387,7 @@ EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # -# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: @@ -1370,7 +1370,7 @@ func_lt_ver () #! /bin/sh # Set a version string for this script. -scriptversion=2015-10-07.11; # UTC +scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 @@ -1530,8 +1530,6 @@ func_run_hooks () { $debug_cmd - _G_rc_run_hooks=false - case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; @@ -1540,16 +1538,16 @@ func_run_hooks () eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - if eval $_G_hook '"$@"'; then - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift - _G_rc_run_hooks=: - fi + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift done - $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result } @@ -1559,16 +1557,10 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, you may remove/edit -# any options that you action, and then pass back the remaining unprocessed +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for -# 'eval'. In this case you also must return $EXIT_SUCCESS to let the -# hook's caller know that it should pay attention to -# '_result'. Returning $EXIT_FAILURE signalizes that -# arguments are left untouched by the hook and therefore caller will ignore the -# result variable. -# -# Like this: +# 'eval'. Like this: # # my_options_prep () # { @@ -1578,11 +1570,9 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# # No change in '$@' (ignored completely by this hook). There is -# # no need to do the equivalent (but slower) action: -# # func_quote_for_eval ${1+"$@"} -# # my_options_prep_result=$func_quote_for_eval_result -# false +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # @@ -1591,37 +1581,25 @@ func_run_hooks () # { # $debug_cmd # -# args_changed=false -# # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in -# --silent|-s) opt_silent=: -# args_changed=: -# ;; +# --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift -# args_changed=: # ;; -# *) # Make sure the first unrecognised option "$_G_opt" -# # is added back to "$@", we could need that later -# # if $args_changed is true. -# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # -# if $args_changed; then -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result -# fi -# -# $args_changed +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # @@ -1633,32 +1611,16 @@ func_run_hooks () # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # -# false +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # -# You'll also need to manually amend $usage_message to reflect the extra +# You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. -# func_options_finish [ARG]... -# ---------------------------- -# Finishing the option parse loop (call 'func_options' hooks ATM). -func_options_finish () -{ - $debug_cmd - - _G_func_options_finish_exit=false - if func_run_hooks func_options ${1+"$@"}; then - func_options_finish_result=$func_run_hooks_result - _G_func_options_finish_exit=: - fi - - $_G_func_options_finish_exit -} - - # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the @@ -1668,28 +1630,17 @@ func_options () { $debug_cmd - _G_rc_options=false + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} - for my_func in options_prep parse_options validate_options options_finish - do - if eval func_$my_func '${1+"$@"}'; then - eval _G_res_var='$'"func_${my_func}_result" - eval set dummy "$_G_res_var" ; shift - _G_rc_options=: - fi - done - - # Save modified positional parameters for caller. As a top-level - # options-parser function we always need to set the 'func_options_result' - # variable (regardless the $_G_rc_options value). - if $_G_rc_options; then - func_options_result=$_G_res_var - else - func_quote_for_eval ${1+"$@"} - func_options_result=$func_quote_for_eval_result - fi + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} - $_G_rc_options + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result } @@ -1698,9 +1649,9 @@ func_options () # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and -# needs to propagate that back to rest of this script, then the complete +# needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before -# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +# returning. func_hookable func_options_prep func_options_prep () { @@ -1710,14 +1661,10 @@ func_options_prep () opt_verbose=false opt_warning_types= - _G_rc_options_prep=false - if func_run_hooks func_options_prep ${1+"$@"}; then - _G_rc_options_prep=: - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result - fi + func_run_hooks func_options_prep ${1+"$@"} - $_G_rc_options_prep + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result } @@ -1731,20 +1678,18 @@ func_parse_options () func_parse_options_result= - _G_rc_parse_options=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. - if func_run_hooks func_parse_options ${1+"$@"}; then - eval set dummy "$func_run_hooks_result"; shift - _G_rc_parse_options=: - fi + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break - _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -1759,10 +1704,7 @@ func_parse_options () ;; --warnings|--warning|-W) - if test $# = 0 && func_missing_arg $_G_opt; then - _G_rc_parse_options=: - break - fi + test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above @@ -1815,25 +1757,15 @@ func_parse_options () shift ;; - --) _G_rc_parse_options=: ; break ;; + --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift - _G_match_parse_options=false - break - ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac - - $_G_match_parse_options && _G_rc_parse_options=: done - - if $_G_rc_parse_options; then - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result - fi - - $_G_rc_parse_options + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result } @@ -1846,21 +1778,16 @@ func_validate_options () { $debug_cmd - _G_rc_validate_options=false - # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - if func_run_hooks func_validate_options ${1+"$@"}; then - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result - _G_rc_validate_options=: - fi + func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - $_G_rc_validate_options + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result } @@ -2141,7 +2068,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname $scriptversion Debian-2.4.6-14 + version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` @@ -2343,8 +2270,6 @@ libtool_options_prep () nonopt= preserve_args= - _G_rc_lt_options_prep=: - # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2368,18 +2293,11 @@ libtool_options_prep () uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; - *) - _G_rc_lt_options_prep=false - ;; esac - if $_G_rc_lt_options_prep; then - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result - fi - - $_G_rc_lt_options_prep + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep @@ -2391,12 +2309,9 @@ libtool_parse_options () { $debug_cmd - _G_rc_lt_parse_options=false - # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do - _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -2471,22 +2386,15 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"} ; shift - _G_match_lt_parse_options=false - break - ;; + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac - $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done - if $_G_rc_lt_parse_options; then - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result - fi - $_G_rc_lt_parse_options + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options @@ -7367,13 +7275,10 @@ func_mode_link () # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer - # -fuse-ld=* Linker select flags for GCC - # -static-* direct GCC to link specific libraries statically - # -fcilkplus Cilk Plus language extension features for C/C++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ - -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) + -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" diff --git a/build-aux/missing b/build-aux/missing index 625aeb1..f62bbae 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2018-03-07.03; # UTC +scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2018-03-07.03; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ else exit $st fi -perl_URL=https://www.perl.org/ -flex_URL=https://github.com/westes/flex -gnu_software_URL=https://www.gnu.org/software +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software program_details () { @@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \ exit $st # Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) +# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" +# time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: diff --git a/configure b/configure index c2938e9..662b6b8 100755 --- 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 exfatprogs 1.2.1. +# Generated by GNU Autoconf 2.69 for exfatprogs 1.2.2. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='exfatprogs' PACKAGE_TARNAME='exfatprogs' -PACKAGE_VERSION='1.2.1' -PACKAGE_STRING='exfatprogs 1.2.1' +PACKAGE_VERSION='1.2.2' +PACKAGE_STRING='exfatprogs 1.2.2' PACKAGE_BUGREPORT='linkinjeon@kernel.org' PACKAGE_URL='https://github.com/exfatprogs/exfatprogs' @@ -674,6 +674,7 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE +am__quote am__include DEPDIR OBJEXT @@ -748,8 +749,7 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL -am__quote' +SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -1325,7 +1325,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 exfatprogs 1.2.1 to adapt to many kinds of systems. +\`configure' configures exfatprogs 1.2.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1396,7 +1396,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of exfatprogs 1.2.1:";; + short | recursive ) echo "Configuration of exfatprogs 1.2.2:";; esac cat <<\_ACEOF @@ -1508,7 +1508,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -exfatprogs configure 1.2.1 +exfatprogs configure 1.2.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1786,7 +1786,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 exfatprogs $as_me 1.2.1, which was +It was created by exfatprogs $as_me 1.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2168,7 +2168,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -am__api_version='1.16' +am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2654,7 +2654,7 @@ fi # Define the identity of the package. PACKAGE='exfatprogs' - VERSION='1.2.1' + VERSION='1.2.2' cat >>confdefs.h <<_ACEOF @@ -2684,8 +2684,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2821,7 +2821,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3690,45 +3690,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 -$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } -cat > confinc.mk << 'END' + +am_make=${MAKE-make} +cat > confinc << 'END' am__doit: - @echo this is the am__doit target >confinc.out + @echo this is the am__doit target .PHONY: am__doit END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 - (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - case $?:`cat confinc.out 2>/dev/null` in #( - '0:this is the am__doit target') : - case $s in #( - BSD) : - am__include='.include' am__quote='"' ;; #( - *) : - am__include='include' am__quote='' ;; -esac ;; #( - *) : - ;; +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; esac - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 -$as_echo "${_am_result}" >&6; } +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -5881,7 +5881,7 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cr} +: ${AR_FLAGS=cru} @@ -6382,8 +6382,11 @@ _LT_EOF test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 - if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -7602,8 +7605,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cr libconftest.a conftest.o" >&5 - $AR cr libconftest.a conftest.o 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF @@ -8732,12 +8735,6 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; - # flang / f18. f95 an alias for gfortran or flang on Debian - flang* | f18* | f95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -13256,7 +13253,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 exfatprogs $as_me 1.2.1, which was +This file was extended by exfatprogs $as_me 1.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13323,7 +13320,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="\\ -exfatprogs config.status 1.2.1 +exfatprogs config.status 1.2.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -13442,7 +13439,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -14345,35 +14342,29 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - case $CONFIG_FILES in #( - *\'*) : - eval set x "$CONFIG_FILES" ;; #( - *) : - set x $CONFIG_FILES ;; #( - *) : - ;; -esac + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf + for mf do # Strip MF so we end up with the name of the file. - am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`$as_dirname -- "$am_mf" || -$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$am_mf" : 'X\(//\)[^/]' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$am_mf" | + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -14391,48 +14382,53 @@ $as_echo X"$am_mf" | q } s/.*/./; q'` - am_filepart=`$as_basename -- "$am_mf" || -$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$am_mf" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } - /^X\/\(\/\/\)$/{ + /^X\(\/\/\)[^/].*/{ s//\1/ q } - /^X\/\(\/\).*/{ + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` - { echo "$as_me:$LINENO: cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles" >&5 - (cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } || am_rc=$? + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done - if test $am_rc -ne 0; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking). -See \`config.log' for more details" "$LINENO" 5; } - fi - { am_dirpart=; unset am_dirpart;} - { am_filepart=; unset am_filepart;} - { am_mf=; unset am_mf;} - { am_rc=; unset am_rc;} - rm -f conftest-deps.mk } ;; "libtool":C) diff --git a/dump/Makefile.in b/dump/Makefile.in index 33cf63c..e79c123 100644 --- a/dump/Makefile.in +++ b/dump/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/dump.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,13 +386,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -477,10 +470,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -553,7 +543,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/dump.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -599,7 +589,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/dump.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -620,9 +610,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/dump/dump.c b/dump/dump.c index 3d77bb9..8c96376 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -223,6 +223,7 @@ int main(int argc, char *argv[]) bool version_only = false; init_user_input(&ui); + ui.writeable = false; if (!setlocale(LC_CTYPE, "")) exfat_err("failed to init locale/codeset\n"); diff --git a/exfat2img/Makefile.in b/exfat2img/Makefile.in index 9590182..04ba633 100644 --- a/exfat2img/Makefile.in +++ b/exfat2img/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/exfat2img.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,13 +386,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat2img.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat2img.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -477,10 +470,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -553,7 +543,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/exfat2img.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -599,7 +589,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/exfat2img.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -620,9 +610,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/exfat2img/exfat2img.c b/exfat2img/exfat2img.c index be1f0f3..3f83588 100644 --- a/exfat2img/exfat2img.c +++ b/exfat2img/exfat2img.c @@ -319,7 +319,7 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, if (!node) return -ENOMEM; - for (i = 2; i <= file_de->file_num_ext; i++) { + for (i = 2; i <= MIN(file_de->file_num_ext, 1 + MAX_NAME_DENTRIES); i++) { ret = exfat_de_iter_get(iter, i, &dentry); if (ret || dentry->type != EXFAT_NAME) break; diff --git a/fsck/Makefile.in b/fsck/Makefile.in index 1e32a5d..56fa169 100644 --- a/fsck/Makefile.in +++ b/fsck/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/fsck.Po ./$(DEPDIR)/repair.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,14 +386,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -478,10 +471,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -554,8 +544,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/fsck.Po - -rm -f ./$(DEPDIR)/repair.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -601,8 +590,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/fsck.Po - -rm -f ./$(DEPDIR)/repair.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -623,9 +611,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/fsck/fsck.c b/fsck/fsck.c index cd9ee9a..77272aa 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -103,31 +103,21 @@ static void usage(char *name) }) static int check_clus_chain(struct exfat_de_iter *de_iter, - struct exfat_inode *node) + struct exfat_inode *node) { struct exfat *exfat = de_iter->exfat; struct exfat_dentry *stream_de; - clus_t clus, prev, next, new_clus; + clus_t clus, prev, next; uint64_t count, max_count; - int err; clus = node->first_clus; prev = EXFAT_EOF_CLUSTER; count = 0; max_count = DIV_ROUND_UP(node->size, exfat->clus_size); - if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) { - /* locate a cluster for the empty dir if the dir starts with EXFAT_FREE_CLUSTER */ - if (node->attr & ATTR_SUBDIR) { - if (repair_file_ask(de_iter, node, - ER_DE_FIRST_CLUS, - "size %#" PRIx64 ", but the first cluster %#x", - node->size, node->first_clus)) - goto allocate_cluster; - return -EINVAL; - } + if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) return 0; - } + /* the first cluster is wrong */ if ((node->size == 0 && node->first_clus != EXFAT_FREE_CLUSTER) || (node->size > 0 && !exfat_heap_clus(exfat, node->first_clus))) { @@ -225,38 +215,6 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, } return 0; -allocate_cluster: - exfat_de_iter_get_dirty(de_iter, 1, &stream_de); - err = exfat_find_free_cluster(exfat, exfat->start_clu, &new_clus); - if (err) { - exfat->start_clu = EXFAT_FIRST_CLUSTER; - exfat_err("failed to find a free cluster\n"); - return -ENOSPC; - } - exfat->start_clu = new_clus; - - if (exfat_set_fat(exfat, new_clus, EXFAT_EOF_CLUSTER)) - return -EIO; - - /* zero out the new cluster */ - if (exfat_write(exfat->blk_dev->dev_fd, exfat->zero_cluster, - exfat->clus_size, exfat_c2o(exfat, new_clus)) != - (ssize_t)exfat->clus_size) { - exfat_err("failed to fill new cluster with zeroes\n"); - return -EIO; - } - - /* modify the number of cluster form 0 to 1 */ - count = 1; - stream_de->stream_start_clu = cpu_to_le32(new_clus); - stream_de->stream_size = cpu_to_le64(count * exfat->clus_size); - stream_de->stream_valid_size = cpu_to_le64(count * exfat->clus_size); - stream_de->dentry.stream.flags |= EXFAT_SF_CONTIGUOUS; - node->first_clus = new_clus; - node->size = count * exfat->clus_size; - node->is_contiguous = true; - exfat_bitmap_set(exfat->alloc_bitmap, new_clus); - return 1; truncate_file: node->size = count * exfat->clus_size; if (!exfat_heap_clus(exfat, prev)) @@ -677,6 +635,35 @@ static int check_inode(struct exfat_de_iter *iter, struct exfat_inode *node) return valid ? ret : -EINVAL; } +static int handle_duplicated_filename(struct exfat_de_iter *iter, + struct exfat_inode *inode) +{ + int ret; + struct exfat_lookup_filter filter; + char filename[PATH_MAX + 1] = {0}; + + ret = exfat_lookup_file_by_utf16name(iter->exfat, iter->parent, + inode->name, &filter); + if (ret) + return ret; + + free(filter.out.dentry_set); + + /* Hash is same, but filename is not same */ + if (exfat_de_iter_device_offset(iter) == filter.out.dev_offset) + return 0; + + ret = exfat_utf16_dec(inode->name, NAME_BUFFER_SIZE, filename, + PATH_MAX); + if (ret < 0) { + exfat_err("failed to decode filename\n"); + return ret; + } + + return exfat_repair_rename_ask(&exfat_fsck, iter, filename, + ER_DE_DUPLICATED_NAME, "filename is duplicated"); +} + static int check_name_dentry_set(struct exfat_de_iter *iter, struct exfat_inode *inode) { @@ -707,77 +694,16 @@ static int check_name_dentry_set(struct exfat_de_iter *iter, return -EINVAL; } } - return 0; -} -static int check_bad_char(char w) -{ - return (w < 0x0020) || (w == '*') || (w == '?') || (w == '<') || - (w == '>') || (w == '|') || (w == '"') || (w == ':') || - (w == '/') || (w == '\\'); -} + if (BITMAP_GET(iter->name_hash_bitmap, hash)) { + int ret = handle_duplicated_filename(iter, inode); -static char *get_rename_from_user(struct exfat_de_iter *iter) -{ - char *rename = malloc(ENTRY_NAME_MAX + 2); - - if (!rename) - return NULL; - -retry: - /* +2 means LF(Line Feed) and NULL terminator */ - memset(rename, 0x1, ENTRY_NAME_MAX + 2); - printf("New name: "); - if (fgets(rename, ENTRY_NAME_MAX + 2, stdin)) { - int i, len, err; - struct exfat_lookup_filter filter; - - len = strlen(rename); - /* Remove LF in filename */ - rename[len - 1] = '\0'; - for (i = 0; i < len - 1; i++) { - if (check_bad_char(rename[i])) { - printf("filename contain invalid character(%c)\n", rename[i]); - goto retry; - } - } - - exfat_de_iter_flush(iter); - err = exfat_lookup_file(iter->exfat, iter->parent, rename, &filter); - if (!err) { - printf("file(%s) already exists, retry to insert name\n", rename); - goto retry; - } - } - - return rename; -} - -static char *generate_rename(struct exfat_de_iter *iter) -{ - char *rename; - - if (iter->dot_name_num > DOT_NAME_NUM_MAX) - return NULL; - - rename = malloc(ENTRY_NAME_MAX + 1); - if (!rename) - return NULL; - - while (1) { - struct exfat_lookup_filter filter; - int err; - - snprintf(rename, ENTRY_NAME_MAX + 1, "FILE%07d.CHK", - iter->dot_name_num++); - err = exfat_lookup_file(iter->exfat, iter->parent, rename, - &filter); - if (!err) - continue; - break; - } + if (ret) + return ret; + } else + BITMAP_SET(iter->name_hash_bitmap, hash); - return rename; + return 0; } const __le16 MSDOS_DOT[ENTRY_NAME_MAX] = {cpu_to_le16(46), 0, }; @@ -788,8 +714,6 @@ static int handle_dot_dotdot_filename(struct exfat_de_iter *iter, int strm_name_len) { char *filename; - char error_msg[150]; - int num; if (!memcmp(dentry->name_unicode, MSDOS_DOT, strm_name_len * 2)) filename = "."; @@ -799,56 +723,8 @@ static int handle_dot_dotdot_filename(struct exfat_de_iter *iter, else return 0; - sprintf(error_msg, "ERROR: '%s' filename is not allowed.\n" - " [1] Insert the name you want to rename.\n" - " [2] Automatically renames filename.\n" - " [3] Bypass this check(No repair)\n", filename); -ask_again: - num = exfat_repair_ask(&exfat_fsck, ER_DE_DOT_NAME, - error_msg); - if (num) { - __le16 utf16_name[ENTRY_NAME_MAX]; - char *rename = NULL; - __u16 hash; - struct exfat_dentry *stream_de; - int name_len, ret; - - switch (num) { - case 1: - rename = get_rename_from_user(iter); - break; - case 2: - rename = generate_rename(iter); - break; - case 3: - break; - default: - exfat_info("select 1 or 2 number instead of %d\n", num); - goto ask_again; - } - - if (!rename) - return -EINVAL; - - exfat_info("%s filename is renamed to %s\n", filename, rename); - - exfat_de_iter_get_dirty(iter, 2, &dentry); - - memset(utf16_name, 0, sizeof(utf16_name)); - ret = exfat_utf16_enc(rename, utf16_name, sizeof(utf16_name)); - free(rename); - if (ret < 0) - return ret; - - memcpy(dentry->name_unicode, utf16_name, ENTRY_NAME_MAX * 2); - name_len = exfat_utf16_len(utf16_name, ENTRY_NAME_MAX * 2); - hash = exfat_calc_name_hash(iter->exfat, utf16_name, (int)name_len); - exfat_de_iter_get_dirty(iter, 1, &stream_de); - stream_de->stream_name_len = (__u8)name_len; - stream_de->stream_name_hash = cpu_to_le16(hash); - } - - return 0; + return exfat_repair_rename_ask(&exfat_fsck, iter, filename, + ER_DE_DOT_NAME, "filename is not allowed"); } static int read_file_dentry_set(struct exfat_de_iter *iter, @@ -898,7 +774,7 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, if (!node) return -ENOMEM; - for (i = 2; i <= file_de->file_num_ext; i++) { + for (i = 2; i <= MIN(file_de->file_num_ext, 1 + MAX_NAME_DENTRIES); i++) { ret = exfat_de_iter_get(iter, i, &dentry); if (ret || dentry->type != EXFAT_NAME) { if (i > 2 && repair_file_ask(iter, NULL, ER_DE_NAME, @@ -1004,6 +880,7 @@ static int read_bitmap(struct exfat *exfat) { struct exfat_lookup_filter filter = { .in.type = EXFAT_BITMAP, + .in.dentry_count = 0, .in.filter = NULL, .in.param = NULL, }; @@ -1078,6 +955,7 @@ static int read_upcase_table(struct exfat *exfat) { struct exfat_lookup_filter filter = { .in.type = EXFAT_UPCASE, + .in.dentry_count = 0, .in.filter = NULL, .in.param = NULL, }; @@ -1171,6 +1049,10 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir) else if (ret) return ret; + de_iter->name_hash_bitmap = fsck->name_hash_bitmap; + memset(fsck->name_hash_bitmap, 0, + EXFAT_BITMAP_SIZE(EXFAT_MAX_HASH_COUNT)); + while (1) { ret = exfat_de_iter_get(de_iter, 0, &dentry); if (ret == EOF) { @@ -1211,6 +1093,7 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir) case EXFAT_VOLUME: case EXFAT_BITMAP: case EXFAT_UPCASE: + case EXFAT_GUID: if (dir == exfat->root) break; /* fallthrough */ @@ -1300,6 +1183,12 @@ static int exfat_filesystem_check(struct exfat_fsck *fsck) return -ENOENT; } + fsck->name_hash_bitmap = malloc(EXFAT_BITMAP_SIZE(EXFAT_MAX_HASH_COUNT)); + if (!fsck->name_hash_bitmap) { + exfat_err("failed to allocate name hash bitmap\n"); + return -ENOMEM; + } + list_add(&exfat->root->list, &exfat->dir_list); while (!list_empty(&exfat->dir_list)) { @@ -1328,6 +1217,7 @@ static int exfat_filesystem_check(struct exfat_fsck *fsck) } out: exfat_free_dir_list(exfat); + free(fsck->name_hash_bitmap); return ret; } @@ -1427,9 +1317,40 @@ static int rescue_orphan_clusters(struct exfat_fsck *fsck) struct exfat_dentry_loc loc; struct exfat_lookup_filter lf = { .in.type = EXFAT_INVAL, + .in.dentry_count = 0, .in.filter = NULL, }; + clu_count = le32_to_cpu(exfat->bs->bsx.clu_count); + + /* find clusters which are not marked as free, but not allocated to + * any files. + */ + disk_b = (bitmap_t *)exfat->disk_bitmap; + alloc_b = (bitmap_t *)exfat->alloc_bitmap; + ohead_b = (bitmap_t *)exfat->ohead_bitmap; + for (i = 0; i < EXFAT_BITMAP_SIZE(clu_count) / sizeof(bitmap_t); i++) + ohead_b[i] = disk_b[i] & ~alloc_b[i]; + + /* no orphan clusters */ + if (exfat_bitmap_find_one(exfat, exfat->ohead_bitmap, + EXFAT_FIRST_CLUSTER, &s_clu)) + return 0; + + err = exfat_create_file(exfat_fsck.exfat, + exfat_fsck.exfat->root, + "LOST+FOUND", + ATTR_SUBDIR); + if (err) { + exfat_err("failed to create LOST+FOUND directory\n"); + return err; + } + + if (fsync(exfat_fsck.exfat->blk_dev->dev_fd) != 0) { + exfat_err("failed to sync()\n"); + return -EIO; + } + err = read_lostfound(exfat, &lostfound); if (err) { exfat_err("failed to find LOST+FOUND\n"); @@ -1455,17 +1376,6 @@ static int rescue_orphan_clusters(struct exfat_fsck *fsck) } dset[1].dentry.stream.flags |= EXFAT_SF_CONTIGUOUS; - clu_count = le32_to_cpu(exfat->bs->bsx.clu_count); - - /* find clusters which are not marked as free, but not allocated to - * any files. - */ - disk_b = (bitmap_t *)exfat->disk_bitmap; - alloc_b = (bitmap_t *)exfat->alloc_bitmap; - ohead_b = (bitmap_t *)exfat->ohead_bitmap; - for (i = 0; i < EXFAT_BITMAP_SIZE(clu_count) / sizeof(bitmap_t); i++) - ohead_b[i] = disk_b[i] & ~alloc_b[i]; - /* create temporary files and allocate contiguous orphan clusters * to each file. */ @@ -1657,23 +1567,6 @@ int main(int argc, char * const argv[]) goto out; } - if (exfat_fsck.options & FSCK_OPTS_RESCUE_CLUS) { - ret = exfat_create_file(exfat_fsck.exfat, - exfat_fsck.exfat->root, - "LOST+FOUND", - ATTR_SUBDIR); - if (ret) { - exfat_err("failed to create lost+found directory\n"); - goto out; - } - - if (fsync(exfat_fsck.exfat->blk_dev->dev_fd) != 0) { - ret = -EIO; - exfat_err("failed to sync()\n"); - goto out; - } - } - exfat_debug("verifying directory entries...\n"); ret = exfat_filesystem_check(&exfat_fsck); if (ret) diff --git a/fsck/fsck.h b/fsck/fsck.h index 53003f6..ee0cb30 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -28,6 +28,8 @@ struct exfat_fsck { enum fsck_ui_options options; bool dirty:1; bool dirty_fat:1; + + char *name_hash_bitmap; }; off_t exfat_c2o(struct exfat *exfat, unsigned int clus); diff --git a/fsck/repair.c b/fsck/repair.c index ab46f85..f983ee1 100644 --- a/fsck/repair.c +++ b/fsck/repair.c @@ -6,12 +6,12 @@ #include #include #include +#include #include "exfat_ondisk.h" #include "libexfat.h" #include "repair.h" #include "exfat_fs.h" -#include "exfat_dir.h" #include "fsck.h" struct exfat_repair_problem { @@ -54,6 +54,7 @@ static struct exfat_repair_problem problems[] = { {ER_DE_NAME_HASH, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}, {ER_DE_NAME_LEN, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}, {ER_DE_DOT_NAME, ERF_PREEN_YES, ERP_RENAME, 2, 3, 4}, + {ER_DE_DUPLICATED_NAME, ERF_PREEN_YES, ERP_RENAME, 2, 3, 4}, {ER_FILE_VALID_SIZE, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}, {ER_FILE_INVALID_CLUS, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, {ER_FILE_FIRST_CLUS, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, @@ -61,7 +62,6 @@ static struct exfat_repair_problem problems[] = { {ER_FILE_LARGER_SIZE, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, {ER_FILE_DUPLICATED_CLUS, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0}, {ER_FILE_ZERO_NOFAT, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}, - {ER_DE_FIRST_CLUS, ERF_PREEN_YES, ERP_FIX, 0, 0, 0} }; static struct exfat_repair_problem *find_problem(er_problem_code_t prcode) @@ -158,3 +158,138 @@ int exfat_repair_ask(struct exfat_fsck *fsck, er_problem_code_t prcode, } return repair; } + +static int check_bad_char(char w) +{ + return (w < 0x0020) || (w == '*') || (w == '?') || (w == '<') || + (w == '>') || (w == '|') || (w == '"') || (w == ':') || + (w == '/') || (w == '\\'); +} + +static char *get_rename_from_user(struct exfat_de_iter *iter) +{ + char *rename = malloc(ENTRY_NAME_MAX + 2); + + if (!rename) + return NULL; + +retry: + /* +2 means LF(Line Feed) and NULL terminator */ + memset(rename, 0x1, ENTRY_NAME_MAX + 2); + printf("New name: "); + if (fgets(rename, ENTRY_NAME_MAX + 2, stdin)) { + int i, len, err; + struct exfat_lookup_filter filter; + + len = strlen(rename); + /* Remove LF in filename */ + rename[len - 1] = '\0'; + for (i = 0; i < len - 1; i++) { + if (check_bad_char(rename[i])) { + printf("filename contain invalid character(%c)\n", rename[i]); + goto retry; + } + } + + exfat_de_iter_flush(iter); + err = exfat_lookup_file(iter->exfat, iter->parent, rename, &filter); + if (!err) { + printf("file(%s) already exists, retry to insert name\n", rename); + goto retry; + } + } + + return rename; +} + +static char *generate_rename(struct exfat_de_iter *iter) +{ + char *rename; + + if (iter->invalid_name_num > INVALID_NAME_NUM_MAX) + return NULL; + + rename = malloc(ENTRY_NAME_MAX + 1); + if (!rename) + return NULL; + + while (1) { + struct exfat_lookup_filter filter; + int err; + + snprintf(rename, ENTRY_NAME_MAX + 1, "FILE%07d.CHK", + iter->invalid_name_num++); + err = exfat_lookup_file(iter->exfat, iter->parent, rename, + &filter); + if (!err) + continue; + break; + } + + return rename; +} + +int exfat_repair_rename_ask(struct exfat_fsck *fsck, struct exfat_de_iter *iter, + char *old_name, er_problem_code_t prcode, char *error_msg) +{ + int num; + +ask_again: + num = exfat_repair_ask(fsck, prcode, "ERROR: '%s' %s.\n%s", + old_name, error_msg, + " [1] Insert the name you want to rename.\n" + " [2] Automatically renames filename.\n" + " [3] Bypass this check(No repair)\n"); + if (num) { + __le16 utf16_name[ENTRY_NAME_MAX]; + char *rename = NULL; + __u16 hash; + struct exfat_dentry *dentry; + int ret, i; + + switch (num) { + case 1: + rename = get_rename_from_user(iter); + break; + case 2: + rename = generate_rename(iter); + break; + case 3: + break; + default: + exfat_info("select 1 or 2 number instead of %d\n", num); + goto ask_again; + } + + if (!rename) + return -EINVAL; + + exfat_info("%s filename is renamed to %s\n", old_name, rename); + + exfat_de_iter_get_dirty(iter, 2, &dentry); + + memset(utf16_name, 0, sizeof(utf16_name)); + ret = exfat_utf16_enc(rename, utf16_name, sizeof(utf16_name)); + free(rename); + if (ret < 0) + return ret; + + ret >>= 1; + memcpy(dentry->name_unicode, utf16_name, ENTRY_NAME_MAX * 2); + hash = exfat_calc_name_hash(iter->exfat, utf16_name, ret); + exfat_de_iter_get_dirty(iter, 1, &dentry); + dentry->stream_name_len = (__u8)ret; + dentry->stream_name_hash = cpu_to_le16(hash); + + exfat_de_iter_get_dirty(iter, 0, &dentry); + i = dentry->file_num_ext; + dentry->file_num_ext = 2; + + for (; i > 2; i--) { + exfat_de_iter_get_dirty(iter, i, &dentry); + dentry->type &= EXFAT_DELETE; + } + } + + return 0; +} diff --git a/fsck/repair.h b/fsck/repair.h index ea89747..634cc49 100644 --- a/fsck/repair.h +++ b/fsck/repair.h @@ -5,6 +5,8 @@ #ifndef _REPAIR_H #define _REPAIR_H +#include "exfat_dir.h" + #define ER_BS_CHECKSUM 0x00000001 #define ER_BS_BOOT_REGION 0x00000002 #define ER_DE_CHECKSUM 0x00001001 @@ -16,6 +18,7 @@ #define ER_DE_NAME_HASH 0x00001031 #define ER_DE_NAME_LEN 0x00001032 #define ER_DE_DOT_NAME 0x00001033 +#define ER_DE_DUPLICATED_NAME 0x00001034 #define ER_FILE_VALID_SIZE 0x00002001 #define ER_FILE_INVALID_CLUS 0x00002002 #define ER_FILE_FIRST_CLUS 0x00002003 @@ -23,11 +26,13 @@ #define ER_FILE_LARGER_SIZE 0x00002005 #define ER_FILE_DUPLICATED_CLUS 0x00002006 #define ER_FILE_ZERO_NOFAT 0x00002007 -#define ER_DE_FIRST_CLUS 0x00002008 + typedef unsigned int er_problem_code_t; struct exfat_fsck; int exfat_repair_ask(struct exfat_fsck *fsck, er_problem_code_t prcode, const char *fmt, ...); +int exfat_repair_rename_ask(struct exfat_fsck *fsck, struct exfat_de_iter *iter, + char *old_name, er_problem_code_t prcode, char *error_msg); #endif diff --git a/include/exfat_dir.h b/include/exfat_dir.h index 12e1546..d450c61 100644 --- a/include/exfat_dir.h +++ b/include/exfat_dir.h @@ -25,13 +25,16 @@ struct exfat_de_iter { off_t de_file_offset; off_t next_read_offset; int max_skip_dentries; -#define DOT_NAME_NUM_MAX 9999999 - unsigned int dot_name_num; +#define INVALID_NAME_NUM_MAX 9999999 + unsigned int invalid_name_num; + + char *name_hash_bitmap; /* bitmap of children's name hashes */ }; struct exfat_lookup_filter { struct { uint8_t type; + int dentry_count; /* return 0 if matched, return 1 if not matched, * otherwise return errno */ @@ -43,8 +46,15 @@ struct exfat_lookup_filter { struct exfat_dentry *dentry_set; int dentry_count; off_t file_offset; - /* device offset where the dentry_set locates, or - * the empty slot locates or EOF if not found. + /* + * If the dentry_set found: + * - device offset where the dentry_set locates. + * If the dentry_set not found: + * - device offset where the first empty dentry_set locates + * if in.dentry_count > 0 and there are enough empty dentry. + * - device offset where the last empty dentry_set locates + * if in.dentry_count = 0 or no enough empty dentry. + * - EOF if no empty dentry_set. */ off_t dev_offset; } out; @@ -65,6 +75,10 @@ int exfat_lookup_dentry_set(struct exfat *exfat, struct exfat_inode *parent, struct exfat_lookup_filter *filter); int exfat_lookup_file(struct exfat *exfat, struct exfat_inode *parent, const char *name, struct exfat_lookup_filter *filter_out); +int exfat_lookup_file_by_utf16name(struct exfat *exfat, + struct exfat_inode *parent, + __le16 *utf16_name, + struct exfat_lookup_filter *filter_out); int exfat_create_file(struct exfat *exfat, struct exfat_inode *parent, const char *name, unsigned short attr); @@ -75,7 +89,6 @@ int exfat_update_file_dentry_set(struct exfat *exfat, int exfat_build_file_dentry_set(struct exfat *exfat, const char *name, unsigned short attr, struct exfat_dentry **dentry_set, int *dentry_count); -int exfat_find_free_cluster(struct exfat *exfat, clus_t start, clus_t *new_clu); int exfat_add_dentry_set(struct exfat *exfat, struct exfat_dentry_loc *loc, struct exfat_dentry *dset, int dcount, bool need_next_loc); diff --git a/include/exfat_ondisk.h b/include/exfat_ondisk.h index d1786bf..42cdadf 100644 --- a/include/exfat_ondisk.h +++ b/include/exfat_ondisk.h @@ -40,6 +40,7 @@ /* exFAT allows 8388608(256MB) directory entries */ #define MAX_EXFAT_DENTRIES 8388608 #define MIN_FILE_DENTRIES 3 +#define MAX_NAME_DENTRIES 17 /* dentry types */ #define MSDOS_DELETED 0xE5 /* deleted mark */ @@ -133,6 +134,7 @@ struct pbr { }; #define VOLUME_LABEL_MAX_LEN 11 +#define VOLUME_GUID_LEN 16 #define ENTRY_NAME_MAX 15 struct exfat_dentry { @@ -190,6 +192,13 @@ struct exfat_dentry { __le32 start_clu; __le64 size; } __attribute__((packed)) upcase; /* up-case table directory entry */ + struct { + __u8 num_ext; + __le16 checksum; + __u16 flags; + __u8 guid[VOLUME_GUID_LEN]; + __u8 reserved[10]; + } __attribute__((packed)) guid; /* volume GUID directory entry */ } __attribute__((packed)) dentry; } __attribute__((packed)); diff --git a/include/libexfat.h b/include/libexfat.h index 0623501..9e853a8 100644 --- a/include/libexfat.h +++ b/include/libexfat.h @@ -45,6 +45,8 @@ typedef __u32 clus_t; #define EXFAT_SET_VOLUME_LABEL 0x02 #define EXFAT_GET_VOLUME_SERIAL 0x03 #define EXFAT_SET_VOLUME_SERIAL 0x04 +#define EXFAT_GET_VOLUME_GUID 0x05 +#define EXFAT_SET_VOLUME_GUID 0x06 #define EXFAT_MAX_SECTOR_SIZE 4096 @@ -52,6 +54,8 @@ typedef __u32 clus_t; (pbr)->bsx.sect_per_clus_bits)) #define EXFAT_SECTOR_SIZE(pbr) (1 << (pbr)->bsx.sect_size_bits) +#define EXFAT_MAX_HASH_COUNT (UINT16_MAX + 1) + enum { BOOT_SEC_IDX = 0, EXBOOT_SEC_IDX, @@ -84,6 +88,7 @@ struct exfat_user_input { __u16 volume_label[VOLUME_LABEL_MAX_LEN]; int volume_label_len; unsigned int volume_serial; + const char *guid; }; struct exfat; @@ -102,18 +107,24 @@ typedef __u32 bitmap_t; #define EXFAT_BITMAP_SIZE(__c_count) \ (DIV_ROUND_UP(__c_count, BITS_PER) * sizeof(bitmap_t)) +#define BITMAP_GET(bmap, bit) \ + (((bitmap_t *)(bmap))[BIT_ENTRY(bit)] & BIT_MASK(bit)) + +#define BITMAP_SET(bmap, bit) \ + (((bitmap_t *)(bmap))[BIT_ENTRY(bit)] |= BIT_MASK(bit)) + static inline bool exfat_bitmap_get(char *bmap, clus_t c) { clus_t cc = c - EXFAT_FIRST_CLUSTER; - return ((bitmap_t *)(bmap))[BIT_ENTRY(cc)] & BIT_MASK(cc); + return BITMAP_GET(bmap, cc); } static inline void exfat_bitmap_set(char *bmap, clus_t c) { clus_t cc = c - EXFAT_FIRST_CLUSTER; - (((bitmap_t *)(bmap))[BIT_ENTRY(cc)] |= BIT_MASK(cc)); + BITMAP_SET(bmap, cc); } static inline void exfat_bitmap_clear(char *bmap, clus_t c) @@ -147,6 +158,9 @@ ssize_t exfat_utf16_dec(const __u16 *in_str, size_t in_len, off_t exfat_get_root_entry_offset(struct exfat_blk_dev *bd); int exfat_read_volume_label(struct exfat *exfat); int exfat_set_volume_label(struct exfat *exfat, char *label_input); +int __exfat_set_volume_guid(struct exfat_dentry *dentry, const char *guid); +int exfat_read_volume_guid(struct exfat *exfat); +int exfat_set_volume_guid(struct exfat *exfat, const char *guid); int exfat_read_sector(struct exfat_blk_dev *bd, void *buf, unsigned int sec_off); int exfat_write_sector(struct exfat_blk_dev *bd, void *buf, diff --git a/include/version.h b/include/version.h index f0b250c..f3cf9e2 100644 --- a/include/version.h +++ b/include/version.h @@ -5,6 +5,6 @@ #ifndef _VERSION_H -#define EXFAT_PROGS_VERSION "1.2.1" +#define EXFAT_PROGS_VERSION "1.2.2" #endif /* !_VERSION_H */ diff --git a/label/Makefile.in b/label/Makefile.in index fcf1417..b79d9d5 100644 --- a/label/Makefile.in +++ b/label/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/label.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,13 +386,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -477,10 +470,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -553,7 +543,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/label.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -599,7 +589,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/label.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -620,9 +610,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 6b7fe70..50c6658 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -126,9 +126,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/exfat_dir.Po ./$(DEPDIR)/exfat_fs.Po \ - ./$(DEPDIR)/libexfat.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -321,8 +319,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -348,15 +346,9 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat_dir.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat_fs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libexfat.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat_dir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exfat_fs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libexfat.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -440,10 +432,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -513,9 +502,7 @@ clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/exfat_dir.Po - -rm -f ./$(DEPDIR)/exfat_fs.Po - -rm -f ./$(DEPDIR)/libexfat.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -561,9 +548,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/exfat_dir.Po - -rm -f ./$(DEPDIR)/exfat_fs.Po - -rm -f ./$(DEPDIR)/libexfat.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -584,16 +569,16 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am diff --git a/lib/exfat_dir.c b/lib/exfat_dir.c index 7c145f4..98e820f 100644 --- a/lib/exfat_dir.c +++ b/lib/exfat_dir.c @@ -237,7 +237,7 @@ int exfat_de_iter_init(struct exfat_de_iter *iter, struct exfat *exfat, iter->de_file_offset = 0; iter->next_read_offset = iter->read_size; iter->max_skip_dentries = 0; - iter->dot_name_num = 0; + iter->invalid_name_num = 0; if (iter->parent->size == 0) return EOF; @@ -356,9 +356,8 @@ int exfat_lookup_dentry_set(struct exfat *exfat, struct exfat_inode *parent, struct exfat_dentry *dentry = NULL; off_t free_file_offset = 0, free_dev_offset = 0; struct exfat_de_iter de_iter; - int dentry_count; + int dentry_count, empty_dentry_count = 0; int retval; - bool last_is_free = false; bd = exfat_alloc_buffer(2, exfat->clus_size, exfat->sect_size); if (!bd) @@ -379,6 +378,12 @@ int exfat_lookup_dentry_set(struct exfat *exfat, struct exfat_inode *parent, goto out; } + if (!IS_EXFAT_DELETED(dentry->type)) { + if (filter->in.dentry_count == 0 || + empty_dentry_count < filter->in.dentry_count) + empty_dentry_count = 0; + } + dentry_count = 1; if (dentry->type == filter->in.type) { retval = 0; @@ -407,18 +412,17 @@ int exfat_lookup_dentry_set(struct exfat *exfat, struct exfat_inode *parent, } else if (retval < 0) { goto out; } - last_is_free = false; - } else if ((dentry->type == EXFAT_LAST || - IS_EXFAT_DELETED(dentry->type))) { - if (!last_is_free) { + } else if (IS_EXFAT_DELETED(dentry->type)) { + if (empty_dentry_count == 0) { free_file_offset = exfat_de_iter_file_offset(&de_iter); free_dev_offset = exfat_de_iter_device_offset(&de_iter); - last_is_free = true; } - } else { - last_is_free = false; + + if (filter->in.dentry_count == 0 || + empty_dentry_count < filter->in.dentry_count) + empty_dentry_count++; } exfat_de_iter_advance(&de_iter, dentry_count); @@ -430,7 +434,7 @@ out: exfat_de_iter_file_offset(&de_iter); filter->out.dev_offset = exfat_de_iter_device_offset(&de_iter); - } else if (retval == EOF && last_is_free) { + } else if (retval == EOF && empty_dentry_count) { filter->out.file_offset = free_file_offset; filter->out.dev_offset = free_dev_offset; } else { @@ -472,7 +476,7 @@ static int filter_lookup_file(struct exfat_de_iter *de_iter, if (retval || name_de->type != EXFAT_NAME) return 1; - len = MIN(name_len, ENTRY_NAME_MAX); + len = MIN(name_len + 1, ENTRY_NAME_MAX); if (memcmp(name_de->dentry.name.unicode_0_14, name, len * 2) != 0) return 1; @@ -485,19 +489,17 @@ static int filter_lookup_file(struct exfat_de_iter *de_iter, return 0; } -int exfat_lookup_file(struct exfat *exfat, struct exfat_inode *parent, - const char *name, struct exfat_lookup_filter *filter_out) +int exfat_lookup_file_by_utf16name(struct exfat *exfat, + struct exfat_inode *parent, + __le16 *utf16_name, + struct exfat_lookup_filter *filter_out) { int retval; - __le16 utf16_name[PATH_MAX + 2] = {0, }; - - retval = (int)exfat_utf16_enc(name, utf16_name, sizeof(utf16_name)); - if (retval < 0) - return retval; filter_out->in.type = EXFAT_FILE; filter_out->in.filter = filter_lookup_file; filter_out->in.param = utf16_name; + filter_out->in.dentry_count = 0; retval = exfat_lookup_dentry_set(exfat, parent, filter_out); if (retval < 0) @@ -506,6 +508,20 @@ int exfat_lookup_file(struct exfat *exfat, struct exfat_inode *parent, return 0; } +int exfat_lookup_file(struct exfat *exfat, struct exfat_inode *parent, + const char *name, struct exfat_lookup_filter *filter_out) +{ + int retval; + __le16 utf16_name[PATH_MAX + 2] = {0, }; + + retval = (int)exfat_utf16_enc(name, utf16_name, sizeof(utf16_name)); + if (retval < 0) + return retval; + + return exfat_lookup_file_by_utf16name(exfat, parent, utf16_name, + filter_out); +} + void exfat_calc_dentry_checksum(struct exfat_dentry *dentry, uint16_t *checksum, bool primary) { @@ -514,12 +530,17 @@ void exfat_calc_dentry_checksum(struct exfat_dentry *dentry, bytes = (uint8_t *)dentry; - *checksum = ((*checksum << 15) | (*checksum >> 1)) + bytes[0]; - *checksum = ((*checksum << 15) | (*checksum >> 1)) + bytes[1]; + /* use += to avoid promotion to int; UBSan complaints about signed overflow */ + *checksum = (*checksum << 15) | (*checksum >> 1); + *checksum += bytes[0]; + *checksum = (*checksum << 15) | (*checksum >> 1); + *checksum += bytes[1]; i = primary ? 4 : 2; - for (; i < sizeof(*dentry); i++) - *checksum = ((*checksum << 15) | (*checksum >> 1)) + bytes[i]; + for (; i < sizeof(*dentry); i++) { + *checksum = (*checksum << 15) | (*checksum >> 1); + *checksum += bytes[i]; + } } static uint16_t calc_dentry_set_checksum(struct exfat_dentry *dset, int dcount) @@ -548,8 +569,11 @@ uint16_t exfat_calc_name_hash(struct exfat *exfat, ch = exfat->upcase_table[le16_to_cpu(name[i])]; ch = cpu_to_le16(ch); - chksum = ((chksum << 15) | (chksum >> 1)) + (ch & 0xFF); - chksum = ((chksum << 15) | (chksum >> 1)) + (ch >> 8); + /* use += to avoid promotion to int; UBSan complaints about signed overflow */ + chksum = (chksum << 15) | (chksum >> 1); + chksum += ch & 0xFF; + chksum = (chksum << 15) | (chksum >> 1); + chksum += ch >> 8; } return chksum; } @@ -678,7 +702,7 @@ int exfat_update_file_dentry_set(struct exfat *exfat, return 0; } -int exfat_find_free_cluster(struct exfat *exfat, +static int find_free_cluster(struct exfat *exfat, clus_t start, clus_t *new_clu) { clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) + @@ -805,7 +829,7 @@ static int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode, if ((need_dset && !inode->dentry_set) || inode->is_contiguous) return -EINVAL; - err = exfat_find_free_cluster(exfat, exfat->start_clu, new_clu); + err = find_free_cluster(exfat, exfat->start_clu, new_clu); if (err) { exfat->start_clu = EXFAT_FIRST_CLUSTER; exfat_err("failed to find an free cluster\n"); diff --git a/lib/libexfat.c b/lib/libexfat.c index 4fd4ac6..d7b8344 100644 --- a/lib/libexfat.c +++ b/lib/libexfat.c @@ -412,6 +412,7 @@ int exfat_read_volume_label(struct exfat *exfat) __le16 disk_label[VOLUME_LABEL_MAX_LEN]; struct exfat_lookup_filter filter = { .in.type = EXFAT_VOLUME, + .in.dentry_count = 0, .in.filter = NULL, }; @@ -453,6 +454,7 @@ int exfat_set_volume_label(struct exfat *exfat, char *label_input) struct exfat_lookup_filter filter = { .in.type = EXFAT_VOLUME, + .in.dentry_count = 1, .in.filter = NULL, }; @@ -492,6 +494,167 @@ int exfat_set_volume_label(struct exfat *exfat, char *label_input) return err; } +static inline void print_guid(const char *msg, const __u8 *guid) +{ + exfat_info("%s: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + msg, + guid[0], guid[1], guid[2], guid[3], + guid[4], guid[5], guid[5], guid[7], + guid[8], guid[9], guid[10], guid[11], + guid[12], guid[13], guid[14], guid[15]); +} + +static int set_guid(__u8 *guid, const char *input) +{ + int i, j, zero_len = 0; + int len = strlen(input); + + if (len != VOLUME_GUID_LEN * 2 && len != VOLUME_GUID_LEN * 2 + 4) { + exfat_err("invalid format for volume guid\n"); + return -EINVAL; + } + + for (i = 0, j = 0; i < len; i++) { + unsigned char ch = input[i]; + + if (ch >= '0' && ch <= '9') + ch -= '0'; + else if (ch >= 'a' && ch <= 'f') + ch -= 'a' - 0xA; + else if (ch >= 'A' && ch <= 'F') + ch -= 'A' - 0xA; + else if (ch == '-' && len == VOLUME_GUID_LEN * 2 + 4 && + (i == 8 || i == 13 || i == 18 || i == 23)) + continue; + else { + exfat_err("invalid character '%c' for volume GUID\n", ch); + return -EINVAL; + } + + if (j & 1) + guid[j >> 1] |= ch; + else + guid[j >> 1] = ch << 4; + + j++; + + if (ch == 0) + zero_len++; + } + + if (zero_len == VOLUME_GUID_LEN * 2) { + exfat_err("%s is invalid for volume GUID\n", input); + return -EINVAL; + } + + return 0; +} + +int exfat_read_volume_guid(struct exfat *exfat) +{ + int err; + uint16_t checksum = 0; + struct exfat_dentry *dentry; + struct exfat_lookup_filter filter = { + .in.type = EXFAT_GUID, + .in.dentry_count = 1, + .in.filter = NULL, + }; + + err = exfat_lookup_dentry_set(exfat, exfat->root, &filter); + if (err) + return err; + + dentry = filter.out.dentry_set; + exfat_calc_dentry_checksum(dentry, &checksum, true); + + if (cpu_to_le16(checksum) == dentry->dentry.guid.checksum) + print_guid("GUID", dentry->dentry.guid.guid); + else + exfat_info("GUID is corrupted, please delete it or set a new one\n"); + + free(dentry); + + return err; +} + +int __exfat_set_volume_guid(struct exfat_dentry *dentry, const char *guid) +{ + int err; + uint16_t checksum = 0; + + memset(dentry, 0, sizeof(*dentry)); + dentry->type = EXFAT_GUID; + + err = set_guid(dentry->dentry.guid.guid, guid); + if (err) + return err; + + exfat_calc_dentry_checksum(dentry, &checksum, true); + dentry->dentry.guid.checksum = cpu_to_le16(checksum); + + return 0; +} + +/* + * Create/Update/Delete GUID dentry in root directory + * + * create/update GUID if @guid is not NULL. + * delete GUID if @guid is NULL. + */ +int exfat_set_volume_guid(struct exfat *exfat, const char *guid) +{ + struct exfat_dentry *dentry; + struct exfat_dentry_loc loc; + int err; + + struct exfat_lookup_filter filter = { + .in.type = EXFAT_GUID, + .in.dentry_count = 1, + .in.filter = NULL, + }; + + err = exfat_lookup_dentry_set(exfat, exfat->root, &filter); + if (!err) { + /* GUID entry is found */ + dentry = filter.out.dentry_set; + } else { + /* no GUID to delete */ + if (guid == NULL) + return 0; + + dentry = calloc(1, sizeof(*dentry)); + if (!dentry) + return -ENOMEM; + } + + if (guid) { + /* Set GUID */ + err = __exfat_set_volume_guid(dentry, guid); + if (err) + goto out; + } else { + /* Delete GUID */ + dentry->type &= ~EXFAT_INVAL; + } + + loc.parent = exfat->root; + loc.file_offset = filter.out.file_offset; + loc.dev_offset = filter.out.dev_offset; + err = exfat_add_dentry_set(exfat, &loc, dentry, 1, false); + if (!err) { + if (guid) + print_guid("new GUID", dentry->dentry.guid.guid); + else + exfat_info("GUID is deleted\n"); + } + +out: + free(dentry); + + return err; +} + int exfat_read_sector(struct exfat_blk_dev *bd, void *buf, unsigned int sec_off) { int ret; diff --git a/m4/libtool.m4 b/m4/libtool.m4 index a6d21ae..ee80844 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -1041,8 +1041,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1492,7 +1492,7 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cr} +: ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) @@ -4063,8 +4063,7 @@ _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD - if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4704,12 +4703,6 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - # flang / f18. f95 an alias for gfortran or flang on Debian - flang* | f18* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -6445,7 +6438,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no @@ -6820,7 +6813,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6885,7 +6878,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -7224,7 +7217,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support @@ -7308,7 +7301,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7319,7 +7312,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' diff --git a/manpages/mkfs.exfat.8 b/manpages/mkfs.exfat.8 index 9f867d3..76a0065 100644 --- a/manpages/mkfs.exfat.8 +++ b/manpages/mkfs.exfat.8 @@ -17,6 +17,9 @@ mkfs.exfat \- create an exFAT filesystem .B \-L .I volume_label ] [ +.B \-U +.I volume_guid +] [ .B \-\-pack\-bitmap ] [ .B \-v @@ -67,12 +70,23 @@ _ >128 GiB \[<=]512 GiB 256 KiB 32 MiB >512 GiB \[<=]2 TiB 512 KiB 64 MiB .TE +The default is always 1 MiB. .TP .BR \-c ", " \-\-cluster\-size =\fIsize\fR Specifies the cluster size of the exFAT file system. The \fIsize\fR argument is specified in bytes or may be specified with \fBm\fR/\fBM\fR suffix for mebibytes or \fBk\fR/\fBK\fR suffix for kibibytes and must be a power of two. +The default value is described in the following table: +.TS +center; +cb1s6cb,nnn. +Card Capacity Range Cluster Size +_ + \[<=]256 MiB 4 KiB +>256 MiB \[<=]32 GiB 32 KiB +>32 GiB 128 KiB +.TE .TP .BR \-f ", " \-\-full\-format Performs a full format. @@ -84,6 +98,9 @@ Prints the help and exit. .BR \-L ", " \-\-volume\-label =\fIlabel\fR Specifies the volume label to be associated with the exFAT filesystem. .TP +.BR \-U ", " \-\-volume\-guid =\fIguid\fR +Specifies the volume GUID to be associated with the exFAT filesystem. +.TP .B \-\-pack\-bitmap Attempts to relocate the exFAT allocation bitmap so that it ends at the alignment boundary immediately following the FAT rather than beginning at that @@ -101,6 +118,9 @@ allocation unit with the FAT. If there is insufficient space for the bitmap there, then this option will have no effect, and the bitmap will be aligned at the boundary as by default. .TP +.BR \-q ", " \-\-quiet +Prints only error messages while creating the exFAT filesystem. +.TP .BR \-v ", " \-\-verbose Prints verbose debugging information while creating the exFAT filesystem. .TP diff --git a/manpages/tune.exfat.8 b/manpages/tune.exfat.8 index 865dc07..b57c746 100644 --- a/manpages/tune.exfat.8 +++ b/manpages/tune.exfat.8 @@ -10,6 +10,12 @@ tune.exfat \- adjust tunable filesystem parameters on an exFAT filesystem .B \-L .I set-label ] [ +.B \-u +.I print-guid +] [ +.B \-U +.I set-guid +] [ .B \-i .I print-serial ] [ @@ -33,6 +39,12 @@ Print the volume label of the exFAT filesystem. .BI \-L " set-label" Set the volume label of the filesystem to the provided argument. .TP +.BI \-u " print-guid" +Print the volume GUID of the exFAT filesystem. +.TP +.BI \-U " set-guid" +Set the volume GUID of the filesystem to the provided argument. +.TP .BI \-i " print-serial" Print the volume serial of the exFAT filesystem. .TP diff --git a/mkfs/Makefile.in b/mkfs/Makefile.in index f89addc..d43dece 100644 --- a/mkfs/Makefile.in +++ b/mkfs/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/mkfs.Po ./$(DEPDIR)/upcase.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,14 +386,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkfs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upcase.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkfs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upcase.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -478,10 +471,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -554,8 +544,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/mkfs.Po - -rm -f ./$(DEPDIR)/upcase.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -601,8 +590,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/mkfs.Po - -rm -f ./$(DEPDIR)/upcase.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -623,9 +611,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index f9e5bb4..773c64e 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -337,8 +337,8 @@ static int exfat_create_bitmap(struct exfat_blk_dev *bd) static int exfat_create_root_dir(struct exfat_blk_dev *bd, struct exfat_user_input *ui) { - struct exfat_dentry ed[3] = {0}; - int dentries_len = sizeof(struct exfat_dentry) * 3; + struct exfat_dentry ed[4] = {0}; + int dentries_len = sizeof(ed); int nbytes; /* Set volume label entry */ @@ -347,17 +347,29 @@ static int exfat_create_root_dir(struct exfat_blk_dev *bd, memcpy(ed[0].vol_label, ui->volume_label, ui->volume_label_len); ed[0].vol_char_cnt = ui->volume_label_len/2; + /* Set volume GUID entry */ + if (ui->guid) { + if (__exfat_set_volume_guid(&ed[1], ui->guid)) + return -1; + } else { + /* + * Since a single empty entry cannot be allocated for a + * file, this can reserve the entry for volume GUID. + */ + ed[1].type = EXFAT_GUID & ~EXFAT_INVAL; + } + /* Set bitmap entry */ - ed[1].type = EXFAT_BITMAP; - ed[1].bitmap_flags = 0; - ed[1].bitmap_start_clu = cpu_to_le32(EXFAT_FIRST_CLUSTER); - ed[1].bitmap_size = cpu_to_le64(finfo.bitmap_byte_len); + ed[2].type = EXFAT_BITMAP; + ed[2].bitmap_flags = 0; + ed[2].bitmap_start_clu = cpu_to_le32(EXFAT_FIRST_CLUSTER); + ed[2].bitmap_size = cpu_to_le64(finfo.bitmap_byte_len); /* Set upcase table entry */ - ed[2].type = EXFAT_UPCASE; - ed[2].upcase_checksum = cpu_to_le32(0xe619d30d); - ed[2].upcase_start_clu = cpu_to_le32(finfo.ut_start_clu); - ed[2].upcase_size = cpu_to_le64(EXFAT_UPCASE_TABLE_SIZE); + ed[3].type = EXFAT_UPCASE; + ed[3].upcase_checksum = cpu_to_le32(0xe619d30d); + ed[3].upcase_start_clu = cpu_to_le32(finfo.ut_start_clu); + ed[3].upcase_size = cpu_to_le64(EXFAT_UPCASE_TABLE_SIZE); nbytes = pwrite(bd->dev_fd, ed, dentries_len, finfo.root_byte_off); if (nbytes != dentries_len) { @@ -373,11 +385,13 @@ static void usage(void) { fputs("Usage: mkfs.exfat\n" "\t-L | --volume-label=label Set volume label\n" + "\t-U | --volume-guid=guid Set volume GUID\n" "\t-c | --cluster-size=size(or suffixed by 'K' or 'M') Specify cluster size\n" "\t-b | --boundary-align=size(or suffixed by 'K' or 'M') Specify boundary alignment\n" "\t --pack-bitmap Move bitmap into FAT segment\n" "\t-f | --full-format Full format\n" "\t-V | --version Show version\n" + "\t-q | --quiet Print only errors\n" "\t-v | --verbose Print debug\n" "\t-h | --help Show help\n", stderr); @@ -389,11 +403,13 @@ static void usage(void) static const struct option opts[] = { {"volume-label", required_argument, NULL, 'L' }, + {"volume-guid", required_argument, NULL, 'U' }, {"cluster-size", required_argument, NULL, 'c' }, {"boundary-align", required_argument, NULL, 'b' }, {"pack-bitmap", no_argument, NULL, PACK_BITMAP }, {"full-format", no_argument, NULL, 'f' }, {"version", no_argument, NULL, 'V' }, + {"quiet", no_argument, NULL, 'q' }, {"verbose", no_argument, NULL, 'v' }, {"help", no_argument, NULL, 'h' }, {"?", no_argument, NULL, '?' }, @@ -605,6 +621,7 @@ int main(int argc, char *argv[]) struct exfat_blk_dev bd; struct exfat_user_input ui; bool version_only = false; + bool quiet = false; init_user_input(&ui); @@ -612,7 +629,7 @@ int main(int argc, char *argv[]) exfat_err("failed to init locale/codeset\n"); opterr = 0; - while ((c = getopt_long(argc, argv, "n:L:c:b:fVvh", opts, NULL)) != EOF) + while ((c = getopt_long(argc, argv, "n:L:U:c:b:fVqvh", opts, NULL)) != EOF) switch (c) { /* * Make 'n' option fallthrough to 'L' option for for backward @@ -629,6 +646,10 @@ int main(int argc, char *argv[]) ui.volume_label_len = ret; break; } + case 'U': + if (*optarg != '\0' && *optarg != '\r') + ui.guid = optarg; + break; case 'c': ret = parse_size(optarg); if (ret < 0) @@ -664,6 +685,10 @@ int main(int argc, char *argv[]) case 'V': version_only = true; break; + case 'q': + print_level = EXFAT_ERROR; + quiet = true; + break; case 'v': print_level = EXFAT_DEBUG; break; @@ -673,9 +698,12 @@ int main(int argc, char *argv[]) usage(); } - show_version(); - if (version_only) + if (version_only) { + show_version(); exit(EXIT_FAILURE); + } else if (!quiet) { + show_version(); + } if (argc - optind != 1) { usage(); @@ -708,6 +736,6 @@ out: if (!ret) exfat_info("\nexFAT format complete!\n"); else - exfat_info("\nexFAT format fail!\n"); + exfat_err("\nexFAT format fail!\n"); return ret; } diff --git a/tune/Makefile.in b/tune/Makefile.in index 4bc7ca5..030f811 100644 --- a/tune/Makefile.in +++ b/tune/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -125,8 +125,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/tune.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -315,8 +314,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -387,13 +386,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tune.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tune.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -477,10 +470,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -553,7 +543,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/tune.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -599,7 +589,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/tune.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -620,9 +610,9 @@ uninstall-am: uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/tune/tune.c b/tune/tune.c index 135f624..f883556 100644 --- a/tune/tune.c +++ b/tune/tune.c @@ -20,6 +20,8 @@ static void usage(void) fprintf(stderr, "Usage: tune.exfat\n"); fprintf(stderr, "\t-l | --print-label Print volume label\n"); fprintf(stderr, "\t-L | --set-label=label Set volume label\n"); + fprintf(stderr, "\t-u | --print-guid Print volume GUID\n"); + fprintf(stderr, "\t-U | --set-guid=guid Set volume GUID\n"); fprintf(stderr, "\t-i | --print-serial Print volume serial\n"); fprintf(stderr, "\t-I | --set-serial=value Set volume serial\n"); fprintf(stderr, "\t-V | --version Show version\n"); @@ -32,6 +34,8 @@ static void usage(void) static struct option opts[] = { {"print-label", no_argument, NULL, 'l' }, {"set-label", required_argument, NULL, 'L' }, + {"print-guid", no_argument, NULL, 'u' }, + {"set-guid", required_argument, NULL, 'U' }, {"print-serial", no_argument, NULL, 'i' }, {"set-serial", required_argument, NULL, 'I' }, {"version", no_argument, NULL, 'V' }, @@ -59,7 +63,7 @@ int main(int argc, char *argv[]) exfat_err("failed to init locale/codeset\n"); opterr = 0; - while ((c = getopt_long(argc, argv, "I:iL:lVvh", opts, NULL)) != EOF) + while ((c = getopt_long(argc, argv, "I:iL:lU:uVvh", opts, NULL)) != EOF) switch (c) { case 'l': flags = EXFAT_GET_VOLUME_LABEL; @@ -69,6 +73,14 @@ int main(int argc, char *argv[]) optarg); flags = EXFAT_SET_VOLUME_LABEL; break; + case 'u': + flags = EXFAT_GET_VOLUME_GUID; + break; + case 'U': + if (*optarg != '\0' && *optarg != '\r') + ui.guid = optarg; + flags = EXFAT_SET_VOLUME_GUID; + break; case 'i': flags = EXFAT_GET_VOLUME_SERIAL; break; @@ -140,6 +152,11 @@ int main(int argc, char *argv[]) ret = exfat_read_volume_label(exfat); else if (flags == EXFAT_SET_VOLUME_LABEL) ret = exfat_set_volume_label(exfat, label_input); + else if (flags == EXFAT_GET_VOLUME_GUID) + ret = exfat_read_volume_guid(exfat); + else if (flags == EXFAT_SET_VOLUME_GUID) + ret = exfat_set_volume_guid(exfat, ui.guid); + close_fd_out: close(bd.dev_fd); if (exfat) -- 2.39.2 From d8f4a908282b8d0212cfc61d9fd705ccc1f79360 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Sun, 29 Oct 2023 11:41:37 +0100 Subject: [PATCH 14/16] New upstream release. --- debian/changelog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 77ff19e..e3da194 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,9 @@ -exfatprogs (1.2.1-3) UNRELEASED; urgency=medium +exfatprogs (1.2.2-1) UNRELEASED; urgency=medium + * New upstream release. * Update debian/copyright. Drop year from my own copyright line. - -- Sven Hoexter Wed, 14 Jun 2023 17:39:59 +0200 + -- Sven Hoexter Sun, 29 Oct 2023 11:41:19 +0100 exfatprogs (1.2.1-2) unstable; urgency=medium -- 2.39.2 From 760c7a0f47754a291cc741cdeb8144f0d4266c15 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Sun, 29 Oct 2023 11:53:58 +0100 Subject: [PATCH 15/16] releasing package exfatprogs version 1.2.2-1 --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index e3da194..45cfcf1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -exfatprogs (1.2.2-1) UNRELEASED; urgency=medium +exfatprogs (1.2.2-1) unstable; urgency=medium * New upstream release. * Update debian/copyright. Drop year from my own copyright line. - -- Sven Hoexter Sun, 29 Oct 2023 11:41:19 +0100 + -- Sven Hoexter Sun, 29 Oct 2023 11:53:47 +0100 exfatprogs (1.2.1-2) unstable; urgency=medium -- 2.39.2 From 67926d683b4aecd83193718510fe4f908e18865f Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Tue, 31 Oct 2023 19:52:55 +0100 Subject: [PATCH 16/16] Add CVE ID to debian changelog --- debian/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/changelog b/debian/changelog index 45cfcf1..f3a4431 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ exfatprogs (1.2.2-1) unstable; urgency=medium * New upstream release. + Includes fixes for CVE-2023-45897 out-of-bounds memory access. * Update debian/copyright. Drop year from my own copyright line. -- Sven Hoexter Sun, 29 Oct 2023 11:53:47 +0100 -- 2.39.2