diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | changelog | 30 | ||||
-rw-r--r-- | hadori.C | 30 | ||||
-rw-r--r-- | hadori.help2man | 13 | ||||
-rw-r--r-- | version.h | 2 |
6 files changed, 66 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..749f85d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/hadori +/hadori.o +/hadori.1 @@ -22,8 +22,8 @@ CPPFLAGS+=-D_FILE_OFFSET_BITS=64 all: hadori.1 -hadori.1: hadori - help2man -n $< -o $@ -N ./$< +%.1: %.help2man % + help2man -i $< -o $@ -N -L C.UTF-8 $(*D)/$(*F) hadori: hadori.o hadori.o: hadori.C version.h @@ -1,3 +1,33 @@ +commit 36dbc5d061b39b22f2620ac0e0a137ea05dbad33 +Author: Timo Weingärtner <timo@tiwe.de> +Date: 2021-01-13 23:53:07 +0100 + + improve man page generation with help2man + +commit 2cad5033359975238cbb95824595b638892bc039 +Author: Timo Weingärtner <timo@tiwe.de> +Date: 2018-10-27 21:37:40 +0200 + + move dry-run checking into do_link + +commit 07d402e83fd6b58d53825441169503cc92fd71d6 +Author: Ben Wiederhake <BenWiederhake.GitHub@gmx.de> +Date: 2017-06-20 10:58:54 +0200 + + Clang lints ('static' and typing) + +commit ce1d8ee5bd88cc05c6e0cdee4517bb1ab8fb6100 +Author: Ben Wiederhake <BenWiederhake.GitHub@gmx.de> +Date: 2017-06-20 10:57:28 +0200 + + Add .gitignore + +commit a987b5383931dd4735a3f7e2261e9a809543b22a (tag: 1.0) +Author: Timo Weingärtner <timo@tiwe.de> +Date: 2017-04-30 12:45:05 +0200 + + release 1.0 + commit 75293a34994df27b84ee30d94b8db625b0ca40ea Author: Timo Weingärtner <timo@tiwe.de> Date: 2014-11-23 01:06:29 +0100 @@ -40,8 +40,8 @@ namespace po = boost::program_options; #include "version.h" -po::variables_map config; -std::ostream debug(std::clog.rdbuf()), verbose(std::clog.rdbuf()), error(std::clog.rdbuf()); +static po::variables_map config; +static std::ostream debug(std::clog.rdbuf()), verbose(std::clog.rdbuf()), error(std::clog.rdbuf()); struct inode { std::string const filename; @@ -59,7 +59,7 @@ inline bool compare (inode const & l, inode const & r) { rf.read(rbuffer, sizeof(rbuffer)); if (lf.gcount() != rf.gcount()) return false; - if (memcmp(lbuffer, rbuffer, lf.gcount())) + if (memcmp(lbuffer, rbuffer, static_cast<size_t>(lf.gcount()))) return false; } return true; @@ -70,7 +70,9 @@ inline std::ostream& operator<< (std::ostream& os, inode const & i) { return os; } -void do_link (inode const & i, std::string const & other) { +static void do_link (inode const & i, std::string const & other) { + if (config.count("dry-run")) + return; if (!link(i.filename.c_str(), other.c_str())) { error << "linking " << i << " to " << other << " succeeded before unlinking (race condition)" << std::endl; exit(EX_UNAVAILABLE); @@ -92,7 +94,7 @@ void do_link (inode const & i, std::string const & other) { } } -void handle_file(std::string const & path, struct stat const & s) { +static void handle_file (std::string const & path, struct stat const & s) { static std::unordered_map<ino_t, inode const> kept; static std::unordered_map<ino_t, ino_t const> to_link; static std::unordered_multimap<off_t, ino_t const> sizes; @@ -129,8 +131,7 @@ void handle_file(std::string const & path, struct stat const & s) { verbose << "linking " << candidate << " to " << path << std::endl; if (s.st_nlink > 1) to_link.insert({s.st_ino, it.second}); - if (not config.count("dry-run")) - do_link(candidate, path); + do_link(candidate, path); return; } debug << "we keep " << f << std::endl; @@ -138,7 +139,7 @@ void handle_file(std::string const & path, struct stat const & s) { sizes.insert({s.st_size, s.st_ino}); } -void recurse (std::string const & dir, dev_t const dev) { +static void recurse (std::string const & dir, dev_t const dev) { DIR* D; struct dirent *d; struct stat s; @@ -179,7 +180,7 @@ void recurse (std::string const & dir, dev_t const dev) { } } -void recurse_start (std::string const & dir) { +static void recurse_start (std::string const & dir) { struct stat s; if (lstat(dir.c_str(), &s)) { @@ -201,7 +202,7 @@ void recurse_start (std::string const & dir) { } int main (int const argc, char const * const * const argv) { - po::options_description opts("OPTIONS"); + po::options_description opts("Options"); opts.add_options() ("help,h", "print this help message") ("version,V", "print version information") @@ -223,13 +224,16 @@ int main (int const argc, char const * const * const argv) { po::notify(config); if (config.count("help")) { - std::cout << "Invocation: hadori [ OPTIONS ] [ ARGUMENTS ]" << std::endl; - std::cout << opts << std::endl; + std::cout << "Usage: hadori [ OPTIONS ] [ ARGUMENTS ]\n"; + std::cout << opts; return EX_OK; } if (config.count("version")) { - std::cout << HADORI_VERSION << std::endl; + std::cout << HADORI_VERSION "\n"; + std::cout << "Written by Timo Weingärtner.\n"; + std::cout << "Report bugs to the Debian BTS at https://bugs.debian.org/\n"; + std::cout << "or by mail to timo@tiwe.de.\n"; return EX_OK; } diff --git a/hadori.help2man b/hadori.help2man new file mode 100644 index 0000000..859dd2f --- /dev/null +++ b/hadori.help2man @@ -0,0 +1,13 @@ +# roff markup for the list generated using "pandoc -t man" and pasted here +[NAME] +hadori \- hardlink identical files +[DESCRIPTION] +This might look like yet another hardlinking tool, but it is the only one which only memorizes one filename per inode. That results in less memory consumption and faster execution compared to its +alternatives. Therefore (and because all the other names are already taken) it's called "HArdlinking DOne RIght". + +Advantages over other hardlinking tools: +.IP \[bu] 2 +predictability: arguments are scanned in order, each first version is +kept +.IP \[bu] 2 +much lower CPU and memory consumption @@ -1 +1 @@ -#define HADORI_VERSION "hadori 0.2" +#define HADORI_VERSION "hadori 1.1" |