Commit 2b002a52 authored by Aleksey Kravchenko's avatar Aleksey Kravchenko

Imported Upstream version 1.2.7

parent c6706f67
Sun Aug 14 2011 Aleksey
* === Version 1.2.7 ===
Sun Aug 7 2011 Aleksey
* Bugfix: percents option was broken in v1.2.6
Fri Aug 5 2011 Aleksey
* supported verification of sha256, sha512 and other hash sums
Mon Jul 11 2011 Aleksey
* librhash: rhash_cancel() macro to cancel hashing from another thread
Fri Jun 24 2011 Aleksey
* Bugfix: repaired default output encoding to be UTF-8 on Windows
Wed Jun 22 2011 Aleksey
* Bugfix: crash on WinXP
Thu Jun 16 2011 Aleksey
* === Version 1.2.6 ===
......@@ -418,7 +436,7 @@ Fri Sep 08 2006 Aleksey
Wed Apr 19 2006 Aleksey
* checking of md5/sha1 files in *BSD format supported
* improved I/O errors handling
* improved I/O errors handling
Mon Apr 10 2006 Aleksey
* === Version 0.8.3 ===
......
......@@ -2,7 +2,7 @@
Linux Installation:
===================
You need GCC (or Intel Compiler) and GNU Make.
You need GCC (or Intel Compiler) and GNU Make.
To compile and install the program just type
'make install'
......@@ -15,14 +15,14 @@ RPM package can be created by commands
To compile with openssl support use the following flags
make ADDCFLAGS="-DUSE_OPENSSL -DOPENSSL_RUNTIME -rdynamic" ADDLDFLAGS="-ldl"
The LibRHash library can be compiled using
The LibRHash static/shared library can be compiled by
'make lib-static' or 'make lib-shared'
Windows Installation:
=====================
You need MinGW compiler and MSYS enviropment.
You need MinGW compiler and MSYS environment.
To compile the program run 'make'.
Otionally you can run 'make test'.
......
This diff is collapsed.
=== RHash program ===
=== RHash program ===
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,
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
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.
* Can calculate Magnet links and EDonkey 2000 links.
* Updating hash files (adding hash sums of files missing in the hash file).
* Calculates several hash sums in one pass
* Ability to process directories recursively.
* Portability: the program works the same on Linux, *BSD or Windows.
=== The LibRHash library ===
=== The LibRHash library ===
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
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
Hash sums are used to ensure and verify integrity of large volumes of data
for a long-term storing or transferring.
Features:
......@@ -33,16 +33,26 @@ Features:
* Portability: the library works on Linux, *BSD and Windows.
=== About hash functions ===
=== Links ===
* Project Home Page: http://rhash.sourceforge.net/
* Oficial Releases: http://sf.net/projects/rhash/files/rhash/
* RHash hash functions descriptions http://rhash.anz.ru/hashes.php
* Table of the hash functions supported by RHash
https://sourceforge.net/apps/mediawiki/rhash/index.php?title=Hash_sums
* The table of the hash functions supported by RHash
http://sf.net/apps/mediawiki/rhash/index.php?title=Hash_sums
* ECRYPT: The Hash Function Zoo
http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo
=== Notes on RHash License ===
=== Getting latest source code ===
The latest source code can be obtained from Git repository by command:
git clone git://github.com/rhash/RHash.git
=== Notes on RHash License ===
The RHash program and LibRHash library are distributed under RHash License,
see the COPYING file for details. In particluar, the program, the library
......
This diff is collapsed.
......@@ -5,73 +5,44 @@
#include <stdint.h>
#include "librhash/rhash.h"
#include "common_func.h"
#include "hash_check.h"
#ifdef __cplusplus
extern "C" {
#endif
/* binary result of calculations */
typedef struct rhash_sums_t
{
unsigned flags;
union {
unsigned char digest[4];
unsigned be;
} crc32;
unsigned char md4_digest[16];
unsigned char md5_digest[16];
unsigned char ed2k_digest[16];
unsigned char sha1_digest[20];
unsigned char tiger_digest[24];
unsigned char tth_digest[24];
unsigned char aich_digest[20];
unsigned char whirlpool_digest[64];
unsigned char ripemd160_digest[20];
unsigned char gost_digest[32];
unsigned char gost_cryptopro_digest[32];
unsigned char snefru256_digest[32];
unsigned char snefru128_digest[16];
unsigned char has160_digest[20];
unsigned char btih_digest[20];
unsigned char sha224_digest[28];
unsigned char sha256_digest[32];
unsigned char sha384_digest[48];
unsigned char sha512_digest[64];
unsigned char edonr256_digest[32];
unsigned char edonr512_digest[64];
} rhash_sums_t;
#include <sys/types.h> /* struct stat */
#include <sys/stat.h> /* stat() */
/* information about currently processed file */
/**
* Information about a file to calculate/verify hashes for.
*/
struct file_info {
char* full_path;
const char* print_path;
char* utf8_print_path;
uint64_t size; /* the size of the file */
double time; /* file processing time in seconds */
struct infohash_ctx *infohash;
struct rhash_sums_t *orig_sums; /* sums from a crc file */
rhash rctx; /* state of hash algorithms */
unsigned wrong_sums; /* sum comparison results */
int error; /* -1 for i/o error, -2 for wrong sum, 0 on success */
char* allocated_ptr;
/* note: rsh_stat_struct size depends on _FILE_OFFSET_BITS */
struct rsh_stat_struct stat_buf; /* file attributes */
struct rhash_sums_t sums; /* sums of the file */
char* full_path; /* file path (in system encoding) */
const char* print_path; /* the path part to print */
char* utf8_print_path; /* file path in UTF8 */
uint64_t size; /* the size of the file */
double time; /* file processing time in seconds */
struct infohash_ctx *infohash;
rhash rctx; /* state of hash algorithms */
int error; /* -1 for i/o error, -2 for wrong sum, 0 on success */
char* allocated_ptr;
/* note: rsh_stat_struct size depends on _FILE_OFFSET_BITS */
struct rsh_stat_struct stat_buf; /* file attributes */
unsigned sums_flags; /* mask of ids of calculated hash functions */
struct hash_check hc; /* hash values parsed from a hash file */
};
void file_info_destroy(struct file_info*); /* free allocated memory */
const char* file_info_get_utf8_print_path(struct file_info*);
unsigned char* rhash_get_digest_ptr(struct rhash_sums_t *sums, unsigned hash_id);
int calculate_and_print_sums(FILE* out, const char *print_path, const char *full_path, struct rsh_stat_struct* stat_buf);
int check_crc_file(const char* crc_file_path, int chdir);
int rename_file_to_embed_crc32(struct file_info *info);
int calculate_and_print_sums(FILE* out, const char *print_path, const char *full_path, struct rsh_stat_struct* stat_buf);
int check_hash_file(const char* crc_file_path, int chdir);
int rename_file_to_embed_crc32(struct file_info *info);
void print_sfv_banner(FILE* out);
int print_sfv_header_line(FILE* out, const char* printpath, const char* fullpath);
int print_sfv_header_line(FILE* out, const char* printpath, const char* fullpath);
#ifdef __cplusplus
} /* extern "C" */
......
......@@ -14,40 +14,45 @@
#include "parse_cmdline.h"
/**
* Print a 0-terminated string representation of a 64-bit number to char buffer.
* Print a 0-terminated string representation of a 64-bit number to
* a string buffer.
*
* @param dst the string buffer to write the number to
* @param number the 64-bit number to output
* @param min_width the minimum width, the number must take
*/
void sprintI64(char *dst, uint64_t number, int max_width)
void sprintI64(char *dst, uint64_t number, int min_width)
{
char buf[24];
size_t len;
char *p = buf + 23;
*(p--) = 0; /* last symbol should be '\0' */
if(number == 0) {
*(p--) = '0';
} else {
for(; p >= buf && number != 0; p--, number /= 10) {
*p = '0' + (char)(number % 10);
}
}
len = buf + 22 - p;
if((size_t)max_width > len) {
memset(dst, 0x20, max_width - len);
dst += max_width - len;
}
memcpy(dst, p+1, len+1);
char buf[24]; /* internal buffer to output the number to */
size_t len;
char *p = buf + 23; /* start filling from the buffer end */
*(p--) = 0; /* last symbol should be '\0' */
if(number == 0) {
*(p--) = '0';
} else {
for(; p >= buf && number != 0; p--, number /= 10) {
*p = '0' + (char)(number % 10);
}
}
len = buf + 22 - p;
if((size_t)min_width > len) {
memset(dst, 0x20, min_width - len); /* fill by spaces */
dst += min_width - len;
}
memcpy(dst, p+1, len+1); /* copy the number to the output buffer */
}
/**
* Calculate length of decimal representation of given 64-bit integer.
*
*
* @param num integer to calculate the length for
* @return length of decimal representation
*/
int int_len(uint64_t num)
{
int len;
for(len = 0; num; len++, num /= 10);
return (len == 0 ? 1 : len); /* note: int_len(0) == 1 */
int len;
for(len = 0; num; len++, num /= 10);
return (len == 0 ? 1 : len); /* note: int_len(0) == 1 */
}
/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */
......@@ -55,31 +60,31 @@ int int_len(uint64_t num)
/**
* URL-encode given string.
*
* @param dst buffer to recieve result or NULL to calculate encoded string size
*
* @param dst buffer to receive result or NULL to calculate encoded string size
* @param filename the file name
* @return the length of the result string
*/
int urlencode(char *dst, const char *name)
{
const char *start;
if(!dst) {
int len;
for(len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3);
/* ed2k://|file|<fname>|<fsize>|2E398E5533AE4A83475B1AF001C6CEE6|h=RKLBEXT4O2H4RZER676WAVWGACIHQ56Z|/ */
return len;
}
/* encode URL as specified by RFC 1738 */
for(start = dst; *name; name++) {
if( IS_GOOD_URL_CHAR(*name) ) {
*dst++ = *name;
} else {
*dst++ = '%';
dst = rhash_print_hex_byte(dst, *name, 'A');
}
}
*dst = 0;
return (int)(dst - start);
const char *start;
if(!dst) {
int len;
for(len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3);
/* ed2k://|file|<fname>|<fsize>|2E398E5533AE4A83475B1AF001C6CEE6|h=RKLBEXT4O2H4RZER676WAVWGACIHQ56Z|/ */
return len;
}
/* encode URL as specified by RFC 1738 */
for(start = dst; *name; name++) {
if( IS_GOOD_URL_CHAR(*name) ) {
*dst++ = *name;
} else {
*dst++ = '%';
dst = rhash_print_hex_byte(dst, *name, 'A');
}
}
*dst = 0;
return (int)(dst - start);
}
/**
......@@ -92,12 +97,12 @@ int urlencode(char *dst, const char *name)
*/
char* str_tolower(const char* str)
{
char* buf = rsh_strdup(str);
char* p;
if(buf) {
for(p = buf; *p; p++) *p = tolower(*p);
}
return buf;
char* buf = rsh_strdup(str);
char* p;
if(buf) {
for(p = buf; *p; p++) *p = tolower(*p);
}
return buf;
}
/**
......@@ -108,14 +113,14 @@ char* str_tolower(const char* str)
*/
char* str_trim(char* str)
{
char* last = str + strlen(str) - 1;
while(isspace(*str)) str++;
while(isspace(*last) && last > str) *(last--) = 0;
return str;
char* last = str + strlen(str) - 1;
while(isspace(*str)) str++;
while(isspace(*last) && last > str) *(last--) = 0;
return str;
}
/**
* Fill a buffer with NULL-terminated string consisting
* Fill a buffer with NULL-terminated string consisting
* solely of a given repeated character.
*
* @param buf the modifiable buffer to fill
......@@ -125,9 +130,9 @@ char* str_trim(char* str)
*/
char* str_set(char* buf, int ch, int length)
{
memset(buf, ch, length);
buf[length] = '\0';
return buf;
memset(buf, ch, length);
buf[length] = '\0';
return buf;
}
/**
......@@ -139,12 +144,12 @@ char* str_set(char* buf, int ch, int length)
*/
int is_binary_string(const char* str)
{
for(; *str; str++) {
if(((unsigned char)*str) < 32 && ((1 << (unsigned char)*str) & ~0x2600)) {
return 1;
}
}
return 0;
for(; *str; str++) {
if(((unsigned char)*str) < 32 && ((1 << (unsigned char)*str) & ~0x2600)) {
return 1;
}
}
return 0;
}
/**
......@@ -155,11 +160,11 @@ int is_binary_string(const char* str)
*/
size_t strlen_utf8_c(const char *str)
{
size_t length = 0;
for(; *str; str++) {
if((*str & 0xc0) != 0x80) length++;
}
return length;
size_t length = 0;
for(; *str; str++) {
if((*str & 0xc0) != 0x80) length++;
}
return length;
}
/**
......@@ -169,8 +174,8 @@ size_t strlen_utf8_c(const char *str)
*/
void rhash_exit(int code)
{
IF_WINDOWS(restore_console());
exit(code);
IF_WINDOWS(restore_console());
exit(code);
}
/* FILE FUNCTIONS */
......@@ -183,9 +188,9 @@ void rhash_exit(int code)
*/
const char* get_basename(const char* path)
{
const char *p = path + strlen(path) - 1;
for(; p >= path && !IS_PATH_SEPARATOR(*p); p--);
return (p+1);
const char *p = path + strlen(path) - 1;
for(; p >= path && !IS_PATH_SEPARATOR(*p); p--);
return (p+1);
}
/**
......@@ -197,17 +202,17 @@ const char* get_basename(const char* path)
*/
char* get_dirname(const char* path)
{
const char *p = path + strlen(path) - 1;
char *res;
for(; p > path && !IS_PATH_SEPARATOR(*p); p--);
if((p - path) > 1) {
res = (char*)rsh_malloc(p-path+1);
memcpy(res, path, p-path);
res[p-path] = 0;
return res;
} else {
return rsh_strdup(".");
}
const char *p = path + strlen(path) - 1;
char *res;
for(; p > path && !IS_PATH_SEPARATOR(*p); p--);
if((p - path) > 1) {
res = (char*)rsh_malloc(p-path+1);
memcpy(res, path, p-path);
res[p-path] = 0;
return res;
} else {
return rsh_strdup(".");
}
}
/**
......@@ -219,26 +224,26 @@ char* get_dirname(const char* path)
*/
char* make_path(const char* dir_path, const char* filename)
{
char* buf;
size_t len;
assert(dir_path);
assert(filename);
char* buf;
size_t len;
assert(dir_path);
assert(filename);
/* remove leading path separators from filename */
while(IS_PATH_SEPARATOR(*filename)) filename++;
/* remove leading path separators from filename */
while(IS_PATH_SEPARATOR(*filename)) filename++;
/* copy directory path */
len = strlen(dir_path);
buf = (char*)rsh_malloc(len + strlen(filename) + 2);
strcpy(buf, dir_path);
/* copy directory path */
len = strlen(dir_path);
buf = (char*)rsh_malloc(len + strlen(filename) + 2);
strcpy(buf, dir_path);
/* separate directory from filename */
if(len > 0 && !IS_PATH_SEPARATOR(buf[len-1]))
buf[len++] = SYS_PATH_SEPARATOR;
/* separate directory from filename */
if(len > 0 && !IS_PATH_SEPARATOR(buf[len-1]))
buf[len++] = SYS_PATH_SEPARATOR;
/* append filename */
strcpy(buf+len, filename);
return buf;
/* append filename */
strcpy(buf+len, filename);
return buf;
}
/**
......@@ -249,16 +254,16 @@ char* make_path(const char* dir_path, const char* filename)
*/
void print_time(FILE *out, time_t time)
{
struct tm *t = localtime(&time);
static struct tm zero_tm;
if(t == NULL) {
/* if strange day, then print `00:00.00 1900-01-00' */
t = &zero_tm;
t->tm_hour = t->tm_min = t->tm_sec =
t->tm_year = t->tm_mon = t->tm_mday = 0;
}
fprintf(out, "%02u:%02u.%02u %4u-%02u-%02u", t->tm_hour, t->tm_min,
t->tm_sec, (1900+t->tm_year), t->tm_mon+1, t->tm_mday);
struct tm *t = localtime(&time);
static struct tm zero_tm;
if(t == NULL) {
/* if strange day, then print `00:00.00 1900-01-00' */
t = &zero_tm;
t->tm_hour = t->tm_min = t->tm_sec =
t->tm_year = t->tm_mon = t->tm_mday = 0;
}
fprintf(out, "%02u:%02u.%02u %4u-%02u-%02u", t->tm_hour, t->tm_min,
t->tm_sec, (1900+t->tm_year), t->tm_mon+1, t->tm_mday);
}
#ifdef _WIN32
......@@ -267,18 +272,18 @@ void print_time(FILE *out, time_t time)
/**
* Return ticks in milliseconds for time intervals measurement.
* This function should be not precise but the fastest one
* to retrive internal clock value.
* This function should be not precise but the fastest one
* to retrieve internal clock value.
*
* @return ticks count in milliseconds
*/
unsigned rhash_get_ticks(void)
{
#ifdef _WIN32
return GetTickCount();
return GetTickCount();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
#endif
}
......@@ -51,6 +51,8 @@ char* make_path(const char* dir, const char* filename);
# define rsh_fopen_bin(path, mode) win_fopen_bin(path, mode)
# define is_utf8() win_is_utf8()
# define to_utf8(str) win_to_utf8(str)
typedef wchar_t rsh_tchar;
# define RSH_T(str) L##str
#else /* non _WIN32 part */
# define IF_WINDOWS(code)
# define SYS_PATH_SEPARATOR '/'
......@@ -59,6 +61,8 @@ char* make_path(const char* dir, const char* filename);
/* stub for utf8 */
# define is_utf8() 1
# define to_utf8(str) NULL
typedef char rsh_tchar;
# define RSH_T(str) str
#endif /* _WIN32 */
/* rhash stat function */
......
This diff is collapsed.
......@@ -7,31 +7,32 @@ extern "C" {
#endif
typedef struct print_item {
struct print_item *next;
unsigned flags;
unsigned hash_id;
unsigned width;
const char *data;
struct print_item *next;
unsigned flags;
unsigned hash_id;
unsigned width;
const char *data;
} print_item;
typedef struct print_hash_info
{
char short_name[16];
char short_char;
const char *name;
const char *urn;
char short_name[16];
char short_char;
const char *name;
const char *urn;
} print_hash_info;
extern print_hash_info hash_info_table[];
struct file_info;
struct strbuf_t;
print_item* parse_print_string(const char* format, unsigned *sum_mask);
void print_line(FILE* out, print_item* list, struct file_info *info);
void free_print_list(print_item* list);
void init_hash_info_table(void);
void init_printf_format(strbuf_t* out);
void init_printf_format(struct strbuf_t* out);
#ifdef __cplusplus
} /* extern "C" */
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
extern "C" {
#endif
int update_crc_file(const char* filepath);
int update_hash_file(const char* filepath);
#ifdef __cplusplus
} /* extern "C" */
......
......@@ -10,10 +10,10 @@ rhash \- calculate/check CRC32, MD5, SHA1, GOST, TTH, BTIH or other hash sums.
.SH DESCRIPTION
.B RHash
(Recursive Hasher)
computes and verifies various message digests (hash sums) of files.
Supported message digests include CRC32, MD4, MD5, SHA1/SHA2, Tiger, DC++ TTH,
BitTorrent BTIH, AICH, ED2K, GOST R 34.11\-94, RIPEMD\-160,
HAS\-160, EDON\-R 256/512, Whirlpool, Snefru\-128/256.
computes and verifies various message digests (hash sums) of files.
Supported message digests include CRC32, MD4, MD5, SHA1, SHA256, SHA512,
Tiger, DC++ TTH, BitTorrent BTIH, AICH, ED2K, GOST R 34.11\-94,
RIPEMD\-160, HAS\-160, EDON\-R 256/512, Whirlpool, Snefru\-128/256.
The program can create and verify Magnet links
and eDonkey ed2k:// links, see \-\-magnet and \-\-ed2k\-link options.
......@@ -221,49 +221,61 @@ URL\(hyencoded filename.
File's size in bytes.
.IP %{mtime}
File's last modification time.
.IP "%a or %A"
AICH hash sum.
.IP "%c or %C"
CRC32 hash sum.
Use %c for lowercase and %C for uppercase characters.
.IP "%m or %M"
MD5 hash.
.IP "%h or %H"
SHA1 hash.
.IP "%g or %G"
GOST R 34.11\-94 hash.
.IP "%t or %T"
TTH sum.
.IP "%h or %H"
SHA1 hash.
.IP "%e or %E"
eDonkey hash sum.
ED2K hash sum.
.IP "%l or %L"
eDonkey ed2k://... link.
EDonkey ed2k://... link.
.IP "%m or %M"
MD5 hash.
.IP "%r or %R"
RIPEMD-160 hash.
.IP "%t or %T"
TTH sum.
.IP "%w or %W"
Whirlpool hash.
.IP "%{md4}, %{btih}, %{tiger}, %{has160}, %{ripemd160}, %{snefru128}, %{snefru256}, ..."
Print specified <hash sum>. Actually the %{<hash sum>} directive can print
any supported hash sum. Start <hash sum> with capital letter to print uppercased hash
e.g. %{TTH}, %{Md4}.
.IP "%{md4}, %{sha224}, %{sha256}, %{sha384}, %{sha512}, %{tiger}, %{btih}, %{gost\-cryptopro}, %{has160}, %{snefru128}, %{snefru256}, %{edon\-r256}, %{edon\-r512}"
Print specified hash sum. Actually the %{<hash sum>} directive can print any
supported hash sum. If a hash sum name starts with a capital letter then the
hash is printed in uppercase, e.g. %{TTH}, %{Sha512}.
.IP "%x<hash>, %b<hash>, %B<hash>, %@<hash>"
Use one of these prefixes to output a hash sum in hexadecimal, base32,
base64 or raw (binary) format respectively, e.g. %b{md4}, %BH or %xT.
.RE
.SH CONFIG FILE
RHash looks for config file at
$HOME/.rhashrc and /etc/rhashrc
RHash looks for a config file
at $HOME/.rhashrc and /etc/rhashrc.
The syntax of the config file line is
The config file consists of lines formated as
.RS