Initial commit.
authorKristian H?gsberg <krh@redhat.com>
Mon Sep 03 14:36:59 2007 -0400 (2007-09-03)
changeset 0e15eb9ef9c28
child 1 38be5ee4d231
Initial commit.
Makefile
import-rpm.sh
razor.c
sha1.c
sha1.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Makefile	Mon Sep 03 14:36:59 2007 -0400
     1.3 @@ -0,0 +1,7 @@
     1.4 +CFLAGS = -Wall -g
     1.5 +LDLIBS = -lexpat -g
     1.6 +
     1.7 +razor : razor.o sha1.o
     1.8 +
     1.9 +clean :
    1.10 +	rm -f *.o razor
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/import-rpm.sh	Mon Sep 03 14:36:59 2007 -0400
     2.3 @@ -0,0 +1,24 @@
     2.4 +#!/bin/sh
     2.5 +
     2.6 +import_rpm() {
     2.7 +    echo "<package name=\"$p\" version=\"3.2\" build=\"9\">"
     2.8 +    echo "  <properties>"
     2.9 +
    2.10 +    rpm -q --provides $p | sort -u | while read name ignore version; do
    2.11 +	echo "    <provides name=\"$name\"/>"
    2.12 +    done
    2.13 +
    2.14 +    rpm -q --requires $p | sort -u | while read name ignore version; do
    2.15 +	echo "    <requires name=\"$name\"/>"
    2.16 +    done
    2.17 +
    2.18 +    echo "  </properties>"
    2.19 +    echo "</package>"
    2.20 +}
    2.21 +
    2.22 +mkdir pkgs
    2.23 +rpm -qa | while read p; do
    2.24 +    base=${p%-*-*}
    2.25 +    echo $base
    2.26 +    import_rpm $base > pkgs/$base.rzr
    2.27 +done
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/razor.c	Mon Sep 03 14:36:59 2007 -0400
     3.3 @@ -0,0 +1,495 @@
     3.4 +#include <stdlib.h>
     3.5 +#include <stdio.h>
     3.6 +#include <string.h>
     3.7 +#include <sys/types.h>
     3.8 +#include <sys/stat.h>
     3.9 +#include <sys/mman.h>
    3.10 +#include <unistd.h>
    3.11 +#include <fcntl.h>
    3.12 +
    3.13 +#include <expat.h>
    3.14 +#include "sha1.h"
    3.15 +
    3.16 +static int
    3.17 +write_to_fd(int fd, void *p, size_t size)
    3.18 +{
    3.19 +	int rest, len;
    3.20 +
    3.21 +	rest = size;
    3.22 +	while (rest > 0) {
    3.23 +		len = write(fd, p, rest);
    3.24 +		if (len < 0)
    3.25 +			return -1;
    3.26 +		rest -= len;
    3.27 +	}
    3.28 +
    3.29 +	return 0;
    3.30 +}
    3.31 +
    3.32 +static int
    3.33 +write_to_file(const char *filename, void *p, size_t size)
    3.34 +{
    3.35 +	int fd, err;
    3.36 +
    3.37 +	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
    3.38 +	if (fd < 0)
    3.39 +		return -1;
    3.40 +	err = write_to_fd(fd, p, size);
    3.41 +	close(fd);
    3.42 +
    3.43 +	return err;
    3.44 +}
    3.45 +
    3.46 +struct hashtable_header {
    3.47 +	unsigned int magic;
    3.48 +	unsigned int version;
    3.49 +	struct { unsigned int type, offset; } sections[0];
    3.50 +};
    3.51 +
    3.52 +#define HASHTABLE_MAGIC 0x7a7a7a7a
    3.53 +#define HASHTABLE_VERSION 1
    3.54 +#define HASHTABLE_BUCKETS 1
    3.55 +#define HASHTABLE_STRINGS 2
    3.56 +
    3.57 +struct hashtable {
    3.58 +	unsigned long *buckets;
    3.59 +	int bucket_count, bucket_alloc;
    3.60 +	char *string_pool;
    3.61 +	int pool_size, pool_alloc;
    3.62 +	struct hashtable_header *header;
    3.63 +};
    3.64 +
    3.65 +static void *
    3.66 +zalloc(size_t size)
    3.67 +{
    3.68 +	void *p;
    3.69 +
    3.70 +	p = malloc(size);
    3.71 +	memset(p, 0, size);
    3.72 +
    3.73 +	return p;
    3.74 +}
    3.75 +
    3.76 +struct hashtable *
    3.77 +hashtable_create(void)
    3.78 +{
    3.79 +	struct hashtable *ht;
    3.80 +
    3.81 +	ht = zalloc(sizeof *ht);
    3.82 +	ht->buckets = zalloc(4096 * sizeof *ht->buckets);
    3.83 +	ht->bucket_count = 0;
    3.84 +	ht->bucket_alloc = 4096;
    3.85 +
    3.86 +	ht->string_pool = zalloc(4096);
    3.87 +	ht->pool_size = 1;
    3.88 +	ht->pool_alloc = 4096;
    3.89 +
    3.90 +	return ht;
    3.91 +}
    3.92 +
    3.93 +struct hashtable *
    3.94 +hashtable_create_from_file(const char *filename)
    3.95 +{
    3.96 +	struct hashtable *ht;
    3.97 +	struct stat stat;
    3.98 +	unsigned int size, offset;
    3.99 +	int fd, i;
   3.100 +
   3.101 +	ht = zalloc(sizeof *ht);
   3.102 +	fd = open(filename, O_RDONLY);
   3.103 +	if (fstat(fd, &stat) < 0)
   3.104 +		return NULL;
   3.105 +	ht->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   3.106 +	if (ht->header == MAP_FAILED) {
   3.107 +		free(ht);
   3.108 +		return NULL;
   3.109 +	}
   3.110 +
   3.111 +	for (i = 0; i < ht->header->sections[i].type; i++) {
   3.112 +		offset = ht->header->sections[i].offset;
   3.113 +		size = ht->header->sections[i + 1].offset - offset;
   3.114 +
   3.115 +		switch (ht->header->sections[i].type) {
   3.116 +		case HASHTABLE_BUCKETS:
   3.117 +			ht->buckets = (void *) ht->header + offset;
   3.118 +			ht->bucket_count = size / sizeof *ht->buckets;
   3.119 +			ht->bucket_alloc = ht->bucket_count;
   3.120 +			break;
   3.121 +		case HASHTABLE_STRINGS:
   3.122 +			ht->string_pool = (void *) ht->header + offset;
   3.123 +			ht->pool_size = size;
   3.124 +			ht->pool_alloc = size;
   3.125 +			break;
   3.126 +		}
   3.127 +	}
   3.128 +	close(fd);
   3.129 +
   3.130 +	return ht;
   3.131 +}
   3.132 +
   3.133 +void
   3.134 +hashtable_destroy(struct hashtable *ht)
   3.135 +{
   3.136 +	unsigned int size;
   3.137 +	int i;
   3.138 +
   3.139 +	if (ht->header) {
   3.140 +		for (i = 0; ht->header->sections[i].type; i++)
   3.141 +			;
   3.142 +		size = ht->header->sections[i].type;
   3.143 +		munmap(ht->header, size);
   3.144 +	} else {
   3.145 +		free(ht->buckets);
   3.146 +		free(ht->string_pool);
   3.147 +	}
   3.148 +
   3.149 +	free(ht);
   3.150 +}
   3.151 +
   3.152 +static int
   3.153 +hashtable_write(struct hashtable *ht, const char *filename)
   3.154 +{
   3.155 +	int fd;
   3.156 +	char data[4096];
   3.157 +	struct hashtable_header *header = (struct hashtable_header *) data;
   3.158 +
   3.159 +	memset(data, 0, sizeof data);
   3.160 +	header->magic = HASHTABLE_MAGIC;
   3.161 +	header->version = HASHTABLE_VERSION;
   3.162 +
   3.163 +	header->sections[0].type = HASHTABLE_BUCKETS;
   3.164 +	header->sections[0].offset = sizeof data;
   3.165 +
   3.166 +	header->sections[1].type = HASHTABLE_STRINGS;
   3.167 +	header->sections[1].offset =
   3.168 +		sizeof data + ht->bucket_alloc * sizeof *ht->buckets;
   3.169 +
   3.170 +	header->sections[2].type = 0;
   3.171 +	header->sections[2].offset =
   3.172 +		header->sections[1].offset + ht->pool_size;
   3.173 +
   3.174 +	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
   3.175 +	if (fd < 0)
   3.176 +		return -1;
   3.177 +
   3.178 +	write_to_fd(fd, data, sizeof data);
   3.179 +	write_to_fd(fd, ht->buckets, ht->bucket_alloc * sizeof *ht->buckets);
   3.180 +	write_to_fd(fd, ht->string_pool, ht->pool_size);
   3.181 +
   3.182 +	return 0;
   3.183 +}
   3.184 +
   3.185 +static unsigned int
   3.186 +hash_string(const char *key)
   3.187 +{
   3.188 +	const char *p;
   3.189 +	unsigned int hash = 0;
   3.190 +
   3.191 +	for (p = key; *p; p++)
   3.192 +		hash = (hash << 2) ^ *p;
   3.193 +
   3.194 +	return hash;
   3.195 +}
   3.196 +
   3.197 +unsigned long
   3.198 +hashtable_lookup(struct hashtable *ht, const char *key)
   3.199 +{
   3.200 +	unsigned int start;
   3.201 +	unsigned int mask;
   3.202 +	unsigned long value;
   3.203 +	int i;
   3.204 +
   3.205 +	mask = ht->bucket_alloc - 1;
   3.206 +	start = hash_string(key) & mask;
   3.207 +	i = start;
   3.208 +	do {
   3.209 +		value = ht->buckets[i];
   3.210 +
   3.211 +		if (value == 0)
   3.212 +			return 0;
   3.213 +
   3.214 +		if (strcmp(key, &ht->string_pool[value]) == 0)
   3.215 +			return value;
   3.216 +
   3.217 +		i = (i + 1) & mask;
   3.218 +	} while (i != start);
   3.219 +
   3.220 +	return 0;
   3.221 +}
   3.222 +
   3.223 +static unsigned long
   3.224 +add_to_string_pool(struct hashtable *ht, const char *key)
   3.225 +{
   3.226 +	int len, alloc;
   3.227 +	char *pool;
   3.228 +	unsigned long value;
   3.229 +
   3.230 +	len = strlen(key) + 1;
   3.231 +	alloc = ht->pool_alloc;
   3.232 +	while (alloc < ht->pool_size + len)
   3.233 +		alloc *= 2;
   3.234 +	if (ht->pool_alloc < alloc) {
   3.235 +		pool = realloc(ht->string_pool, alloc);
   3.236 +		if (pool == NULL)
   3.237 +			return 0;
   3.238 +		ht->string_pool = pool;
   3.239 +		ht->pool_alloc = alloc;
   3.240 +	}
   3.241 +
   3.242 +	memcpy(ht->string_pool + ht->pool_size, key, len);
   3.243 +	value = ht->pool_size;
   3.244 +	ht->pool_size += len;
   3.245 +
   3.246 +	return value;
   3.247 +}
   3.248 +
   3.249 +static void
   3.250 +do_insert(struct hashtable *ht, unsigned long value)
   3.251 +{
   3.252 +	unsigned int mask;
   3.253 +	const char *key;
   3.254 +	int i, start;
   3.255 +
   3.256 +	key = &ht->string_pool[value];
   3.257 +	mask = ht->bucket_alloc - 1;
   3.258 +	start = hash_string(key) & mask;
   3.259 +	i = start;
   3.260 +	do {
   3.261 +		if (ht->buckets[i] == 0) {
   3.262 +			ht->buckets[i] = value;
   3.263 +			break;
   3.264 +		}
   3.265 +		i = (i + 1) & mask;
   3.266 +	} while (i != start);
   3.267 +}
   3.268 +
   3.269 +unsigned long
   3.270 +hashtable_insert(struct hashtable *ht, const char *key)
   3.271 +{
   3.272 +	unsigned long value, *buckets, *old_buckets;
   3.273 +	int i, alloc, old_alloc;
   3.274 +
   3.275 +	alloc = ht->bucket_alloc;
   3.276 +	while (alloc < 4 * ht->bucket_count)
   3.277 +		alloc *= 2;
   3.278 +
   3.279 +	if (alloc != ht->bucket_alloc) {
   3.280 +		buckets = zalloc(alloc * sizeof *ht->buckets);
   3.281 +		if (buckets == NULL)
   3.282 +			return 0;
   3.283 +		old_buckets = ht->buckets;
   3.284 +		ht->buckets = buckets;
   3.285 +		old_alloc = ht->bucket_alloc;
   3.286 +		ht->bucket_alloc = alloc;
   3.287 +		
   3.288 +		for (i = 0; i < old_alloc; i++) {
   3.289 +			value = old_buckets[i];
   3.290 +			if (value != 0)
   3.291 +				do_insert(ht, value);
   3.292 +		}
   3.293 +		free(old_buckets);
   3.294 +	}
   3.295 +
   3.296 +	value = add_to_string_pool(ht, key);
   3.297 +	do_insert (ht, value);
   3.298 +	ht->bucket_count++;
   3.299 +
   3.300 +	return value;
   3.301 +}
   3.302 +
   3.303 +struct razor_context {
   3.304 +	struct hashtable *global_ht;
   3.305 +};
   3.306 +
   3.307 +struct razor_context *
   3.308 +razor_context_create (void)
   3.309 +{
   3.310 +	struct razor_context *ctx;
   3.311 +
   3.312 +	ctx = malloc(sizeof *ctx);
   3.313 +	ctx->global_ht = hashtable_create();
   3.314 +
   3.315 +	return ctx;
   3.316 +}
   3.317 +
   3.318 +struct razor_context *
   3.319 +razor_context_create_from_file (const char *filename)
   3.320 +{
   3.321 +	struct razor_context *ctx;
   3.322 +
   3.323 +	ctx = malloc(sizeof *ctx);
   3.324 +	ctx->global_ht = hashtable_create_from_file(filename);
   3.325 +
   3.326 +	return ctx;
   3.327 +}
   3.328 +
   3.329 +unsigned long
   3.330 +razor_context_tokenize(struct razor_context *ctx, const char *string)
   3.331 +{
   3.332 +	unsigned long token;
   3.333 +
   3.334 +	token = hashtable_lookup(ctx->global_ht, string);
   3.335 +	if (token != 0)
   3.336 +		return token;
   3.337 +
   3.338 +	return hashtable_insert(ctx->global_ht, string);
   3.339 +}
   3.340 +
   3.341 +struct razor_set {
   3.342 +	struct razor_context *ctx;
   3.343 +};
   3.344 +
   3.345 +struct parsing_context {
   3.346 +	struct razor_context *ctx;
   3.347 +};
   3.348 +
   3.349 +static void
   3.350 +start_element(void *data, const char *name, const char **atts)
   3.351 +{
   3.352 +	struct parsing_context *ctx = data;
   3.353 +	int i;
   3.354 +
   3.355 +	for (i = 0; atts[i]; i += 2)
   3.356 +		razor_context_tokenize(ctx->ctx, atts[i + 1]);
   3.357 +}
   3.358 +
   3.359 +static void
   3.360 +end_element (void *data, const char *name)
   3.361 +{
   3.362 +}
   3.363 +
   3.364 +static char *
   3.365 +sha1_to_hex(const unsigned char *sha1)
   3.366 +{
   3.367 +	static int bufno;
   3.368 +	static char hexbuffer[4][50];
   3.369 +	static const char hex[] = "0123456789abcdef";
   3.370 +	char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
   3.371 +	int i;
   3.372 +
   3.373 +	for (i = 0; i < 20; i++) {
   3.374 +		unsigned int val = *sha1++;
   3.375 +		*buf++ = hex[val >> 4];
   3.376 +		*buf++ = hex[val & 0xf];
   3.377 +	}
   3.378 +	*buf = '\0';
   3.379 +
   3.380 +	return buffer;
   3.381 +}
   3.382 +
   3.383 +static int
   3.384 +razor_context_read_file(struct razor_context *ctx, const char *filename)
   3.385 +{
   3.386 +	SHA_CTX sha1;
   3.387 +	XML_Parser parser;
   3.388 +	struct parsing_context pctx;
   3.389 +	int fd;
   3.390 +	void *p;
   3.391 +	struct stat stat;
   3.392 +	char buf[128];
   3.393 +	unsigned char hash[20];
   3.394 +
   3.395 +	fd = open(filename, O_RDONLY);
   3.396 +	if (fstat(fd, &stat) < 0)
   3.397 +		return -1;
   3.398 +	p = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   3.399 +	if (p == MAP_FAILED)
   3.400 +		return -1;
   3.401 +
   3.402 +	parser = XML_ParserCreate(NULL);
   3.403 +	pctx.ctx = ctx;
   3.404 +	XML_SetUserData(parser, &pctx);
   3.405 +	XML_SetElementHandler(parser, start_element, end_element);
   3.406 +	if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) {
   3.407 +		fprintf(stderr,
   3.408 +			"%s at line %d, %s\n",
   3.409 +			XML_ErrorString(XML_GetErrorCode(parser)),
   3.410 +			XML_GetCurrentLineNumber(parser),
   3.411 +			filename);
   3.412 +		return 1;
   3.413 +	}
   3.414 +
   3.415 +	XML_ParserFree(parser);
   3.416 +
   3.417 +	SHA1_Init(&sha1);
   3.418 +	SHA1_Update(&sha1, p, stat.st_size);
   3.419 +	SHA1_Final(hash, &sha1);
   3.420 +
   3.421 +	close(fd);
   3.422 +
   3.423 +	snprintf(buf, sizeof buf, "set/%s", sha1_to_hex(hash));
   3.424 +	if (write_to_file(buf, p, stat.st_size) < 0)
   3.425 +		return -1;
   3.426 +	munmap(p, stat.st_size);
   3.427 +
   3.428 +	return 0;
   3.429 +}
   3.430 +
   3.431 +int
   3.432 +razor_context_write(struct razor_context *ctx, const char *filename)
   3.433 +{
   3.434 +	return hashtable_write(ctx->global_ht, filename);
   3.435 +}
   3.436 +
   3.437 +void
   3.438 +razor_context_destroy(struct razor_context *ctx)
   3.439 +{
   3.440 +	hashtable_destroy(ctx->global_ht);
   3.441 +	free(ctx);
   3.442 +}
   3.443 +
   3.444 +static int
   3.445 +usage(void)
   3.446 +{
   3.447 +	printf("usage: razor [ import FILES | lookup <key> ]\n");
   3.448 +	exit(1);
   3.449 +}
   3.450 +
   3.451 +static const char repo_filename[] = "system.repo";
   3.452 +
   3.453 +int
   3.454 +main(int argc, char *argv[])
   3.455 +{
   3.456 +	int i;
   3.457 +	struct razor_context *ctx;
   3.458 +	struct stat statbuf;
   3.459 +
   3.460 +	if (argc < 3) {
   3.461 +		usage();
   3.462 +	} else if (strcmp(argv[1], "import") == 0) {
   3.463 +		if (stat("set", &statbuf) && mkdir("set", 0777)) {
   3.464 +			fprintf(stderr, "could not create directory 'set'\n");
   3.465 +			exit(-1);
   3.466 +		}
   3.467 +			
   3.468 +		ctx = razor_context_create();
   3.469 +
   3.470 +		for (i = 2; i < argc; i++) {
   3.471 +			if (razor_context_read_file(ctx, argv[i]) < 0) {
   3.472 +				fprintf(stderr, "failed to import %s\n",
   3.473 +					argv[i]);
   3.474 +				exit(-1);
   3.475 +			}
   3.476 +		}
   3.477 +
   3.478 +		printf("number of buckets: %d\n",
   3.479 +		       ctx->global_ht->bucket_count);
   3.480 +		printf("bucket allocation: %d\n",
   3.481 +		       ctx->global_ht->bucket_alloc);
   3.482 +		printf("pool size: %d\n", ctx->global_ht->pool_size);
   3.483 +		printf("pool allocation: %d\n", ctx->global_ht->pool_alloc);
   3.484 +
   3.485 +		razor_context_write(ctx, repo_filename);
   3.486 +
   3.487 +		razor_context_destroy(ctx);
   3.488 +	} else if (strcmp(argv[1], "lookup") == 0) {
   3.489 +		ctx = razor_context_create_from_file(repo_filename);
   3.490 +		printf("%s is %lu\n", argv[2],
   3.491 +		       hashtable_lookup(ctx->global_ht, argv[2]));
   3.492 +		razor_context_destroy(ctx);
   3.493 +	} else {
   3.494 +		usage();
   3.495 +	}
   3.496 +
   3.497 +	return 0;
   3.498 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/sha1.c	Mon Sep 03 14:36:59 2007 -0400
     4.3 @@ -0,0 +1,151 @@
     4.4 +/*
     4.5 + * The contents of this file are subject to the Mozilla Public
     4.6 + * License Version 1.1 (the "License"); you may not use this file
     4.7 + * except in compliance with the License. You may obtain a copy of
     4.8 + * the License at http://www.mozilla.org/MPL/
     4.9 + *
    4.10 + * Software distributed under the License is distributed on an "AS
    4.11 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
    4.12 + * implied. See the License for the specific language governing
    4.13 + * rights and limitations under the License.
    4.14 + *
    4.15 + * The Original Code is SHA 180-1 Reference Implementation (Compact version)
    4.16 + *
    4.17 + * The Initial Developer of the Original Code is Paul Kocher of
    4.18 + * Cryptography Research.  Portions created by Paul Kocher are
    4.19 + * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
    4.20 + * Rights Reserved.
    4.21 + *
    4.22 + * Contributor(s):
    4.23 + *
    4.24 + *     Paul Kocher
    4.25 + *
    4.26 + * Alternatively, the contents of this file may be used under the
    4.27 + * terms of the GNU General Public License Version 2 or later (the
    4.28 + * "GPL"), in which case the provisions of the GPL are applicable
    4.29 + * instead of those above.  If you wish to allow use of your
    4.30 + * version of this file only under the terms of the GPL and not to
    4.31 + * allow others to use your version of this file under the MPL,
    4.32 + * indicate your decision by deleting the provisions above and
    4.33 + * replace them with the notice and other provisions required by
    4.34 + * the GPL.  If you do not delete the provisions above, a recipient
    4.35 + * may use your version of this file under either the MPL or the
    4.36 + * GPL.
    4.37 + */
    4.38 +
    4.39 +#include "sha1.h"
    4.40 +
    4.41 +static void shaHashBlock(SHA_CTX *ctx);
    4.42 +
    4.43 +void SHA1_Init(SHA_CTX *ctx) {
    4.44 +  int i;
    4.45 +
    4.46 +  ctx->lenW = 0;
    4.47 +  ctx->sizeHi = ctx->sizeLo = 0;
    4.48 +
    4.49 +  /* Initialize H with the magic constants (see FIPS180 for constants)
    4.50 +   */
    4.51 +  ctx->H[0] = 0x67452301;
    4.52 +  ctx->H[1] = 0xefcdab89;
    4.53 +  ctx->H[2] = 0x98badcfe;
    4.54 +  ctx->H[3] = 0x10325476;
    4.55 +  ctx->H[4] = 0xc3d2e1f0;
    4.56 +
    4.57 +  for (i = 0; i < 80; i++)
    4.58 +    ctx->W[i] = 0;
    4.59 +}
    4.60 +
    4.61 +
    4.62 +void SHA1_Update(SHA_CTX *ctx, const void *_dataIn, int len) {
    4.63 +  const unsigned char *dataIn = _dataIn;
    4.64 +  int i;
    4.65 +
    4.66 +  /* Read the data into W and process blocks as they get full
    4.67 +   */
    4.68 +  for (i = 0; i < len; i++) {
    4.69 +    ctx->W[ctx->lenW / 4] <<= 8;
    4.70 +    ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
    4.71 +    if ((++ctx->lenW) % 64 == 0) {
    4.72 +      shaHashBlock(ctx);
    4.73 +      ctx->lenW = 0;
    4.74 +    }
    4.75 +    ctx->sizeLo += 8;
    4.76 +    ctx->sizeHi += (ctx->sizeLo < 8);
    4.77 +  }
    4.78 +}
    4.79 +
    4.80 +
    4.81 +void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx) {
    4.82 +  unsigned char pad0x80 = 0x80;
    4.83 +  unsigned char pad0x00 = 0x00;
    4.84 +  unsigned char padlen[8];
    4.85 +  int i;
    4.86 +
    4.87 +  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
    4.88 +   */
    4.89 +  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
    4.90 +  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
    4.91 +  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
    4.92 +  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
    4.93 +  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
    4.94 +  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
    4.95 +  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
    4.96 +  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
    4.97 +  SHA1_Update(ctx, &pad0x80, 1);
    4.98 +  while (ctx->lenW != 56)
    4.99 +    SHA1_Update(ctx, &pad0x00, 1);
   4.100 +  SHA1_Update(ctx, padlen, 8);
   4.101 +
   4.102 +  /* Output hash
   4.103 +   */
   4.104 +  for (i = 0; i < 20; i++) {
   4.105 +    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
   4.106 +    ctx->H[i / 4] <<= 8;
   4.107 +  }
   4.108 +
   4.109 +  /*
   4.110 +   *  Re-initialize the context (also zeroizes contents)
   4.111 +   */
   4.112 +  SHA1_Init(ctx);
   4.113 +}
   4.114 +
   4.115 +
   4.116 +#define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
   4.117 +
   4.118 +static void shaHashBlock(SHA_CTX *ctx) {
   4.119 +  int t;
   4.120 +  unsigned int A,B,C,D,E,TEMP;
   4.121 +
   4.122 +  for (t = 16; t <= 79; t++)
   4.123 +    ctx->W[t] =
   4.124 +      SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
   4.125 +
   4.126 +  A = ctx->H[0];
   4.127 +  B = ctx->H[1];
   4.128 +  C = ctx->H[2];
   4.129 +  D = ctx->H[3];
   4.130 +  E = ctx->H[4];
   4.131 +
   4.132 +  for (t = 0; t <= 19; t++) {
   4.133 +    TEMP = SHA_ROT(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999;
   4.134 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   4.135 +  }
   4.136 +  for (t = 20; t <= 39; t++) {
   4.137 +    TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1;
   4.138 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   4.139 +  }
   4.140 +  for (t = 40; t <= 59; t++) {
   4.141 +    TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
   4.142 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   4.143 +  }
   4.144 +  for (t = 60; t <= 79; t++) {
   4.145 +    TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6;
   4.146 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   4.147 +  }
   4.148 +
   4.149 +  ctx->H[0] += A;
   4.150 +  ctx->H[1] += B;
   4.151 +  ctx->H[2] += C;
   4.152 +  ctx->H[3] += D;
   4.153 +  ctx->H[4] += E;
   4.154 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/sha1.h	Mon Sep 03 14:36:59 2007 -0400
     5.3 @@ -0,0 +1,45 @@
     5.4 +/*
     5.5 + * The contents of this file are subject to the Mozilla Public
     5.6 + * License Version 1.1 (the "License"); you may not use this file
     5.7 + * except in compliance with the License. You may obtain a copy of
     5.8 + * the License at http://www.mozilla.org/MPL/
     5.9 + *
    5.10 + * Software distributed under the License is distributed on an "AS
    5.11 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
    5.12 + * implied. See the License for the specific language governing
    5.13 + * rights and limitations under the License.
    5.14 + *
    5.15 + * The Original Code is SHA 180-1 Header File
    5.16 + *
    5.17 + * The Initial Developer of the Original Code is Paul Kocher of
    5.18 + * Cryptography Research.  Portions created by Paul Kocher are
    5.19 + * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
    5.20 + * Rights Reserved.
    5.21 + *
    5.22 + * Contributor(s):
    5.23 + *
    5.24 + *     Paul Kocher
    5.25 + *
    5.26 + * Alternatively, the contents of this file may be used under the
    5.27 + * terms of the GNU General Public License Version 2 or later (the
    5.28 + * "GPL"), in which case the provisions of the GPL are applicable
    5.29 + * instead of those above.  If you wish to allow use of your
    5.30 + * version of this file only under the terms of the GPL and not to
    5.31 + * allow others to use your version of this file under the MPL,
    5.32 + * indicate your decision by deleting the provisions above and
    5.33 + * replace them with the notice and other provisions required by
    5.34 + * the GPL.  If you do not delete the provisions above, a recipient
    5.35 + * may use your version of this file under either the MPL or the
    5.36 + * GPL.
    5.37 + */
    5.38 +
    5.39 +typedef struct {
    5.40 +  unsigned int H[5];
    5.41 +  unsigned int W[80];
    5.42 +  int lenW;
    5.43 +  unsigned int sizeHi,sizeLo;
    5.44 +} SHA_CTX;
    5.45 +
    5.46 +void SHA1_Init(SHA_CTX *ctx);
    5.47 +void SHA1_Update(SHA_CTX *ctx, const void *dataIn, int len);
    5.48 +void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx);