.gear/rhash.spec | 119 +++++++++++++++++++++ .gear/rules | 3 + .../tags/e26e4e1cc7e73c3342f24bfab5ba84f773a29fa1 | 22 ++++ .gear/tags/list | 1 + ChangeLog | 6 ++ Makefile | 10 +- bindings/perl/META.json | 2 +- bindings/perl/META.yml | 2 +- bindings/perl/Rhash.pm | 2 +- calc_sums.c | 2 - common_func.c | 43 +++++++- common_func.h | 10 +- hash_print.c | 35 +++++- librhash/Makefile | 106 +++++++++--------- librhash/byte_order.h | 4 - librhash/config.h | 2 - parse_cmdline.c | 23 ++-- rhash_main.c | 15 +-- tests/test_rhash.sh | 63 +++++++++-- win_utils.c | 38 +++---- 20 files changed, 387 insertions(+), 121 deletions(-) diff --git a/.gear/rhash.spec b/.gear/rhash.spec new file mode 100644 index 0000000..184a653 --- /dev/null +++ b/.gear/rhash.spec @@ -0,0 +1,119 @@ +%def_disable static +Summary: Utility for computing hash sums and creating magnet links. +Name: rhash +Version: 1.3.5 +Release: alt3 +License: MIT +Group: File tools +URL: http://rhash.sourceforge.net/ +Source: %name-%version.tar +Patch: %name-%version.patch +BuildRequires: gcc libssl-devel + +%description +RHash is a console utility for calculation and verification of magnet links +and a wide range of hash sums like CRC32, MD4, MD5, SHA1, SHA256, SHA512, +AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, +HAS-160, EDON-R, Whirlpool and Snefru. +Hash sums are used to ensure and verify integrity of large volumes of data +for a long-term storing or transferring. + +Features: + * Output in a predefined (SFV, BSD-like) or a user-defined format. + * Calculation of Magnet links and EDonkey 2000 links. + * Updating hash files (adding hash sums of files missing in the hash file). + * Ability to process directories recursively. + * Portability: the program works the same on Linux, *BSD or Windows. + +# LibRHash shared library, contains librhash.so.[major] only +%package -n lib%name +Summary: LibRHash shared library +Group: System/Libraries + +%description -n lib%name +LibRHash is a professional, portable, thread-safe C library for computing +a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, +AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160 +HAS-160, EDON-R, Whirlpool and Snefru. +Hash sums are used to ensure and verify integrity of large volumes of data +for a long-term storing or transferring. + +%package -n lib%name-devel +Summary: Headers and shared library for LibRHash +Group: Development/C +Requires: lib%name = %version-%release + +%description -n lib%name-devel +LibRHash is a professional, portable, thread-safe C library for computing +a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, +AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160 +HAS-160, EDON-R, Whirlpool and Snefru. +Hash sums are used to ensure and verify integrity of large volumes of data +for a long-term storing or transferring. + +%package -n lib%name-devel-static +Summary: Static library for LibRHash +Group: Development/C +Requires: lib%name-devel = %version-%release + +%description -n lib%name-devel-static +LibRHash is a professional, portable, thread-safe C library for computing +a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, +AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160 +HAS-160, EDON-R, Whirlpool and Snefru. +Hash sums are used to ensure and verify integrity of large volumes of data +for a long-term storing or transferring. + +%prep +%setup +%patch -p1 + +%build +make CFLAGS="$RPM_OPT_FLAGS -DNDEBUG -DUSE_OPENSSL -DOPENSSL_RUNTIME -rdynamic" LDFLAGS=-ldl lib-shared build-shared all + +%check +make test-shared + +%install +make PREFIX=%_prefix DESTDIR="%buildroot" MANDIR="%_mandir" LIBDIR="%_libdir" install install-lib-static install-lib-shared install-shared-binary +make PREFIX=%_prefix DESTDIR="%buildroot" MANDIR="%_mandir" LIBDIR="%_libdir" -C librhash install-so-link install-headers + +%if_disabled static +rm -v %buildroot%_libdir/librhash.a +%endif + +%files +%_bindir/* +%config %_sysconfdir/rhashrc +%_man1dir/* + +%files -n lib%name-devel +%_libdir/librhash.so +%_includedir/*.h + +%if_enabled static +%files -n lib%name-devel-static +%_libdir/librhash.a +%endif + +%files -n lib%name +%doc COPYING README ChangeLog +%_libdir/librhash.so.* + +%changelog +* Thu Sep 30 2021 Vitaly Lipatov 1.3.5-alt3 +- NMU: disable build devel-static subpackage + +* Mon Sep 11 2017 Alexey Shabalin 1.3.5-alt2 +- fix requires for static package + +* Mon Sep 11 2017 Alexey Shabalin 1.3.5-alt1 +- 1.3.5 +- add static library package + +* Wed Jul 31 2013 Evgeny Sinelnikov 1.2.10-alt1 +- Initial Sisyphus release based on original specfile by Aleksey Kravchenko + from Novosibirsk, Animegorodok last build for mdk in 14 September 2011 + + Upstream git repository^ git://github.com/rhash/RHash.git + + Author contact: Aleksey + diff --git a/.gear/rules b/.gear/rules new file mode 100644 index 0000000..027cc83 --- /dev/null +++ b/.gear/rules @@ -0,0 +1,3 @@ +spec: .gear/rhash.spec +tar: v@version@:. +diff: v@version@:. . name=@name@-@version@.patch diff --git a/.gear/tags/e26e4e1cc7e73c3342f24bfab5ba84f773a29fa1 b/.gear/tags/e26e4e1cc7e73c3342f24bfab5ba84f773a29fa1 new file mode 100644 index 0000000..a2a2c9a --- /dev/null +++ b/.gear/tags/e26e4e1cc7e73c3342f24bfab5ba84f773a29fa1 @@ -0,0 +1,22 @@ +object db0808d99a4f9ab0e7668c5638fcef5d9952bd57 +type commit +tag v1.3.5 +tagger Aleksey 1502676584 +0300 + +RHash v1.3.5 +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEKHX2scLSek8MivYLKnFEl+NzY64FAlmRBnkACgkQKnFEl+Nz +Y67vgw//SucDBxT/KZwqF03d3PtkxcxsC8yjw6CPnaBsUWAdkVEp1tS7vIwSwpf0 +fE6PuowkWdaczTCczUBnZtTnGJqn3EcaMc86sVU5uCojmox2dfCokAhTXbbLH5ZI +8smbe5CKOZhWKlG25rZuiG2Lp7nOLlsCjpW22FWdXMFAyu8prFKV+B0bKw9JIAYm +yU8gZmc4jt+GXsbb4CfnZZqGfbZPUOXOtJM3sZLoSbgS7v7UdL0KkDpd8xXFSj8r +HsaBi/9+J30ptxJ80vQtCACHagJz5a0v1waNVVWm0ZQtWiOQf3TdDD1QTXQyZTc2 +GFYyCUVeS36IFbgLqDVmifRwi7R/eWiMOiMxqX6lOdZviNDcEHWOU/exbX5VJRF0 +ZrNbL/tzJRSQvI1t3RaISdInlEG/UTGHEzXyqKgDhPSnVW3bjFS6hyC6vgo0q15K +vGgJJCGwBFJZQ/BAL07Z6jgBH3FSZzKsv5EVyEjccaYZ11vOsOfVUiX1NpOtr5gA +DFd/MUth/ZYX2VZyZjMt8cFNk6udEogV15/PJAV9piUwRdFgoerdQ7P1s8A5dial +mFJNzHx9xAKmBRMbWfsUt7oGf/GxHg5r2MSd4CoIH0M2VQBLfU0ZELOXqUy9F9Pi +8vZuS52mJnlfcedz4mNgR9cH6nLklpf3XwsJx/WUhOklT88aEuk= +=TqnI +-----END PGP SIGNATURE----- diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 0000000..2b48397 --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1 @@ +e26e4e1cc7e73c3342f24bfab5ba84f773a29fa1 v1.3.5 diff --git a/ChangeLog b/ChangeLog index 365d33a..86ccf1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Sep 4 2017 Aleksey + * Bugfix: broken binary hash output + +Mon Aug 28 2017 Aleksey + * Bugfix: fix running on WinXP + Mon Aug 14 2017 Aleksey * === Version 1.3.5 === * look for locales directory at PROGRAM_DIRECTORY\locale on Windows diff --git a/Makefile b/Makefile index 69245fb..9a3932c 100644 --- a/Makefile +++ b/Makefile @@ -50,10 +50,10 @@ LIBRHASH_FILES = librhash/algorithms.c librhash/algorithms.h \ librhash/tiger_sbox.c librhash/tth.c librhash/tth.h librhash/whirlpool.c \ librhash/whirlpool.h librhash/whirlpool_sbox.c librhash/test_hashes.c \ librhash/test_hashes.h librhash/torrent.h librhash/torrent.c librhash/ustd.h \ - librhash/util.h librhash/config.h librhash/Makefile -I18N_FILES = po/de.po po/en_AU.po po/es.po po/gl.po po/it.po po/ru.po + librhash/util.h librhash/Makefile +I18N_FILES = po/ca.po po/de.po po/en_AU.po po/es.po po/fr.po po/gl.po po/it.po po/ro.po po/ru.po DIST_FILES = $(LIN_DIST_FILES) $(LIBRHASH_FILES) $(WIN_DIST_FILES) $(WIN_SRC_FILES) $(I18N_FILES) -DESTDIR = +DESTDIR = BINDIR = $(PREFIX)/bin MANDIR = $(PREFIX)/share/man LOCALEDIR = $(PREFIX)/share/locale @@ -159,9 +159,9 @@ test-static: $(TARGET) chmod +x tests/test_rhash.sh tests/test_rhash.sh -test-shared: $(SHARED_TRG) test-shared-lib +test-shared: $(SHARED_TRG) chmod +x tests/test_rhash.sh - LD_LIBRARY_PATH=../librhash:$(LD_LIBRARY_PATH) tests/test_rhash.sh ./$(SHARED_TRG) + tests/test_rhash.sh --shared ./$(SHARED_TRG) version.h: Makefile echo "#define VERSION \"$(VERSION)\"" > version.h diff --git a/bindings/perl/META.json b/bindings/perl/META.json index 7883f60..64a9f9a 100644 --- a/bindings/perl/META.json +++ b/bindings/perl/META.json @@ -47,5 +47,5 @@ "url" : "https://github.com/rhash/RHash" } }, - "version" : "0.93" + "version" : "0.94" } diff --git a/bindings/perl/META.yml b/bindings/perl/META.yml index ce42821..3817166 100644 --- a/bindings/perl/META.yml +++ b/bindings/perl/META.yml @@ -23,4 +23,4 @@ resources: homepage: http://rhash.sf.net/ license: http://rhash.anz.ru/license.php repository: https://github.com/rhash/RHash -version: 0.93 +version: 0.94 diff --git a/bindings/perl/Rhash.pm b/bindings/perl/Rhash.pm index c322c61..d2a1799 100644 --- a/bindings/perl/Rhash.pm +++ b/bindings/perl/Rhash.pm @@ -21,7 +21,7 @@ our %EXPORT_TAGS = ( Exporter::export_tags( ); Exporter::export_ok_tags( qw(Functions Constants) ); -our $VERSION = '0.93'; +our $VERSION = '0.94'; require XSLoader; XSLoader::load('Crypt::Rhash', $VERSION); diff --git a/calc_sums.c b/calc_sums.c index 5473486..06205c5 100644 --- a/calc_sums.c +++ b/calc_sums.c @@ -431,12 +431,10 @@ int calculate_and_print_sums(FILE* out, file_t* file, const char *print_path) if (rhash_data.print_list && res >= 0) { if (!opt.bt_batch_file) { print_line(out, rhash_data.print_list, &info); - fflush(out); /* print calculated line to stderr or log-file if verbose */ if ((opt.mode & MODE_UPDATE) && (opt.flags & OPT_VERBOSE)) { print_line(rhash_data.log, rhash_data.print_list, &info); - fflush(rhash_data.log); } } diff --git a/common_func.c b/common_func.c index f1f29a3..49ec00f 100644 --- a/common_func.c +++ b/common_func.c @@ -558,14 +558,50 @@ int if_file_exists(const char* path) * Custom program exit function *=========================================================================*/ +struct rhash_exit_handlers_t +{ + unsigned handlers_count; + exit_handler_t handlers[4]; +} rhash_exit_handlers = { 0 }; + +/** +* Install a handler to be called on program exit. +* +* @param handler the hadler to add +*/ +void rsh_install_exit_handler(exit_handler_t handler) +{ + if (rhash_exit_handlers.handlers_count >= (sizeof(rhash_exit_handlers.handlers) / sizeof(rhash_exit_handlers.handlers[0]))) + { + assert(!"to many handlers"); + rsh_exit(2); + } + rhash_exit_handlers.handlers[rhash_exit_handlers.handlers_count] = handler; + rhash_exit_handlers.handlers_count++; +} + +/** +* Remove the last installed exit handler. +*/ +void rsh_remove_exit_handler(void) +{ + if (rhash_exit_handlers.handlers_count == 0) + { + assert(rhash_exit_handlers.handlers_count > 0 && "no handlers installed"); + rsh_exit(2); + } + rhash_exit_handlers.handlers_count--; +} + /** -* Exit the program, with restoring console state. +* Call all installed exit handlers, starting from the latest one, and exit the program. * * @param code the program exit code */ -void rhash_exit(int code) +void rsh_exit(int code) { - IF_WINDOWS(restore_console()); + while (rhash_exit_handlers.handlers_count > 0) + rhash_exit_handlers.handlers[--rhash_exit_handlers.handlers_count](); exit(code); } @@ -576,7 +612,6 @@ void rhash_exit(int code) static void report_error_default(const char* srcfile, int srcline, const char* format, ...); -void (*rsh_exit)(int code) = exit; void (*rsh_report_error)(const char* srcfile, int srcline, const char* format, ...) = report_error_default; diff --git a/common_func.h b/common_func.h index a857b87..455d1b8 100644 --- a/common_func.h +++ b/common_func.h @@ -168,9 +168,11 @@ double rsh_timer_stop(timedelta_t* timer); */ unsigned rhash_get_ticks(void); - -void rhash_exit(int code); - +/* program exit handlers */ +typedef void (*exit_handler_t)(void); +void rsh_install_exit_handler(exit_handler_t handler); +void rsh_remove_exit_handler(void); +void rsh_exit(int code); /* clever malloc with error detection */ #define rsh_malloc(size) rhash_malloc(size, __FILE__, __LINE__) @@ -187,8 +189,6 @@ void* rhash_realloc(void* mem, size_t size, const char* srcfile, int srcline); wchar_t* rhash_wcsdup(const wchar_t* str, const char* srcfile, int srcline); #endif - -extern void (*rsh_exit)(int code); extern void (*rsh_report_error)(const char* srcfile, int srcline, const char* format, ...); /* vector functions */ diff --git a/hash_print.c b/hash_print.c index dd965ef..5cd8f1b 100644 --- a/hash_print.c +++ b/hash_print.c @@ -7,6 +7,11 @@ #include #include +#ifdef _WIN32 +#include +#include +#endif /* _WIN32 */ + #include "librhash/rhash.h" #include "calc_sums.h" #include "parse_cmdline.h" @@ -37,6 +42,7 @@ enum { | PRINT_FLAG_HEX | PRINT_FLAG_BASE32 | PRINT_FLAG_BASE64, PRINT_STR = 0x10000000, PRINT_ZERO, + PRINT_NEWLINE, PRINT_FILEPATH, PRINT_BASENAME, PRINT_URLNAME, @@ -77,6 +83,7 @@ static char parse_escaped_char(const char **pformat) { const char* start = *pformat; switch ( *((*pformat)++) ) { + case '0': return '\0'; case 't': return '\t'; case 'r': return '\r'; case 'n': return '\n'; @@ -92,7 +99,7 @@ static char parse_escaped_char(const char **pformat) ch = 16 * ch + (**pformat <= '9' ? **pformat & 15 : (**pformat + 9) & 15); (*pformat)++; } - if (ch) return ch; + return ch; } break; default: @@ -131,11 +138,16 @@ print_item* parse_print_string(const char* format, unsigned *sum_mask) *(p++) = *(format++); if (*format == '\\') { - if (*(++format) == '0') { + format++; + *p = parse_escaped_char(&format); + if (*p == '\0') { item = new_print_item(PRINT_ZERO, 0, NULL); - format++; +#ifdef _WIN32 + } else if (*p == '\n') { + item = new_print_item(PRINT_NEWLINE, 0, NULL); +#endif } else { - *p++ = parse_escaped_char(&format); + p++; continue; } } else if (*format == '%') { @@ -402,6 +414,11 @@ void print_line(FILE* out, print_item* list, struct file_info *info) const char* basename = get_basename(info->print_path), *tmp; char *url = NULL, *ed2k_url = NULL; char buffer[130]; +#ifdef _WIN32 + /* switch to binary mode to correctly output binary hashes */ + int out_fd = _fileno(out); + int old_mode = (out_fd > 0 && !isatty(out_fd) ? _setmode(out_fd, _O_BINARY) : -1); +#endif for (; list; list = list->next) { int print_type = list->flags & ~(PRINT_FLAGS_ALL); @@ -434,6 +451,11 @@ void print_line(FILE* out, print_item* list, struct file_info *info) case PRINT_ZERO: /* the '\0' character */ rsh_fprintf(out, "%c", 0); break; +#ifdef _WIN32 + case PRINT_NEWLINE: + rsh_fprintf(out, "%s", "\r\n"); + break; +#endif case PRINT_FILEPATH: rsh_fprintf(out, "%s", info->print_path); break; @@ -461,6 +483,11 @@ void print_line(FILE* out, print_item* list, struct file_info *info) } free(url); free(ed2k_url); + fflush(out); +#ifdef _WIN32 + if (old_mode >= 0) + _setmode(out_fd, old_mode); +#endif } /** diff --git a/librhash/Makefile b/librhash/Makefile index 298fa9d..1dcac6f 100644 --- a/librhash/Makefile +++ b/librhash/Makefile @@ -9,8 +9,7 @@ LDFLAGS = $(OPTLDFLAGS) ADDCFLAGS = LIBCFLAGS = ADDLDFLAGS = -DEFS = -DIN_RHASH -PRGCFLAGS = -pipe $(DEFS) $(ADDCFLAGS) $(CFLAGS) \ +PRGCFLAGS = -pipe $(ADDCFLAGS) $(CFLAGS) \ -Wall -W -Wstrict-prototypes -Wnested-externs -Winline -Wpointer-arith \ -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations ALLCFLAGS = $(LIBCFLAGS) $(PRGCFLAGS) @@ -35,6 +34,7 @@ DYLINK = librhash.dylib DLLNAME = librhash.dll TEST_TARGET = test_hashes TEST_SHARED = test_shared +TEST_DYLIB = test_dylib # Set variables according to GNU coding standard INSTALL = install INSTALL_DATA = $(INSTALL) -m 644 @@ -81,102 +81,111 @@ uninstall-headers: #%.o: %.c # $(CC) -c $(ALLCFLAGS) $< -o $@ -# NOTE: dependences were generated by 'gcc -MM -DIN_RHASH -DUSE_OPENSSL *.c' +# NOTE: dependences were generated by 'gcc -MM -DUSE_OPENSSL *.c' # we are using plain old makefile style to support BSD make -aich.o: aich.c byte_order.h ustd.h config.h algorithms.h rhash.h aich.h \ - sha1.h +aich.o: aich.c byte_order.h ustd.h algorithms.h rhash.h aich.h sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ -algorithms.o: algorithms.c byte_order.h ustd.h config.h rhash.h \ - algorithms.h aich.h sha1.h crc32.h ed2k.h md4.h edonr.h gost.h has160.h \ - md5.h ripemd-160.h snefru.h sha256.h sha512.h sha3.h tiger.h torrent.h \ - tth.h whirlpool.h +algorithms.o: algorithms.c byte_order.h ustd.h rhash.h algorithms.h \ + aich.h sha1.h crc32.h ed2k.h md4.h edonr.h gost.h has160.h md5.h \ + ripemd-160.h snefru.h sha256.h sha512.h sha3.h tiger.h torrent.h tth.h \ + whirlpool.h $(CC) -c $(ALLCFLAGS) $< -o $@ -byte_order.o: byte_order.c byte_order.h ustd.h config.h +byte_order.o: byte_order.c byte_order.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ -crc32.o: crc32.c byte_order.h ustd.h config.h crc32.h +crc32.o: crc32.c byte_order.h ustd.h crc32.h $(CC) -c $(ALLCFLAGS) $< -o $@ ed2k.o: ed2k.c ed2k.h md4.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ -edonr.o: edonr.c byte_order.h ustd.h config.h edonr.h +edonr.o: edonr.c byte_order.h ustd.h edonr.h $(CC) -c $(ALLCFLAGS) $< -o $@ -gost.o: gost.c byte_order.h ustd.h config.h gost.h +gost.o: gost.c byte_order.h ustd.h gost.h $(CC) -c $(ALLCFLAGS) $< -o $@ -has160.o: has160.c byte_order.h ustd.h config.h has160.h +has160.o: has160.c byte_order.h ustd.h has160.h $(CC) -c $(ALLCFLAGS) $< -o $@ hex.o: hex.c hex.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ -md4.o: md4.c byte_order.h ustd.h config.h md4.h +md4.o: md4.c byte_order.h ustd.h md4.h $(CC) -c $(ALLCFLAGS) $< -o $@ -md5.o: md5.c byte_order.h ustd.h config.h md5.h +md5.o: md5.c byte_order.h ustd.h md5.h $(CC) -c $(ALLCFLAGS) $< -o $@ plug_openssl.o: plug_openssl.c algorithms.h rhash.h byte_order.h ustd.h \ - config.h plug_openssl.h + plug_openssl.h $(CC) -c $(ALLCFLAGS) $< -o $@ -rhash.o: rhash.c byte_order.h ustd.h config.h algorithms.h rhash.h \ - torrent.h sha1.h plug_openssl.h util.h hex.h +rhash.o: rhash.c byte_order.h ustd.h algorithms.h rhash.h torrent.h \ + sha1.h plug_openssl.h util.h hex.h $(CC) -c $(ALLCFLAGS) $< -o $@ -rhash_timing.o: rhash_timing.c byte_order.h ustd.h config.h rhash.h \ - rhash_timing.h +rhash_timing.o: rhash_timing.c byte_order.h ustd.h rhash.h rhash_timing.h $(CC) -c $(ALLCFLAGS) $< -o $@ rhash_torrent.o: rhash_torrent.c algorithms.h rhash.h byte_order.h ustd.h \ - config.h torrent.h sha1.h rhash_torrent.h + torrent.h sha1.h rhash_torrent.h $(CC) -c $(ALLCFLAGS) $< -o $@ -ripemd-160.o: ripemd-160.c byte_order.h ustd.h config.h ripemd-160.h +ripemd-160.o: ripemd-160.c byte_order.h ustd.h ripemd-160.h $(CC) -c $(ALLCFLAGS) $< -o $@ -sha1.o: sha1.c byte_order.h ustd.h config.h sha1.h +sha1.o: sha1.c byte_order.h ustd.h sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ -sha256.o: sha256.c byte_order.h ustd.h config.h sha256.h +sha256.o: sha256.c byte_order.h ustd.h sha256.h $(CC) -c $(ALLCFLAGS) $< -o $@ -sha512.o: sha512.c byte_order.h ustd.h config.h sha512.h +sha3.o: sha3.c byte_order.h ustd.h sha3.h $(CC) -c $(ALLCFLAGS) $< -o $@ -sha3.o: sha3.c byte_order.h ustd.h config.h sha3.h +sha512.o: sha512.c byte_order.h ustd.h sha512.h $(CC) -c $(ALLCFLAGS) $< -o $@ -snefru.o: snefru.c byte_order.h ustd.h config.h snefru.h +snefru.o: snefru.c byte_order.h ustd.h snefru.h $(CC) -c $(ALLCFLAGS) $< -o $@ -test_hashes.o: test_hashes.c byte_order.h ustd.h config.h rhash_timing.h \ +test_hashes.o: test_hashes.c byte_order.h ustd.h rhash_timing.h \ rhash_torrent.h rhash.h test_hashes.h $(CC) -c $(ALLCFLAGS) $< -o $@ -tiger.o: tiger.c byte_order.h ustd.h config.h tiger.h +tiger.o: tiger.c byte_order.h ustd.h tiger.h $(CC) -c $(ALLCFLAGS) $< -o $@ -tiger_sbox.o: tiger_sbox.c byte_order.h ustd.h config.h +tiger_sbox.o: tiger_sbox.c byte_order.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ -torrent.o: torrent.c byte_order.h ustd.h config.h algorithms.h rhash.h \ - hex.h torrent.h sha1.h +torrent.o: torrent.c byte_order.h ustd.h algorithms.h rhash.h hex.h \ + torrent.h sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ -tth.o: tth.c byte_order.h ustd.h config.h tth.h tiger.h +tth.o: tth.c byte_order.h ustd.h tth.h tiger.h $(CC) -c $(ALLCFLAGS) $< -o $@ -whirlpool.o: whirlpool.c byte_order.h ustd.h config.h whirlpool.h +whirlpool.o: whirlpool.c byte_order.h ustd.h whirlpool.h $(CC) -c $(ALLCFLAGS) $< -o $@ -whirlpool_sbox.o: whirlpool_sbox.c byte_order.h ustd.h config.h +whirlpool_sbox.o: whirlpool_sbox.c byte_order.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ +# build shared library +$(SONAME): $(SOURCES) + sed -n '1s/.*/{ global:/p; s/^RHASH_API.* \([a-z0-9_]\+\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(SO_HEADERS) > exports.sym + $(CC) -fpic $(ALLCFLAGS) -shared $(SOURCES) -Wl,--version-script,exports.sym,-soname,$(SONAME) $(LIBLDFLAGS) -o $@ + rm -f $(SOLINK) + ln -s $(SONAME) $(SOLINK) + +test-shared: $(SONAME) test_hashes.o + $(CC) $(PRGCFLAGS) test_hashes.o $(SONAME) $(LIBLDFLAGS) -o $(TEST_SHARED) + LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(TEST_SHARED) + # MINGW: build a dll library $(DLLNAME): $(SOURCES) sed -n '1s/.*/{ global:/p; s/^RHASH_API.* \([a-z0-9_]\+\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(LIB_HEADERS) > exports.sym @@ -185,29 +194,23 @@ $(DLLNAME): $(SOURCES) test-dll: $(DLLNAME) test_hashes.o $(CC) $(PRGCFLAGS) test_hashes.o $(DLLNAME) -o $(TEST_SHARED) && ./$(TEST_SHARED) -# shared and static libraries -$(SONAME): $(SOURCES) - sed -n '1s/.*/{ global:/p; s/^RHASH_API.* \([a-z0-9_]\+\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(SO_HEADERS) > exports.sym - $(CC) -fpic $(ALLCFLAGS) -shared $(SOURCES) -Wl,--version-script,exports.sym,-soname,$(SONAME) $(LIBLDFLAGS) -o $@ - rm -f $(SOLINK) - ln -s $(SONAME) $(SOLINK) -# use 'nm -Cg --defined-only $@' to view exported symbols - +# build osx shared library $(DYNAME): $(SOURCES) $(CC) -fpic $(ALLCFLAGS) -dynamiclib $(SOURCES) $(LIBLDFLAGS) -Wl,-install_name,$(LIBDIR)/$@ -o $@ rm -f $(DYLINK) ln -s $(DYNAME) $(DYLINK) +test-dylib: $(DYNAME) test_hashes.o + $(CC) $(PRGCFLAGS) test_hashes.o $(DYNAME) $(LIBLDFLAGS) -o $(TEST_DYLIB) + DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(TEST_DYLIB) + +# build static library $(LIBRARY): $(OBJECTS) $(AR) cqs $@ $(OBJECTS) $(TEST_TARGET): $(LIBRARY) test_hashes.o $(CC) $(ALLCFLAGS) test_hashes.o $(LIBRARY) $(LIBLDFLAGS) -o $@ -test-shared: $(SONAME) test_hashes.o - $(CC) $(PRGCFLAGS) test_hashes.o $(SONAME) $(LIBLDFLAGS) -o $(TEST_SHARED) - LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(TEST_SHARED) - test-static: $(TEST_TARGET) ./$(TEST_TARGET) @@ -215,4 +218,9 @@ test: test-static if [ -f $(SONAME) ]; then make test-shared; fi clean: - rm -f *.o $(LIBRARY) $(TEST_TARGET) $(TEST_SHARED) $(SONAME) $(SOLINK) exports.sym $(DLLNAME) librhash.def + rm -f *.o $(LIBRARY) $(TEST_TARGET) $(TEST_SHARED) $(SONAME) $(SOLINK) exports.sym $(DLLNAME) librhash.def $(DYNAME) $(DYLINK) $(TEST_DYLIB) + +.PHONY: all clean dist-clean dll dylib install-headers install-lib-shared \ + install-lib-static install-so-link libs-all lib-shared lib-static \ + test test-dll test-dylib test-shared test-static uninstall-headers \ + uninstall-lib uninstall-lib-shared uninstall-lib-static uninstall-so-link diff --git a/librhash/byte_order.h b/librhash/byte_order.h index 5053e36..4085f0e 100644 --- a/librhash/byte_order.h +++ b/librhash/byte_order.h @@ -4,10 +4,6 @@ #include "ustd.h" #include -#ifdef IN_RHASH -#include "config.h" -#endif - #ifdef __GLIBC__ # include #endif diff --git a/librhash/config.h b/librhash/config.h deleted file mode 100644 index ee0089a..0000000 --- a/librhash/config.h +++ /dev/null @@ -1,2 +0,0 @@ -/* config.h */ -/*#define OPENSSL_RUNTIME*/ diff --git a/parse_cmdline.c b/parse_cmdline.c index dfd2531..443de0f 100644 --- a/parse_cmdline.c +++ b/parse_cmdline.c @@ -991,6 +991,17 @@ static void make_final_options_checks(void) if (opt.openssl_mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, 0, opt.openssl_mask, 0); } +static struct parsed_cmd_line_t cmd_line; + +static void cmd_line_destroy(void) +{ + rsh_blocks_vector_destroy(&cmd_line.options); + free(cmd_line.files); +#ifdef _WIN32 + LocalFree(cmd_line.warg); +#endif +} + /** * Parse command line options. * @@ -998,8 +1009,6 @@ static void make_final_options_checks(void) */ void read_options(int argc, char *argv[]) { - struct parsed_cmd_line_t cmd_line; - opt.mem = rsh_vector_new_simple(); opt.find_max_depth = -1; @@ -1008,6 +1017,7 @@ void read_options(int argc, char *argv[]) rsh_blocks_vector_init(&cmd_line.options); cmd_line.argv = argv; cmd_line.argc = argc; + rsh_install_exit_handler(cmd_line_destroy); /* parse command line and apply encoding options */ parse_cmdline_options(&cmd_line); @@ -1020,19 +1030,14 @@ void read_options(int argc, char *argv[]) apply_cmdline_options(&cmd_line); /* process the rest of command options */ /* options were processed, so we don't need them anymore */ - rsh_blocks_vector_destroy(&cmd_line.options); /* set the files and directories to be processed later */ opt.search_data = file_search_data_new(cmd_line.files, cmd_line.n_files, opt.find_max_depth); opt.n_files = cmd_line.n_files; - free(cmd_line.files); - -#ifdef _WIN32 - LocalFree(cmd_line.warg); -#endif + rsh_remove_exit_handler(); + cmd_line_destroy(); make_final_options_checks(); - set_default_sums_flags(argv[0]); /* detect default hashes from program name */ } diff --git a/rhash_main.c b/rhash_main.c index 281a40d..3daeaee 100644 --- a/rhash_main.c +++ b/rhash_main.c @@ -184,10 +184,15 @@ void rhash_destroy(struct rhash_t* ptr) if (ptr->log) fclose(ptr->log); #ifdef _WIN32 if (ptr->program_dir) free(ptr->program_dir); - IF_WINDOWS(restore_console()); #endif } +static void free_allocated_data(void) +{ + options_destroy(&opt); + rhash_destroy(&rhash_data); +} + static void i18n_initialize(void) { setlocale(LC_ALL, ""); /* set locale according to the environment */ @@ -216,6 +221,7 @@ int main(int argc, char *argv[]) memset(&opt, 0, sizeof(opt)); rhash_data.out = stdout; /* set initial output streams */ rhash_data.log = stderr; /* can be altered by options later */ + rsh_install_exit_handler(free_allocated_data); IF_WINDOWS(init_program_dir()); init_hash_info_table(); @@ -321,9 +327,6 @@ int main(int argc, char *argv[]) exit_code = (rhash_data.error_flag ? 1 : opt.search_data->errors_count ? 2 : rhash_data.interrupted ? 3 : 0); - options_destroy(&opt); - rhash_destroy(&rhash_data); - - /* return non-zero error code if error occurred */ - return exit_code; + rsh_exit(exit_code); + return 0; /* unreachable statement */ } diff --git a/tests/test_rhash.sh b/tests/test_rhash.sh index 764ffa7..196f9d8 100755 --- a/tests/test_rhash.sh +++ b/tests/test_rhash.sh @@ -1,17 +1,62 @@ #!/bin/sh +# Run RHash tests +# Usage: test_rhash.sh [ --full | --shared ] +LANG=en_US -if [ "$1" = "--full" ]; then FULL_TEST=1; shift; fi +# read options +while [ "$#" -gt 0 ]; do + case $1 in + --full) + OPT_FULL=1 + ;; + --shared) + OPT_SHARED=1 + ;; + *) + [ -x "$1" -a -z "$rhash" -a -x "$1" ] && rhash="$(cd $(dirname $1) && echo $PWD/${1##*/})" + ;; + esac + shift +done -[ -x "$1" ] && rhash="$(cd ${1%/*} && echo $PWD/${1##*/})" || rhash="../rhash"; +[ -x "$rhash" ] || rhash="../rhash"; cd $(dirname "$0") # chdir after getting absolute path of $1, but before checking for ../rhash [ -x "$rhash" ] || rhash="`which rhash`" -if [ ! -x $rhash ]; then +if [ ! -x "$rhash" ]; then echo "Fatal: $rhash not found" exit 1 fi [ "$rhash" != "../rhash" ] && echo "Testing $rhash" -#version="`$rhash -V|sed 's/^.* v//'`" +if [ -n "$OPT_SHARED" -a -d ../librhash ]; then + D=../librhash + N=$D/librhash + if [ -r $N.0.dylib ] && ( uname -s | grep -qi "^darwin" || [ ! -r $N.so.0 ] ); then + export DYLD_LIBRARY_PATH=$D:$DYLD_LIBRARY_PATH + elif [ -r $N.dll ] && ( uname -s | grep -qi "^mingw" || [ ! -r $N.so.0 ] ); then + export PATH=$D:$PATH + elif [ -r $N.so.0 ]; then + export LD_LIBRARY_PATH=$D:$LD_LIBRARY_PATH + else + echo "shared library not found at $D" + fi +fi + +# run smoke test: test exit code of a simple command +echo | $rhash --printf "" - +res=$? +if [ $res -ne 0 ]; then + if [ $res -eq 127 ]; then + echo "error: could not load dynamic libraries or execute $rhash" + elif [ $res -eq 139 ]; then + echo "error: got segmentation fault by running $rhash" + else + echo "error: obtained unexpected exit_code = $res from $rhash" + fi + exit 2 +fi + +# get the list of supported hash options HASHOPT="`$rhash --list-hashes|sed 's/ .*$//;/[^3]-/s/-\([0-9R]\)/\1/'|tr A-Z a-z`" fail_cnt=0 @@ -31,9 +76,9 @@ print_failed() { # verify obtained value $1 against the expected value $2 check() { sub_test=$((sub_test+1)) - if [ "$1" = "$2" ]; then + if [ "$1" = "$2" ]; then test "$3" = "." || echo "Ok" - else + else print_failed "$3" echo "obtained: \"$1\"" echo "expected: \"$2\"" @@ -116,8 +161,8 @@ TEST_EXPECTED="(stdin) 1 E8B7BE43 5c334qy BTAXLOOA6G3KQMODTHRGS5ZGME hvfkN/qlp/z check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test special characters: " -TEST_RESULT=$( echo | $rhash -p '\63\1\277\x0\x1\t\\ \x34\r' - ) -TEST_EXPECTED=$( printf '\63\1\277\\x0\1\t\\ 4\r' ) +TEST_RESULT=$( echo | $rhash -p '\63\1\277\x0f\x1\t\\ \x34\r' - ) +TEST_EXPECTED=$( printf '\63\1\277\17\1\t\\ 4\r' ) check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test eDonkey link: " @@ -128,7 +173,7 @@ check "$TEST_RESULT" "$TEST_EXPECTED" . TEST_RESULT=$( $rhash -L test1K.data | $rhash -vc - 2>/dev/null | grep test1K.data ) match "$TEST_RESULT" "^test1K.data *OK" -if [ "$FULL_TEST" = 1 ]; then +if [ -n "$OPT_FULL" ]; then new_test "test all hash options: " errors=0 for opt in $HASHOPT ; do diff --git a/win_utils.c b/win_utils.c index 89669c3..f5183e1 100644 --- a/win_utils.c +++ b/win_utils.c @@ -347,6 +347,21 @@ void set_benchmark_cpu_affinity(void) /* functions to setup/restore console */ +/** + * Restore console on program exit. + */ +void restore_console(void) +{ + CONSOLE_CURSOR_INFO cci; + HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE); + if (hOut != INVALID_HANDLE_VALUE && rhash_data.saved_cursor_size) { + /* restore cursor size and visibility */ + cci.dwSize = rhash_data.saved_cursor_size; + cci.bVisible = 1; + SetConsoleCursorInfo(hOut, &cci); + } +} + /** * Prepare console on program initialization: change console font codepage * according to program options and hide cursor. @@ -392,26 +407,11 @@ void setup_console(void) /* now hide cursor */ cci.bVisible = 0; SetConsoleCursorInfo(hOut, &cci); /* hide cursor */ - rsh_exit = rhash_exit; + rsh_install_exit_handler(restore_console); } } } -/** - * Restore console on program exit. - */ -void restore_console(void) -{ - CONSOLE_CURSOR_INFO cci; - HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE); - if (hOut != INVALID_HANDLE_VALUE && rhash_data.saved_cursor_size) { - /* restore cursor size and visibility */ - cci.dwSize = rhash_data.saved_cursor_size; - cci.bVisible = 1; - SetConsoleCursorInfo(hOut, &cci); - } -} - /** * Detect the program directory. */ @@ -503,11 +503,11 @@ int win_vfprintf(FILE* out, const char* format, va_list args) * can be used only from a single-thread program */ static char buffer[8192]; wchar_t *wstr = NULL; - int res = vsnprintf_s(buffer, 8192, _TRUNCATE, format, args); - if (res < 0) + int res = vsnprintf(buffer, 8192, format, args); + if (res < 0 || res >= 8192) { errno = EINVAL; - return res; + return -1; } wstr = cstr_to_wchar(buffer, CP_UTF8); res = fwprintf(out, L"%s", wstr);