Corresponds to Cygwin's 1.4.17-4. Additional patch to not build lssparse if SEEK_HOLE is not defined in unistd.h, as it is not on runtime versions < 3.6.
309 lines
9.1 KiB
Diff
309 lines
9.1 KiB
Diff
diff --git a/ChangeLog b/ChangeLog
|
|
index 0a1709c..53dd562 100644
|
|
--- a/ChangeLog
|
|
+++ b/ChangeLog
|
|
@@ -1,3 +1,21 @@
|
|
+2025-04-24 Mark Geisert <mark@maxrnd.com> (1.4.17-4)
|
|
+
|
|
+ * src/cygstart/cygstart.c: Fix len arg of mbstowcs. Thanks to user
|
|
+ ggl329@gmail.com for the report and Christian Franke for the
|
|
+ diagnosis and discussion.
|
|
+
|
|
+2025-04-05 Mark Geisert <mark@maxrnd.com> (1.4.17-3)
|
|
+
|
|
+ * src/lssparse/lssparse.c: Fix hole display glitch. Updated source
|
|
+ provided by Roland Mainz.
|
|
+
|
|
+2025-04-01 Mark Geisert <mark@maxrnd.com> (1.4.17-2)
|
|
+
|
|
+ * src/lssparse/*: Add new tool contributed by Roland Mainz.
|
|
+ * src/configure.ac: Ditto.
|
|
+ * src/Makefile.am: Ditto.
|
|
+ * cygutils.cygport: Ditto. Also add CXXFLAGS+=" -std=gnu++03".
|
|
+
|
|
2022-01-28 Mark Geisert <mark@maxrnd.com>
|
|
|
|
Release 1.4.17
|
|
diff --git a/Makefile.am b/Makefile.am
|
|
index 79eb2b1..ef9b8a2 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -34,6 +34,7 @@ endif
|
|
|
|
bin_PROGRAMS = $(windows_progs) src/conv/conv \
|
|
src/dump/dump $(ipc_progs) \
|
|
+ src/lssparse/lssparse \
|
|
$(cygwin_specific_progs)
|
|
|
|
bin_SCRIPTS = $(ipc_scripts)
|
|
diff --git a/NEWS b/NEWS
|
|
index 3b42b62..c3326af 100644
|
|
--- a/NEWS
|
|
+++ b/NEWS
|
|
@@ -1,5 +1,6 @@
|
|
1.4.17
|
|
* More bug fixes to getclip and putclip.
|
|
+ * New tool lssparse contributed by Roland Mainz.
|
|
|
|
1.4.16
|
|
* Unicode support added to mkshortcut and readshortcut by Thomas Wolff.
|
|
diff --git a/src/cygstart/cygstart.c b/src/cygstart/cygstart.c
|
|
index 7e5bf3a..cfb2084 100644
|
|
--- a/src/cygstart/cygstart.c
|
|
+++ b/src/cygstart/cygstart.c
|
|
@@ -560,8 +560,7 @@ cygstart_mbs_to_wcs (const char *mbs_path, wchar_t **wcs_path)
|
|
goto err_cleanup;
|
|
}
|
|
|
|
- if (mbstowcs (*wcs_path, mbs_path, (len + 1) * sizeof (wchar_t)) ==
|
|
- (size_t) - 1)
|
|
+ if ((mbstowcs (*wcs_path, mbs_path, len)) == (size_t) - 1)
|
|
{
|
|
fprintf (stderr, "%s: error converting path `%s' to unicode: %s\n",
|
|
program_name, mbs_path, strerror (errno));
|
|
diff --git a/src/lssparse/lssparse.c b/src/lssparse/lssparse.c
|
|
new file mode 100644
|
|
index 0000000..9c64d1b
|
|
--- /dev/null
|
|
+++ b/src/lssparse/lssparse.c
|
|
@@ -0,0 +1,239 @@
|
|
+/*
|
|
+ * MIT License
|
|
+ *
|
|
+ * Copyright (c) 2011-2025 Roland Mainz <roland.mainz@nrubsig.org>
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
+ * of this software and associated documentation files (the "Software"), to deal
|
|
+ * in the Software without restriction, including without limitation the rights
|
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
+ * copies of the Software, and to permit persons to whom the Software is
|
|
+ * furnished to do so, subject to the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be included in all
|
|
+ * copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
+ * SOFTWARE.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * lssparse.c - print sparse file hole+data layout information
|
|
+ *
|
|
+ * Written by Roland Mainz <roland.mainz@nrubsig.org>
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <stdbool.h>
|
|
+#include <string.h>
|
|
+#include <fcntl.h>
|
|
+#include <unistd.h>
|
|
+#include <errno.h>
|
|
+
|
|
+#define EXIT_USAGE (2)
|
|
+
|
|
+static
|
|
+void usage(const char *progname)
|
|
+{
|
|
+ (void)fprintf(stderr, "Usage: %s [-h] [-xdH] <sparse_file>\n"
|
|
+ " -h: Display this help message\n"
|
|
+ " -x: Print offsets in hexadecimal (base 16)\n"
|
|
+ " -d: Print offsets in decimal (base 10)\n"
|
|
+ " -H: Print hole information\n",
|
|
+ progname);
|
|
+}
|
|
+
|
|
+typedef enum _printbase {
|
|
+ pb_hex = 1,
|
|
+ pb_dec = 2
|
|
+} printbase;
|
|
+
|
|
+int main(int argc, char *argv[])
|
|
+{
|
|
+ /* Arguments */
|
|
+ const char *progname = argv[0];
|
|
+ printbase pb = pb_hex;
|
|
+ bool print_holes = false;
|
|
+ const char *filename;
|
|
+
|
|
+ int retval;
|
|
+ int opt;
|
|
+ int fd;
|
|
+
|
|
+ size_t i;
|
|
+ off_t offset = 0;
|
|
+ off_t data_start;
|
|
+ off_t hole_start;
|
|
+ off_t hole_end;
|
|
+ off_t file_size;
|
|
+ off_t data_len;
|
|
+ off_t hole_len;
|
|
+
|
|
+ while ((opt = getopt(argc, argv, "hxdH")) != -1) {
|
|
+ switch (opt) {
|
|
+ case '?':
|
|
+ case 'h':
|
|
+ usage(progname);
|
|
+ return EXIT_USAGE;
|
|
+ case 'x':
|
|
+ pb = pb_hex;
|
|
+ break;
|
|
+ case 'd':
|
|
+ pb = pb_dec;
|
|
+ break;
|
|
+ case 'H':
|
|
+ print_holes = true;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (optind >= argc) {
|
|
+ usage(progname);
|
|
+ return EXIT_USAGE;
|
|
+ }
|
|
+
|
|
+ filename = argv[optind];
|
|
+
|
|
+ fd = open(filename, O_RDONLY);
|
|
+ if (fd == -1) {
|
|
+ (void)fprintf(stderr, "%s: Open file failed with [%s]\n",
|
|
+ progname,
|
|
+ strerror(errno));
|
|
+ return EXIT_FAILURE;
|
|
+ }
|
|
+
|
|
+ /* Get file size */
|
|
+ file_size = lseek(fd, 0, SEEK_END);
|
|
+ if (file_size == -1) {
|
|
+ (void)fprintf(stderr, "%s: Cannot seek [%s]\n",
|
|
+ progname,
|
|
+ strerror(errno));
|
|
+ return EXIT_FAILURE;
|
|
+ }
|
|
+ (void)lseek(fd, 0, SEEK_SET);
|
|
+
|
|
+
|
|
+ /*
|
|
+ * Loop over hole&&data sections
|
|
+ *
|
|
+ * This loop must handle:
|
|
+ * - normal files with no holes
|
|
+ * - sparse files which start with data
|
|
+ * - sparse files which start with a hole
|
|
+ * - sparse files with multiple holes
|
|
+ * - sparse files which end with data
|
|
+ * - sparse files which end with a hole
|
|
+ *
|
|
+ * Note we start with index |1| for compatibility
|
|
+ * with SUN's original sparse file debuggung tools
|
|
+ * and Win32's
|
|
+ * $ /cygdrive/c/Windows/system32/fsutil sparse queryrange ... #
|
|
+ * output
|
|
+ */
|
|
+#define LSSPARSE_START_INDEX 1
|
|
+ for (i=LSSPARSE_START_INDEX ;;) {
|
|
+ data_start = lseek(fd, offset, SEEK_DATA);
|
|
+ if (data_start == -1)
|
|
+ break;
|
|
+ hole_start = lseek(fd, data_start, SEEK_HOLE);
|
|
+
|
|
+ if (hole_start == -1) {
|
|
+ if (errno == ENXIO) {
|
|
+ /* No more holes ? Use file site as pos of next hole */
|
|
+ hole_start = file_size;
|
|
+ } else {
|
|
+ (void)fprintf(stderr,
|
|
+ "%s: lseek(..., SEEK_HOLE, ...) failed with [%s]\n",
|
|
+ progname,
|
|
+ strerror(errno));
|
|
+ retval = EXIT_FAILURE;
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (print_holes &&
|
|
+ (i == LSSPARSE_START_INDEX) && (data_start > 0)) {
|
|
+ (void)printf((pb == pb_hex)?
|
|
+ "Hole range[%ld]: offset=0x%llx,\tlength=0x%llx\n":
|
|
+ "Hole range[%ld]: offset=%lld,\tlength=%lld\n",
|
|
+ (long)i,
|
|
+ (long long)0,
|
|
+ (long long)data_start);
|
|
+ i++;
|
|
+ }
|
|
+
|
|
+ data_len = hole_start - data_start;
|
|
+
|
|
+ (void)printf((pb == pb_hex)?
|
|
+ "Data range[%ld]: offset=0x%llx,\tlength=0x%llx\n":
|
|
+ "Data range[%ld]: offset=%lld,\tlength=%lld\n",
|
|
+ (long)i,
|
|
+ (long long)data_start,
|
|
+ (long long)data_len);
|
|
+ i++;
|
|
+
|
|
+ hole_end = lseek(fd, hole_start, SEEK_DATA);
|
|
+
|
|
+ if (hole_end == -1) {
|
|
+ if (errno == ENXIO) {
|
|
+ /* No more holes ? */
|
|
+ hole_end = file_size;
|
|
+ } else {
|
|
+ (void)fprintf(stderr,
|
|
+ "%s: lseek(..., SEEK_DATA, ...) failed with [%s]\n",
|
|
+ progname,
|
|
+ strerror(errno));
|
|
+ retval = EXIT_FAILURE;
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ hole_len = hole_end - hole_start;
|
|
+
|
|
+ if (print_holes && (hole_len > 0LL)) {
|
|
+ (void)printf((pb == pb_hex)?
|
|
+ "Hole range[%ld]: offset=0x%llx,\tlength=0x%llx\n":
|
|
+ "Hole range[%ld]: offset=%lld,\tlength=%lld\n",
|
|
+ (long)i,
|
|
+ (long long)hole_start,
|
|
+ (long long)hole_len);
|
|
+ i++;
|
|
+ }
|
|
+
|
|
+ offset = hole_end;
|
|
+ }
|
|
+
|
|
+ if ((data_start == -1) && (errno == ENXIO) && (offset == 0)) {
|
|
+ if (print_holes) {
|
|
+ (void)printf((pb == pb_hex)?
|
|
+ "Hole range[%ld]: offset=0x%llx,\tlength=0x%llx\n":
|
|
+ "Hole range[%ld]: offset=%lld,\tlength=%lld\n",
|
|
+ (long)LSSPARSE_START_INDEX,
|
|
+ (long long)0LL,
|
|
+ (long long)file_size);
|
|
+ }
|
|
+
|
|
+ retval = EXIT_SUCCESS;
|
|
+ } else if ((data_start == -1) && (errno != ENXIO)) {
|
|
+ (void)fprintf(stderr,
|
|
+ "%s: lseek(..., SEEK_DATA, ...) failed with [%s]\n",
|
|
+ progname,
|
|
+ strerror(errno));
|
|
+ retval = EXIT_FAILURE;
|
|
+ }
|
|
+ else {
|
|
+ retval = EXIT_SUCCESS;
|
|
+ }
|
|
+
|
|
+done:
|
|
+ (void)close(fd);
|
|
+ return retval;
|
|
+}
|