18b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* This file is derived from libdex project */
28b77a77e785f0e25b13016ed60770e521dc60e0bLogan
38b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*
48b77a77e785f0e25b13016ed60770e521dc60e0bLogan * Tweaked in various ways for Google/Android:
58b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Changed from .cpp to .c.
68b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Made argument to SHA1Update a const pointer, and enabled
78b77a77e785f0e25b13016ed60770e521dc60e0bLogan *    SHA1HANDSOFF.  This incurs a speed penalty but prevents us from
88b77a77e785f0e25b13016ed60770e521dc60e0bLogan *    trashing the input.
98b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Include <endian.h> to get endian info.
108b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Split a small piece into a header file.
118b77a77e785f0e25b13016ed60770e521dc60e0bLogan */
128b77a77e785f0e25b13016ed60770e521dc60e0bLogan
138b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*
148b77a77e785f0e25b13016ed60770e521dc60e0bLogansha1sum: inspired by md5sum.
158b77a77e785f0e25b13016ed60770e521dc60e0bLogan
168b77a77e785f0e25b13016ed60770e521dc60e0bLoganSHA-1 in C
178b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy Steve Reid <steve@edmweb.com>
188b77a77e785f0e25b13016ed60770e521dc60e0bLogan100% Public Domain
198b77a77e785f0e25b13016ed60770e521dc60e0bLogan
208b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
218b77a77e785f0e25b13016ed60770e521dc60e0bLoganModified 7/98
228b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy James H. Brown <jbrown@burgoyne.com>
238b77a77e785f0e25b13016ed60770e521dc60e0bLoganStill 100% Public Domain
248b77a77e785f0e25b13016ed60770e521dc60e0bLogan
258b77a77e785f0e25b13016ed60770e521dc60e0bLoganbit machines
268b77a77e785f0e25b13016ed60770e521dc60e0bLoganRoutine SHA1Update changed from
278b77a77e785f0e25b13016ed60770e521dc60e0bLogan    void SHA1Update(SHA1_CTX* context, unsigned char* data,
288b77a77e785f0e25b13016ed60770e521dc60e0bLogan      unsigned int len)
298b77a77e785f0e25b13016ed60770e521dc60e0bLoganto
308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    void SHA1Update(SHA1_CTX* context, unsigned char* data,
318b77a77e785f0e25b13016ed60770e521dc60e0bLogan      unsigned long len)
328b77a77e785f0e25b13016ed60770e521dc60e0bLogan
338b77a77e785f0e25b13016ed60770e521dc60e0bLoganThe 'len' parameter was declared an int which works fine on 32
348b77a77e785f0e25b13016ed60770e521dc60e0bLoganbit machines. However, on 16 bit machines an int is too small
358b77a77e785f0e25b13016ed60770e521dc60e0bLoganfor the shifts being done against it.  This caused the hash
368b77a77e785f0e25b13016ed60770e521dc60e0bLoganfunction to generate incorrect values if len was greater than
378b77a77e785f0e25b13016ed60770e521dc60e0bLogan8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
388b77a77e785f0e25b13016ed60770e521dc60e0bLogan
398b77a77e785f0e25b13016ed60770e521dc60e0bLoganSince the file IO in main() reads 16K at a time, any file 8K or
408b77a77e785f0e25b13016ed60770e521dc60e0bLoganlarger would be guaranteed to generate the wrong hash (e.g.
418b77a77e785f0e25b13016ed60770e521dc60e0bLoganTest Vector #3, a million "a"s).
428b77a77e785f0e25b13016ed60770e521dc60e0bLogan
438b77a77e785f0e25b13016ed60770e521dc60e0bLoganI also changed the declaration of variables i & j in SHA1Update
448b77a77e785f0e25b13016ed60770e521dc60e0bLoganto unsigned long from unsigned int for the same reason.
458b77a77e785f0e25b13016ed60770e521dc60e0bLogan
468b77a77e785f0e25b13016ed60770e521dc60e0bLoganThese changes should make no difference to any 32 bit
478b77a77e785f0e25b13016ed60770e521dc60e0bLoganimplementations since an int and a long are the same size in
488b77a77e785f0e25b13016ed60770e521dc60e0bLoganthose environments.
498b77a77e785f0e25b13016ed60770e521dc60e0bLogan
508b77a77e785f0e25b13016ed60770e521dc60e0bLogan--
518b77a77e785f0e25b13016ed60770e521dc60e0bLoganI also corrected a few compiler warnings generated by Borland
528b77a77e785f0e25b13016ed60770e521dc60e0bLoganC.
538b77a77e785f0e25b13016ed60770e521dc60e0bLogan1. Added #include <process.h> for exit() prototype
548b77a77e785f0e25b13016ed60770e521dc60e0bLogan2. Removed unused variable 'j' in SHA1Final
558b77a77e785f0e25b13016ed60770e521dc60e0bLogan3. Changed exit(0) to return(0) at end of main.
568b77a77e785f0e25b13016ed60770e521dc60e0bLogan
578b77a77e785f0e25b13016ed60770e521dc60e0bLoganALL changes I made can be located by searching for comments
588b77a77e785f0e25b13016ed60770e521dc60e0bLogancontaining 'JHB'
598b77a77e785f0e25b13016ed60770e521dc60e0bLogan
608b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
618b77a77e785f0e25b13016ed60770e521dc60e0bLoganModified 13 August 2000
628b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy Michael Paul Johnson <mpj@cryptography.org>
638b77a77e785f0e25b13016ed60770e521dc60e0bLoganStill 100% Public Domain
648b77a77e785f0e25b13016ed60770e521dc60e0bLogan
658b77a77e785f0e25b13016ed60770e521dc60e0bLoganChanged command line syntax, added feature to automatically
668b77a77e785f0e25b13016ed60770e521dc60e0bLogancheck files against their previous SHA-1 check values, kind of
678b77a77e785f0e25b13016ed60770e521dc60e0bLoganlike md5sum does. Added functions hexval, verifyfile,
688b77a77e785f0e25b13016ed60770e521dc60e0bLoganand sha1file. Rewrote main().
698b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
708b77a77e785f0e25b13016ed60770e521dc60e0bLogan
718b77a77e785f0e25b13016ed60770e521dc60e0bLoganTest Vectors (from FIPS PUB 180-1)
728b77a77e785f0e25b13016ed60770e521dc60e0bLogan"abc"
738b77a77e785f0e25b13016ed60770e521dc60e0bLogan  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
748b77a77e785f0e25b13016ed60770e521dc60e0bLogan"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
758b77a77e785f0e25b13016ed60770e521dc60e0bLogan  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
768b77a77e785f0e25b13016ed60770e521dc60e0bLoganA million repetitions of "a"
778b77a77e785f0e25b13016ed60770e521dc60e0bLogan  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
788b77a77e785f0e25b13016ed60770e521dc60e0bLogan*/
798b77a77e785f0e25b13016ed60770e521dc60e0bLogan
808b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define SHA1HANDSOFF    /*Copies data before messing with it.*/
818b77a77e785f0e25b13016ed60770e521dc60e0bLogan
828b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*#define CMDLINE        * include main() and file processing */
835de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//#ifdef CMDLINE
845de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//# undef CMDLINE         /* Never include main() for libbcc */
855de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//#endif
868b77a77e785f0e25b13016ed60770e521dc60e0bLogan
878b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include "sha1.h"
888b77a77e785f0e25b13016ed60770e521dc60e0bLogan
898b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <stdio.h>
908b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <string.h>
918b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
928b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <dir.h>
938b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <dos.h>
948b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <process.h>   /*  prototype for exit() - JHB
958b77a77e785f0e25b13016ed60770e521dc60e0bLogan               needed for Win32, but chokes Linux - MPJ */
968b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define X_LITTLE_ENDIAN /* This should be #define'd if true.*/
978b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
988b77a77e785f0e25b13016ed60770e521dc60e0bLogan# define X_LITTLE_ENDIAN
998b77a77e785f0e25b13016ed60770e521dc60e0bLogan# include <unistd.h>
1008b77a77e785f0e25b13016ed60770e521dc60e0bLogan# include <stdlib.h>
1018b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1028b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <ctype.h>
1038b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1048b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define LINESIZE 2048
1058b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1068b77a77e785f0e25b13016ed60770e521dc60e0bLoganstatic void SHA1Transform(unsigned long state[5],
1078b77a77e785f0e25b13016ed60770e521dc60e0bLogan    const unsigned char buffer[64]);
1088b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1098b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define rol(value,bits) \
1108b77a77e785f0e25b13016ed60770e521dc60e0bLogan (((value)<<(bits))|((value)>>(32-(bits))))
1118b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1128b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* blk0() and blk() perform the initial expand. */
1138b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* I got the idea of expanding during the round function from
1148b77a77e785f0e25b13016ed60770e521dc60e0bLogan   SSLeay */
1158b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef X_LITTLE_ENDIAN
1168b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk0(i) (block->l[i]=(rol(block->l[i],24)&0xFF00FF00) \
1178b77a77e785f0e25b13016ed60770e521dc60e0bLogan    |(rol(block->l[i],8)&0x00FF00FF))
1188b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
1198b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk0(i) block->l[i]
1208b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1218b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
1228b77a77e785f0e25b13016ed60770e521dc60e0bLogan    ^block->l[(i+2)&15]^block->l[i&15],1))
1238b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1248b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
1258b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
1268b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
1278b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
1288b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
1298b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
1308b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1318b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1328b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Hash a single 512-bit block. This is the core of the algorithm. */
1338b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1348b77a77e785f0e25b13016ed60770e521dc60e0bLoganstatic void SHA1Transform(unsigned long state[5],
1358b77a77e785f0e25b13016ed60770e521dc60e0bLogan    const unsigned char buffer[64])
1368b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
1378b77a77e785f0e25b13016ed60770e521dc60e0bLoganunsigned long a, b, c, d, e;
1388b77a77e785f0e25b13016ed60770e521dc60e0bLogantypedef union {
1398b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char c[64];
1408b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned long l[16];
1418b77a77e785f0e25b13016ed60770e521dc60e0bLogan} CHAR64LONG16;
1428b77a77e785f0e25b13016ed60770e521dc60e0bLoganCHAR64LONG16* block;
1438b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef SHA1HANDSOFF
1448b77a77e785f0e25b13016ed60770e521dc60e0bLoganstatic unsigned char workspace[64];
1458b77a77e785f0e25b13016ed60770e521dc60e0bLogan    block = (CHAR64LONG16*)workspace;
1468b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memcpy(block, buffer, 64);
1478b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
1488b77a77e785f0e25b13016ed60770e521dc60e0bLogan    block = (CHAR64LONG16*)buffer;
1498b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1508b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Copy context->state[] to working vars */
1518b77a77e785f0e25b13016ed60770e521dc60e0bLogan    a = state[0];
1528b77a77e785f0e25b13016ed60770e521dc60e0bLogan    b = state[1];
1538b77a77e785f0e25b13016ed60770e521dc60e0bLogan    c = state[2];
1548b77a77e785f0e25b13016ed60770e521dc60e0bLogan    d = state[3];
1558b77a77e785f0e25b13016ed60770e521dc60e0bLogan    e = state[4];
1568b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* 4 rounds of 20 operations each. Loop unrolled. */
1578b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2);
1588b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5);
1598b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8);
1608b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
1618b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14);
1628b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17);
1638b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20);
1648b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
1658b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26);
1668b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29);
1678b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32);
1688b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
1698b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38);
1708b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41);
1718b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44);
1728b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
1738b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50);
1748b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53);
1758b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56);
1768b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
1778b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62);
1788b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65);
1798b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68);
1808b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
1818b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74);
1828b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77);
1838b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
1848b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1858b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Add the working vars back into context.state[] */
1868b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[0] += a;
1878b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[1] += b;
1888b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[2] += c;
1898b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[3] += d;
1908b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[4] += e;
1918b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Wipe variables */
1928b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*    a = b = c = d = e = 0; Nice try, but the compiler
1938b77a77e785f0e25b13016ed60770e521dc60e0bLoganoptimizes this out, anyway, and it produces an annoying
1948b77a77e785f0e25b13016ed60770e521dc60e0bLoganwarning. */
1958b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
1968b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1978b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1988b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* SHA1Init - Initialize new context */
1998b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2008b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid SHA1Init(SHA1_CTX* context)
2018b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2028b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* SHA1 initialization constants */
2038b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[0] = 0x67452301;
2048b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[1] = 0xEFCDAB89;
2058b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[2] = 0x98BADCFE;
2068b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[3] = 0x10325476;
2078b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[4] = 0xC3D2E1F0;
2088b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->count[0] = context->count[1] = 0;
2098b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2108b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2118b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2128b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Run your data through this. */
2138b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2148b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid SHA1Update(SHA1_CTX* context, const unsigned char* data,
2158b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned long len)  /* JHB */
2168b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2178b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned long i, j; /* JHB */
2188b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2198b77a77e785f0e25b13016ed60770e521dc60e0bLogan    j = (context->count[0] >> 3) & 63;
2208b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if ((context->count[0] += len << 3) < (len << 3))
2218b77a77e785f0e25b13016ed60770e521dc60e0bLogan        context->count[1]++;
2228b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->count[1] += (len >> 29);
2238b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if ((j + len) > 63)
2248b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2258b77a77e785f0e25b13016ed60770e521dc60e0bLogan        memcpy(&context->buffer[j], data, (i = 64-j));
2268b77a77e785f0e25b13016ed60770e521dc60e0bLogan        SHA1Transform(context->state, context->buffer);
2278b77a77e785f0e25b13016ed60770e521dc60e0bLogan        for ( ; i + 63 < len; i += 64) {
2288b77a77e785f0e25b13016ed60770e521dc60e0bLogan            SHA1Transform(context->state, &data[i]);
2298b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
2308b77a77e785f0e25b13016ed60770e521dc60e0bLogan        j = 0;
2318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2328b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
2338b77a77e785f0e25b13016ed60770e521dc60e0bLogan        i = 0;
2348b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memcpy(&context->buffer[j], &data[i], len - i);
2358b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2368b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2378b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2388b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Add padding and return the message digest. */
2398b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2408b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid SHA1Final(unsigned char digest[HASHSIZE], SHA1_CTX*
2418b77a77e785f0e25b13016ed60770e521dc60e0bLogancontext)
2428b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2438b77a77e785f0e25b13016ed60770e521dc60e0bLoganunsigned long i;    /* JHB */
2448b77a77e785f0e25b13016ed60770e521dc60e0bLoganunsigned char finalcount[8];
2458b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2468b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 0; i < 8; i++)
2478b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2488b77a77e785f0e25b13016ed60770e521dc60e0bLogan        finalcount[i] = (unsigned char)((context->count[(i>=4?
2498b77a77e785f0e25b13016ed60770e521dc60e0bLogan            0:1)]>>((3-(i&3))*8))&255);
2508b77a77e785f0e25b13016ed60770e521dc60e0bLogan        /* Endian independent */
2518b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2528b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Update(context, (unsigned char *)"\200", 1);
2538b77a77e785f0e25b13016ed60770e521dc60e0bLogan    while ((context->count[0] & 504) != 448) {
2548b77a77e785f0e25b13016ed60770e521dc60e0bLogan        SHA1Update(context, (unsigned char *)"\0", 1);
2558b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2568b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Update(context, finalcount, 8);
2578b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Should cause a SHA1Transform() */
2588b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 0; i < HASHSIZE; i++) {
2598b77a77e785f0e25b13016ed60770e521dc60e0bLogan        digest[i] = (unsigned char)
2608b77a77e785f0e25b13016ed60770e521dc60e0bLogan         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
2618b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2628b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Wipe variables */
2638b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->buffer, 0, 64);
2648b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->state, 0, HASHSIZE);
2658b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->count, 0, 8);
2668b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(&finalcount, 0, 8);
2678b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef SHA1HANDSOFF
2688b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* make SHA1Transform overwrite it's own static vars */
2698b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Transform(context->state, context->buffer);
2708b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
2718b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2728b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2738b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2748b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2758b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef CMDLINE
2768b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2778b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* sha1file computes the SHA-1 hash of the named file and puts
2788b77a77e785f0e25b13016ed60770e521dc60e0bLogan   it in the 20-byte array digest. If fname is NULL, stdin is
2798b77a77e785f0e25b13016ed60770e521dc60e0bLogan   assumed.
2808b77a77e785f0e25b13016ed60770e521dc60e0bLogan*/
2818b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid sha1file(char *fname, unsigned char* digest)
2828b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2838b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int bytesread;
2848b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1_CTX context;
2858b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char buffer[16384];
2868b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE* f;
2878b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2888b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (fname)
2898b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2908b77a77e785f0e25b13016ed60770e521dc60e0bLogan        f = fopen(fname, "rb");
2918b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (!f)
2928b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
2938b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr, "Can't open %s\n", fname);
2948b77a77e785f0e25b13016ed60770e521dc60e0bLogan            memset(digest, 0, HASHSIZE);
2958b77a77e785f0e25b13016ed60770e521dc60e0bLogan            return;
2968b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
2978b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2988b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
2998b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3008b77a77e785f0e25b13016ed60770e521dc60e0bLogan        f = stdin;
3018b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3028b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Init(&context);
3038b77a77e785f0e25b13016ed60770e521dc60e0bLogan    while (!feof(f))
3048b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3058b77a77e785f0e25b13016ed60770e521dc60e0bLogan        bytesread = fread(buffer, 1, 16384, f);
3068b77a77e785f0e25b13016ed60770e521dc60e0bLogan        SHA1Update(&context, buffer, bytesread);
3078b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3088b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Final(digest, &context);
3098b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (fname)
3108b77a77e785f0e25b13016ed60770e521dc60e0bLogan        fclose(f);
3118b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3128b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3138b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Convert ASCII hexidecimal digit to 4-bit value. */
3148b77a77e785f0e25b13016ed60770e521dc60e0bLoganunsigned char hexval(char c)
3158b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
3168b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char h;
3178b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3188b77a77e785f0e25b13016ed60770e521dc60e0bLogan    c = toupper(c);
3198b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (c >= 'A')
3208b77a77e785f0e25b13016ed60770e521dc60e0bLogan        h = c - 'A' + 10;
3218b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
3228b77a77e785f0e25b13016ed60770e521dc60e0bLogan        h = c - '0';
3238b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return h;
3248b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3258b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3268b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Verify a file created with sha1sum by redirecting output
3278b77a77e785f0e25b13016ed60770e521dc60e0bLogan   to a file. */
3288b77a77e785f0e25b13016ed60770e521dc60e0bLoganint verifyfile(char *fname)
3298b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
3308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int j, k;
3318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int found = 0;
3328b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char digest[HASHSIZE];
3338b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char expected_digest[HASHSIZE];
3348b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE *checkfile;
3358b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char checkline[LINESIZE];
3368b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char *s;
3378b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char err;
3388b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3398b77a77e785f0e25b13016ed60770e521dc60e0bLogan    checkfile = fopen(fname, "rt");
3408b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (!checkfile)
3418b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3428b77a77e785f0e25b13016ed60770e521dc60e0bLogan        fprintf(stderr, "Can't open %s\n", fname);
3438b77a77e785f0e25b13016ed60770e521dc60e0bLogan        return(0);
3448b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3458b77a77e785f0e25b13016ed60770e521dc60e0bLogan    do
3468b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3478b77a77e785f0e25b13016ed60770e521dc60e0bLogan        s = fgets(checkline, LINESIZE, checkfile);
3488b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (s)
3498b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
3508b77a77e785f0e25b13016ed60770e521dc60e0bLogan            if ((strlen(checkline)>26)&&
3518b77a77e785f0e25b13016ed60770e521dc60e0bLogan                1 /*(!strncmp(checkline,"SHA1=", 5))*/)
3528b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
3538b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Overwrite newline. */
3548b77a77e785f0e25b13016ed60770e521dc60e0bLogan                checkline[strlen(checkline)-1]=0;
3558b77a77e785f0e25b13016ed60770e521dc60e0bLogan                found = 1;
3568b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3578b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Read expected check value. */
3588b77a77e785f0e25b13016ed60770e521dc60e0bLogan                for (k=0, j=5; k < HASHSIZE; k++)
3598b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3608b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    expected_digest[k]=hexval(checkline[j++]);
3618b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    expected_digest[k]=(expected_digest[k]<<4)
3628b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        +hexval(checkline[j++]);
3638b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3648b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3658b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Compute fingerprints */
3668b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = checkline+46;
3678b77a77e785f0e25b13016ed60770e521dc60e0bLogan                sha1file(s, digest);
3688b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3698b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Compare fingerprints */
3708b77a77e785f0e25b13016ed60770e521dc60e0bLogan                err = 0;
3718b77a77e785f0e25b13016ed60770e521dc60e0bLogan                for (k=0; k<HASHSIZE; k++)
3728b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    err |= digest[k]-
3738b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        expected_digest[k];
3748b77a77e785f0e25b13016ed60770e521dc60e0bLogan                if (err)
3758b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3768b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr, "FAILED: %s\n"
3778b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        " EXPECTED: ", s);
3788b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (k=0; k<HASHSIZE; k++)
3798b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        fprintf(stderr, "%02X",
3808b77a77e785f0e25b13016ed60770e521dc60e0bLogan                            expected_digest[k]);
3818b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr,"\n    FOUND: ");
3828b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (k=0; k<HASHSIZE; k++)
3838b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        fprintf(stderr, "%02X", digest[k]);
3848b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr, "\n");
3858b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3868b77a77e785f0e25b13016ed60770e521dc60e0bLogan                else
3878b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3888b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    printf("OK: %s\n", s);
3898b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3908b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
3918b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
3928b77a77e785f0e25b13016ed60770e521dc60e0bLogan    } while (s);
3938b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return found;
3948b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3958b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3968b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3978b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3988b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid syntax(char *progname)
3998b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
4008b77a77e785f0e25b13016ed60770e521dc60e0bLogan    printf("\nsyntax:\n"
4018b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "%s [-c|-h][-q] file name[s]\n"
4028b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -c = check files against previous check values\n"
4038b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -g = generate SHA-1 check values (default action)\n"
4048b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -h = display this help\n"
4058b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "For example,\n"
4068b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "sha1sum test.txt > check.txt\n"
4078b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "generates check value for test.txt in check.txt, and\n"
4088b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "sha1sum -c check.txt\n"
4098b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "checks test.txt against the check value in check.txt\n",
4108b77a77e785f0e25b13016ed60770e521dc60e0bLogan     progname);
4118b77a77e785f0e25b13016ed60770e521dc60e0bLogan    exit(1);
4128b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
4138b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4148b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4158b77a77e785f0e25b13016ed60770e521dc60e0bLogan/**********************************************************/
4168b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4178b77a77e785f0e25b13016ed60770e521dc60e0bLoganint main(int argc, char** argv)
4188b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
4198b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int i, j, k;
4208b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int check = 0;
4218b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int found = 0;
4228b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char digest[HASHSIZE];
4238b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char expected_digest[HASHSIZE];
4248b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE *checkfile;
4258b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char checkline[LINESIZE];
4268b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char *s;
4278b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
4288b77a77e785f0e25b13016ed60770e521dc60e0bLogan    struct ffblk f;
4298b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int done;
4308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char path[MAXPATH];
4318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char drive[MAXDRIVE];
4328b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char dir[MAXDIR];
4338b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char name[MAXFILE];
4348b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char ext[MAXEXT];
4358b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
4368b77a77e785f0e25b13016ed60770e521dc60e0bLogan    unsigned char err;
43726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    const char *binary_output_file = 0;
4385de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen
4398b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 1; i < argc; i++)
4408b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
4418b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (argv[i][0] == '-')
4428b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
4438b77a77e785f0e25b13016ed60770e521dc60e0bLogan            switch (argv[i][1])
4448b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
44526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                case 'B':
44626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    ++i;
44726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    binary_output_file = argv[i];
44826fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    break;
4498b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'c':
4508b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'C':
4518b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    check = 1;
4528b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    break;
4538b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'g':
4548b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'G':
4558b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    check = 0;
4568b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    break;
4578b77a77e785f0e25b13016ed60770e521dc60e0bLogan                default:
4588b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    syntax(argv[0]);
4598b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
4608b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
4618b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
4628b77a77e785f0e25b13016ed60770e521dc60e0bLogan
46326fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    // Read from STDIN
46426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    sha1file(NULL, digest);
46526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    if (binary_output_file) {
46626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      FILE *fout = fopen(binary_output_file, "wb");
46726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      if (!fout) {
46826fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        fprintf(stderr, "Error: Can not write to %s.\n", binary_output_file);
46926fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        return 1;
47026fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      }
47126fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      fwrite(digest, 1, HASHSIZE, fout);
47226fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      fclose(fout);
47326fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      return 0;
47426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    }
47526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    for (j = 0; j < HASHSIZE; j++)
47626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        printf("%02x", digest[j]);
47726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    return 0;
47826fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang
4798b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i=1; i<argc; i++)
4808b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
4818b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (argv[i][0] != '-')
4828b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
4838b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
4848b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fnsplit(argv[i], drive, dir, name, ext);
4858b77a77e785f0e25b13016ed60770e521dc60e0bLogan            done = findfirst(argv[i], &f, FA_RDONLY |
4868b77a77e785f0e25b13016ed60770e521dc60e0bLogan                FA_HIDDEN|FA_SYSTEM|FA_ARCH);
4878b77a77e785f0e25b13016ed60770e521dc60e0bLogan             while (!done)
4888b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
4898b77a77e785f0e25b13016ed60770e521dc60e0bLogan                sprintf(path, "%s%s%s", drive, dir, f.ff_name);
4908b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = path;
4918b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
4928b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = argv[i];
4938b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
4948b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4958b77a77e785f0e25b13016ed60770e521dc60e0bLogan                if (check)
4968b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {   /* Check fingerprint file. */
4978b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    found |= verifyfile(s);
4988b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
4998b77a77e785f0e25b13016ed60770e521dc60e0bLogan                else
5008b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {   /* Generate fingerprints & write to
5018b77a77e785f0e25b13016ed60770e521dc60e0bLogan                       stdout. */
5028b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    sha1file(s, digest);
5038b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    //printf("SHA1=");
5048b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (j=0; j<HASHSIZE; j++)
5058b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        printf("%02x", digest[j]);
5068b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    printf("  %s\n", s);
5078b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    found = 1;
5088b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
5098b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5108b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
5118b77a77e785f0e25b13016ed60770e521dc60e0bLogan                done = findnext(&f);
5128b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
5138b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
5148b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5158b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5168b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
5178b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (!found)
5188b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
5198b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (check)
5208b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
5218b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr,
5228b77a77e785f0e25b13016ed60770e521dc60e0bLogan                "No SHA1 lines found in %s\n",
5238b77a77e785f0e25b13016ed60770e521dc60e0bLogan                argv[i]);
5248b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5258b77a77e785f0e25b13016ed60770e521dc60e0bLogan        else
5268b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
5278b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr, "No files checked.\n");
5288b77a77e785f0e25b13016ed60770e521dc60e0bLogan            syntax(argv[0]);
5298b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
5318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return(0);  /* JHB */
5328b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
5338b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5348b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif  /*CMDLINE*/
535