hashcalc-plain.c (2644B)
1 // $Id$ --*- c -*-- 2 3 // Copyright (C) 2006 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; version 2 of the License. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 #ifdef HAVE_CONFIG_H 20 # include <config.h> 21 #endif 22 23 #include <lib_internal/crypto-wrapper.h> 24 #include <stdbool.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <sys/stat.h> 28 #include <sys/mman.h> 29 30 #define ENSC_TESTSUITE 31 #include "lib_internal/coreassert.h" 32 33 #define HASH_BLOCKSIZE 0x10000000u 34 35 static bool 36 convertDigest(char res[], ensc_hash_context * h_ctx) 37 { 38 static char const HEX_DIGIT[] = "0123456789abcdef"; 39 size_t d_size = ensc_crypto_hashctx_get_digestsize(h_ctx); 40 41 unsigned char digest[d_size]; 42 size_t out = 0; 43 44 if (ensc_crypto_hashctx_get_digest(h_ctx, digest, NULL, d_size)==-1) 45 return false; 46 47 for (size_t in=0; in<d_size; ++in) { 48 res[out++] = HEX_DIGIT[digest[in] >> 4]; 49 res[out++] = HEX_DIGIT[digest[in] & 0x0f]; 50 } 51 res[out++] = '\0'; 52 53 return true; 54 } 55 56 int main(int UNUSED argc, char *argv[]) 57 { 58 int fd = open(argv[1], O_NOFOLLOW|O_NONBLOCK|O_RDONLY|O_NOCTTY); 59 ensc_hash_context hash_context; 60 ensc_hash_method const *method; 61 struct stat st; 62 off_t size; 63 loff_t offset = 0; 64 char digest[2048]; 65 66 ensc_crypto_init(); 67 assert((method = ensc_crypto_hash_find(argv[2]))!=0); 68 assert(ensc_crypto_hashctx_init(&hash_context, method)!=-1); 69 70 assert(fstat(fd, &st)!=-1); 71 assert(ensc_crypto_hashctx_reset(&hash_context)!=-1); 72 73 size = st.st_size; 74 75 while (offset < size) { 76 loff_t volatile buf_size = size-offset; 77 void const * buf; 78 if (buf_size>HASH_BLOCKSIZE) buf_size = HASH_BLOCKSIZE; 79 80 assert((buf=mmap(0, buf_size, PROT_READ, MAP_SHARED, fd, offset))!=MAP_FAILED); 81 offset += buf_size; 82 assert(ensc_crypto_hashctx_update(&hash_context, buf, buf_size)!=-1); 83 munmap((void *)(buf), buf_size); 84 } 85 86 assert(convertDigest(digest, &hash_context)); 87 88 Vwrite(1, digest, strlen(digest)); 89 Vwrite(1, "\n", 1); 90 91 ensc_crypto_hashctx_free(&hash_context); 92 93 return 0; 94 }