160 lines
3.2 KiB
C
160 lines
3.2 KiB
C
//
|
|
// Created by haraldwolff on 07.08.22.
|
|
//
|
|
|
|
#include <hash.h>
|
|
|
|
#include <getopt.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include <time.h>
|
|
|
|
int next_block(char *block, int blocksize);
|
|
|
|
int cntHashes = 25000;
|
|
int blockSize = 4096;
|
|
char sourcePath[FILENAME_MAX];
|
|
char destinationPath[FILENAME_MAX];
|
|
|
|
int srcFile = 0;
|
|
int dstFile = 1;
|
|
|
|
int pattern;
|
|
|
|
time_t lastUpdate;
|
|
|
|
int main(int argc, char *argv[]){
|
|
int opt, r;
|
|
char outline[128];
|
|
|
|
union {
|
|
uint64_t hash;
|
|
struct {
|
|
int32_t x;
|
|
int32_t y;
|
|
};
|
|
} hu;
|
|
|
|
while ((opt = getopt(argc, argv, "n:i:s:o:p:"))!=-1){
|
|
switch (opt){
|
|
case 'n':
|
|
cntHashes = strtol(optarg, NULL, 0);
|
|
break;
|
|
case 'i':
|
|
strncpy(sourcePath, optarg, sizeof(sourcePath));
|
|
break;
|
|
case 's':
|
|
blockSize = strtol(optarg, NULL, 0);
|
|
break;
|
|
case 'o':
|
|
strncpy(destinationPath, optarg, sizeof(destinationPath));
|
|
break;
|
|
case 'p':
|
|
pattern = strtol(optarg, NULL, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "calculating hashes over %d blocks of %d bytes size read from %s\nresults written to %s\n", cntHashes, blockSize, sourcePath, destinationPath);
|
|
fflush(stderr);
|
|
|
|
|
|
if (sourcePath[0])
|
|
{
|
|
srcFile = open(sourcePath, O_RDONLY );
|
|
if (srcFile < 0){
|
|
fprintf(stderr, "could not open source %s, errno = %d ( %s )\n", sourcePath, errno, strerror(errno));
|
|
|
|
fflush(stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
} else {
|
|
strcpy(sourcePath, "stdin");
|
|
}
|
|
|
|
if (destinationPath[0])
|
|
{
|
|
dstFile = open(destinationPath, O_RDWR | O_CREAT | O_TRUNC, S_IRWXO | S_IRWXG | S_IRWXU );
|
|
if (dstFile < 0){
|
|
fprintf(stderr, "could not open destination %s, errno = %d ( %s )\n", destinationPath, errno, strerror(errno));
|
|
fflush(stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
} else {
|
|
strcpy(destinationPath, "stdout");
|
|
}
|
|
|
|
char *block = malloc(blockSize);
|
|
if (!block)
|
|
{
|
|
fprintf(stderr, "could not allocate block memory\n");
|
|
fflush(stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
for (int n=0 ; n < cntHashes ; n++){
|
|
next_block(block, blockSize);
|
|
|
|
hu.hash = dhash( block, blockSize);
|
|
snprintf(outline, sizeof(outline), "%lx,%d,%d\n", hu.hash, hu.x, hu.y);
|
|
|
|
int ol = strlen(outline);
|
|
r = write( dstFile, outline, ol);
|
|
if (r != ol){
|
|
fprintf(stderr, "could not write hash pair to %s (write() returned %d)\n", destinationPath, r);
|
|
if (r == -1)
|
|
fprintf(stderr, "errno = %d ( %s )", errno, strerror(errno));
|
|
fflush(stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
time_t t = time(NULL);
|
|
if (lastUpdate != t){
|
|
lastUpdate = t;
|
|
fprintf(stderr, "\rprogress: %d%%", (100 * n / cntHashes));
|
|
fflush(stderr);
|
|
}
|
|
}
|
|
fprintf(stderr, "\n");
|
|
fflush(stderr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int create_pattern(char *block, int blocksize){
|
|
static uint64_t state;
|
|
uint64_t *b64 = (uint64_t*)block;
|
|
|
|
switch (pattern){
|
|
default:
|
|
if (!state)
|
|
state = 1;
|
|
break;
|
|
}
|
|
|
|
for (int n=0; n < (blocksize >> 3); n++)
|
|
{
|
|
*(b64++) = state;
|
|
}
|
|
|
|
state++;
|
|
return blocksize;
|
|
}
|
|
|
|
int next_block(char *block, int blocksize){
|
|
if (pattern)
|
|
return create_pattern(block, blocksize);
|
|
|
|
int r = read( srcFile, block, blocksize);
|
|
if (r != blocksize){
|
|
fprintf(stderr, "could not read block from source\n");
|
|
fflush(stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
return r;
|
|
} |