/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */ /* * oshash.c -- generate oshash for provided files * Copyright (C) 2011-2012 Jan Gerber * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with This program. If not, see . */ #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #if !defined(_LARGEFILE_SOURCE) #define _LARGEFILE_SOURCE #endif #if !defined(_LARGEFILE64_SOURCE) #define _LARGEFILE64_SOURCE #endif #if !defined(_FILE_OFFSET_BITS) #define _FILE_OFFSET_BITS 64 #endif #include #include #include #include #include #include #include #include #ifndef WIN32 #if !defined(off64_t) #define off64_t off_t #endif #endif #ifdef WIN32 #define fseeko fseeko64 #define ftello ftello64 #endif #ifdef _BIG_ENDIAN #define htonll(x) \ ((((x) & 0xff00000000000000LL) >> 56) | \ (((x) & 0x00ff000000000000LL) >> 40) | \ (((x) & 0x0000ff0000000000LL) >> 24) | \ (((x) & 0x000000ff00000000LL) >> 8) | \ (((x) & 0x00000000ff000000LL) << 8) | \ (((x) & 0x0000000000ff0000LL) << 24) | \ (((x) & 0x000000000000ff00LL) << 40) | \ (((x) & 0x00000000000000ffLL) << 56)) #else #define htonll(x) x #endif /* * os hash * based on public domain example from * http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes * * plus modification for files < 64k, buffer is filled with file data and padded with 0 */ unsigned long long gen_oshash(char const *filename) { FILE *file; int i; unsigned long long t1=0; unsigned long long buffer1[8192*2]; int used = 8192*2; file = fopen(filename, "rb"); if (file) { //add filesize fseeko(file, 0, SEEK_END); t1 = ftello(file); fseeko(file, 0, SEEK_SET); if(t1 < 65536) { used = t1/8; fread(buffer1, used, 8, file); } else { fread(buffer1, 8192, 8, file); fseeko(file, -65536, SEEK_END); fread(&buffer1[8192], 8192, 8, file); } for (i=0; i < used; i++) t1+=htonll(buffer1[i]); fclose(file); } return t1; } int print_oshash(FILE *output, char const *filename) { char hash[32]; #ifdef WIN32 sprintf(hash, "%016I64x", gen_oshash(filename)); #elif defined (__SVR4) && defined (__sun) sprintf(hash,"%016llx", gen_oshash(filename)); #else sprintf(hash, "%016qx", gen_oshash(filename)); #endif if (strcmp(hash,"0000000000000000") > 0) { fprintf(output, "%s %s\n", hash, filename); return 0; } else { fprintf(stderr,"%s: No such file or permission denied\n",filename); return 1; } } int main(int argc, char **argv) { int i,r=0; FILE* output = stdout; if(argc == 1) { fprintf(stderr, "usage: %s [filename]\n", argv[0]); exit(1); } for(i=1;i0?1:0; }