1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-06 21:41:48 +02:00

* Added SHA-1 support. nix-hash' now has an option --type sha1' to

select SHA-1 hashing.
This commit is contained in:
Eelco Dolstra 2005-01-13 17:39:26 +00:00
parent 73992371a3
commit 7e8961f720
9 changed files with 487 additions and 26 deletions

View file

@ -2,17 +2,24 @@
extern "C" {
#include "md5.h"
#include "sha1.h"
}
#include "hash.hh"
#include "archive.hh"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
Hash::Hash(HashType type)
{
this->type = type;
if (type == htMD5) hashSize = md5HashSize;
else if (type == htSHA1) hashSize = sha1HashSize;
else throw Error("unknown hash type");
memset(hash, 0, hashSize);
}
@ -85,44 +92,90 @@ bool isHash(const string & s)
}
Hash hashString(const string & s)
struct Ctx
{
Hash hash(htMD5);
md5_buffer(s.c_str(), s.length(), hash.hash);
md5_ctx md5;
sha_ctx sha1;
};
static void start(HashType ht, Ctx & ctx)
{
if (ht == htMD5) md5_init_ctx(&ctx.md5);
else if (ht == htSHA1) sha_init(&ctx.sha1);
}
static void update(HashType ht, Ctx & ctx,
const unsigned char * bytes, unsigned int len)
{
if (ht == htMD5) md5_process_bytes(bytes, len, &ctx.md5);
else if (ht == htSHA1) sha_update(&ctx.sha1, bytes, len);
}
static void finish(HashType ht, Ctx & ctx, unsigned char * hash)
{
if (ht == htMD5) md5_finish_ctx(&ctx.md5, hash);
else if (ht == htSHA1) {
sha_final(&ctx.sha1);
sha_digest(&ctx.sha1, hash);
}
}
Hash hashString(const string & s, HashType ht)
{
Ctx ctx;
Hash hash(ht);
start(ht, ctx);
update(ht, ctx, (const unsigned char *) s.c_str(), s.length());
finish(ht, ctx, hash.hash);
return hash;
}
Hash hashFile(const Path & path)
Hash hashFile(const Path & path, HashType ht)
{
Hash hash(htMD5);
FILE * file = fopen(path.c_str(), "rb");
if (!file)
throw SysError(format("file `%1%' does not exist") % path);
int err = md5_stream(file, hash.hash);
fclose(file);
if (err) throw SysError(format("cannot hash file `%1%'") % path);
Ctx ctx;
Hash hash(ht);
start(ht, ctx);
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
if (fd == -1) throw SysError(format("opening file `%1%'") % path);
unsigned char buf[8192];
ssize_t n;
while ((n = read(fd, buf, sizeof(buf)))) {
checkInterrupt();
if (n == -1) throw SysError(format("reading file `%1%'") % path);
update(ht, ctx, buf, n);
}
finish(ht, ctx, hash.hash);
return hash;
}
struct HashSink : DumpSink
{
struct md5_ctx ctx;
HashType ht;
Ctx ctx;
virtual void operator ()
(const unsigned char * data, unsigned int len)
{
md5_process_bytes(data, len, &ctx);
update(ht, ctx, data, len);
}
};
Hash hashPath(const Path & path)
Hash hashPath(const Path & path, HashType ht)
{
Hash hash(htMD5);
HashSink sink;
md5_init_ctx(&sink.ctx);
sink.ht = ht;
Hash hash(ht);
start(ht, sink.ctx);
dumpPath(path, sink);
md5_finish_ctx(&sink.ctx, hash.hash);
finish(ht, sink.ctx, hash.hash);
return hash;
}