157 lines
3.6 KiB
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;
|
|
}
|