From efd41dceb1dea92d2caf45c86ee54ab0daf4335a Mon Sep 17 00:00:00 2001 From: Eremey Valetov Date: Thu, 11 Jun 2026 15:17:50 -0400 Subject: [PATCH] add uc2.1 man page and install rules mdoc man page covering all modes and the OTS/ingest long options, verified with groff and NetBSD mandoc. CMake installs the binary and the man page (guarded against add_subdirectory embedding). Also corrects the stale direction-1 comment in the DOSBox round-trip script: multi-file archives created by v3 have extracted fine in the original since the custom-Huffman-tree fix. --- cli/CMakeLists.txt | 10 ++ cli/uc2.1 | 183 ++++++++++++++++++++++++++++++ tests/scripts/roundtrip_dosbox.sh | 10 +- 3 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 cli/uc2.1 diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index e2ddb55..75d8abc 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,5 +1,7 @@ # uc2 command-line tool +include(GNUInstallDirs) + add_executable(uc2-cli src/main.c) set_target_properties(uc2-cli PROPERTIES OUTPUT_NAME uc2) @@ -13,6 +15,14 @@ target_include_directories(uc2-cli PRIVATE target_compile_features(uc2-cli PRIVATE c_std_99) +# Skip installation when uc2 is embedded via add_subdirectory() +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + install(TARGETS uc2-cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + if(UNIX) + install(FILES uc2.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + endif() +endif() + if(WIN32) target_sources(uc2-cli PRIVATE src/compat/compat_win32.c) # Shared compat headers (err.h, fnmatch.h) — both MSVC and MinGW lack these diff --git a/cli/uc2.1 b/cli/uc2.1 new file mode 100644 index 0000000..2a67847 --- /dev/null +++ b/cli/uc2.1 @@ -0,0 +1,183 @@ +.\" SPDX-License-Identifier: GPL-3.0-or-later +.Dd June 11, 2026 +.Dt UC2 1 +.Os +.Sh NAME +.Nm uc2 +.Nd UltraCompressor II archiver +.Sh SYNOPSIS +.Nm +.Op Fl afpqDT +.Op Fl C Ar directory +.Op Fl d Ar destination +.Ar archive.uc2 +.Op Ar file ... +.Nm +.Fl l +.Op Fl aqT +.Ar archive.uc2 +.Op Ar file ... +.Nm +.Fl t +.Op Fl aq +.Ar archive.uc2 +.Op Ar file ... +.Nm +.Fl w +.Op Fl q +.Op Fl L Ar level +.Ar archive.uc2 +.Ar file ... +.Nm +.Fl B +.Ar file ... +.Nm +.Fl -ots-attach Ar proof.ots +.Op Fl f +.Ar archive.uc2 +.Nm +.Fl -ots-extract +.Ar archive.uc2 out.ots +.Nm +.Fl -ots-info +.Ar archive.uc2 +.Nm +.Fl -ingest Ar archive +.Nm +.Fl -ingest-restore Ar archive +.Sh DESCRIPTION +.Nm +is a cross-platform revival of UltraCompressor II, the MS-DOS archiver +published by Nico de Vries (AIP-NL) between 1992 and 1996. +It reads and writes the original UC2 archive format byte-compatibly: +archives created by the original +.Pa uc2pro.exe +extract correctly, and archives created at compression levels 2 through 5 +can be read by the original DOS program. +.Pp +Without a mode option, +.Nm +extracts the named archive into the current directory (or into the +directory given with +.Fl d ) . +If +.Ar file +arguments are given, only matching entries are processed; shell-style +wildcards are accepted. +.Pp +Compression levels 2 through 5 use the original LZ77 and Huffman +bitstream. +Levels 6 through 9 replace the entropy stage with rANS coding for +better ratios; such archives require +.Nm +version 3 and cannot be read by the original DOS program. +Files with similar content are grouped and compressed against shared +master blocks, the deduplication scheme UC2 introduced in 1992. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl a +Process all stored versions of each file, not only the most recent. +.It Fl B +Benchmark every compression method on the given input files and print +a comparison table; no archive is written. +.It Fl C Ar directory +Change to +.Ar directory +before reading or writing any files. +Applies in every mode. +.It Fl c , Fl p +Write extracted data to standard output instead of creating files. +.It Fl D +Do not restore modification times and permissions of directories. +Given twice, file metadata is not restored either. +.It Fl d Ar destination +Extract into +.Ar destination +instead of the current directory. +.It Fl f +Overwrite existing files when extracting, and allow +.Fl -ots-attach +to replace an existing proof. +.It Fl h +Print version, usage, and option summary. +.It Fl L Ar level +Select the compression level for +.Fl w : +2 (Fast), 3 (Normal), 4 (Tight, the default), 5 (Ultra) for the +backward-compatible Huffman methods, or 6 through 9 for rANS. +.It Fl l +List the archive contents. +.It Fl q +Quiet operation; suppress status messages. +.It Fl T +Separate listing columns with tabs instead of spaces. +.It Fl t +Test archive integrity without writing any files. +.It Fl w +Create (write) an archive from the given files and directories. +.It Fl x +Extract; this is the default mode. +.El +.Pp +The long options operate on OpenTimestamps proofs and the streaming +deduplication store: +.Bl -tag -width Ds +.It Fl -ots-attach Ar proof.ots +Attach an OpenTimestamps proof to the archive after verifying that the +proof commits to the archive contents. +The proof is stored in a trailer that the original DOS program ignores. +.It Fl -ots-extract +Write the attached proof to the named output file, suitable for +.Ql ots verify . +.It Fl -ots-info +Describe the attached proof. +.It Fl -ingest Ar archive +Read a data stream from standard input into a content-addressed +deduplicating block store inside +.Ar archive . +.It Fl -ingest-restore Ar archive +Write the ingested stream from +.Ar archive +to standard output. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +Create an archive at the default level and list it: +.Bd -literal -offset indent +$ uc2 -w backup.uc2 project/ notes.txt +$ uc2 -l backup.uc2 +.Ed +.Pp +Extract it elsewhere, overwriting existing files (the destination +directory must exist): +.Bd -literal -offset indent +$ mkdir -p /tmp/restore +$ uc2 -f -d /tmp/restore backup.uc2 +.Ed +.Pp +Create a smaller archive readable only by +.Nm +version 3, then verify it: +.Bd -literal -offset indent +$ uc2 -w -L 9 backup.uc2 project/ +$ uc2 -t backup.uc2 +.Ed +.Sh HISTORY +UltraCompressor II was written by Nico de Vries at AIP-NL and sold as +shareware from 1992 to 1996. +De Vries re-released the original source under the LGPL in 2015; Jan +Bobrowski's libunuc2 (2020) built a portable decompressor from it. +.Nm +version 3 builds on that lineage as a full reimplementation in C99, +maintained by Eremey Valetov. +.Sh AUTHORS +.An Nico de Vries +(original UltraCompressor II), +.An Jan Bobrowski +(libunuc2), +.An Eremey Valetov Aq Mt evaletov@protonmail.com +(version 3). +.Pp +Source and issue tracker: +.Lk https://github.com/evvaletov/uc2 diff --git a/tests/scripts/roundtrip_dosbox.sh b/tests/scripts/roundtrip_dosbox.sh index 59d12cf..6ffcb2b 100755 --- a/tests/scripts/roundtrip_dosbox.sh +++ b/tests/scripts/roundtrip_dosbox.sh @@ -1,11 +1,11 @@ #!/bin/bash # Cross-tool round-trip test: original UC2 Pro -> UC2 v3 via DOSBox-X # -# Tests that archives created by the original 1992 UC2 Pro can be correctly -# extracted by UC2 v3 (Direction 2). Single-file UC2 v3 archives are also -# readable by the original, but multi-file archives still hang — the exact -# cause is under investigation (treegen + cdir encoding match the original -# for single-file cdirs but diverge for multi-file cdirs). +# Tests both directions: UC2 v3 creates a multi-file archive that the +# original extracts (Direction 1), and the original creates an archive +# that UC2 v3 extracts (Direction 2). Multi-file Direction 1 has worked +# since the custom-Huffman-tree fix; an earlier version of this comment +# documented a hang that no longer reproduces. # # Usage: roundtrip_dosbox.sh