sparse-tools/src/bs_tools.c

157 lines
3.6 KiB
C

//
// Created by haraldwolff on 07.08.22.
//
#include <blksync.h>
#define _LARGEFILE64_SOURCE
#include <sys/types.h>
#include <unistd.h>
typedef struct {
int hours;
int minutes;
int seconds;
} bs_time_t;
char* units[] = { "B", "kB", "MB", "GB", "TB" };
char* ntounit(long l, char *p){
static char _buffer[64];
if (!p)
p = _buffer;
int up = 0;
while ((l > 1024) && (up < 5)){
l /= 1024;
up++;
}
snprintf(p, sizeof(_buffer), "%ld %s", l, units[up]);
return p;
}
void bs_time_set(bs_time_t* dst, int seconds){
dst->hours = seconds / 3600;
dst->minutes = (seconds % 3600) / 60;
dst->seconds = seconds % 60;
}
int read_block(bsync_engine_t *engine, long offset, char *block, int blocksize){
while (pthread_mutex_lock(&engine->m_file));
long r = lseek( engine->file, offset, SEEK_SET);
if ((r == -1) || (r != offset)){
fprintf(stderr, "read_block(): could not seek to offset 0x%lx, lseek() returned 0x%lx\n", offset, r);
if (r == -1){
fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno));
dump_engine(engine);
}
fflush(stderr);
return -1;
}
r = read( engine->file, block, blocksize);
if (r != blocksize){
fprintf(stderr, "read_block(): failed to read block at offset 0x%lx, read() returned %d\n", offset, r);
if (r < 0){
fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno));
}
fflush(stderr);
return -1;
}
while (pthread_mutex_unlock(&engine->m_file));
if (engine->ds_flags & DS_DUMPBLOCKS){
fprintf( stderr, "BLOCK (%d bytes): ", blocksize);
for (int n=0;n<blocksize; n++){
fprintf(stderr, "%02hhx", block[n]);
}
fprintf(stderr, "\n");
fflush(stderr);
}
return blocksize;
}
int write_block(bsync_engine_t *engine, long offset, char *block, int blocksize)
{
while (pthread_mutex_lock(&engine->m_file));
long r = lseek( engine->file, offset, SEEK_SET);
if ((r == -1) || (r != offset)){
fprintf(stderr, "write_block(): could not seek to offset 0x%lx, lseek() returned 0x%lx\n", offset, r);
if (r == -1){
fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno));
dump_engine(engine);
}
fflush(stderr);
return -1;
}
r = write( engine->file, block, blocksize);
if (r != blocksize){
fprintf(stderr, "write_block(): failed to write block at offset 0x%lx, write() returned %d\n", offset, r);
if (r < 0){
fprintf(stderr, "errno = %d (%s)\n", errno, strerror(errno));
}
fflush(stderr);
return -1;
}
while (pthread_mutex_unlock(&engine->m_file));
return blocksize;
}
int bs_recv(int socket, void *buffer, int size){
int residue = size;
while (residue){
int s = recv(socket, buffer, residue, 0);
if (s < 0)
return s;
buffer += s;
residue -= s;
}
return size;
}
int bs_send(int socket, const void *buffer, int size){
int residue = size;
while (residue){
int s = send(socket, buffer, residue, 0);
if (s < 0)
return s;
buffer += s;
residue -= s;
}
return size;
}
int dump_engine_state(bsync_engine_t *engine){
char _b[32];
time_t now = time(NULL);
time_t d = now - engine->t_start;
int percentage = engine->filesize ? 100 * engine->last_offset / engine->filesize : 0;
bs_time_t t, r;
bs_time_set(&t, d);
bs_time_set(&r, engine->last_offset ? d * engine->filesize / engine->last_offset : 0);
long syncspeed = d ? engine->stat_block_bytes / d : 0;
fprintf(stderr,"\rS=0x%016lx O=0x%016lx P=%d%% T=%02d:%02d:%02d R=%02d:%02d:%02d N=%ld V=%s VS=%s/s",
engine->filesize,
engine->last_offset,
percentage,
t.hours, t.minutes, t.seconds,
r.hours, r.minutes, r.seconds,
engine->stat_blocks,
ntounit(engine->stat_block_bytes, NULL),
ntounit(syncspeed, _b)
);
engine->t_last_update = now;
}