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:
parent
73992371a3
commit
7e8961f720
9 changed files with 487 additions and 26 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue