dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | LICENSE

commit 8ef5e9d6666a818d610e1e1b1ffefa552f2c76f6
parent a54afccf81b4152c8767ea4eaee2f93e39ac9eba
Author: sin <sin@2f30.org>
Date:   Wed,  8 May 2019 01:14:33 +0100

Implement state file

Diffstat:
MMakefile | 2++
Astate.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astate.h | 4++++
3 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -13,6 +13,7 @@ HDR = \ misc.h \ queue.h \ snap.h \ + state.h \ tree.h \ COMMOBJ = \ @@ -27,6 +28,7 @@ COMMOBJ = \ misc.o \ pack.o \ snap.o \ + state.o \ unpack.o \ DCHECKOBJ = $(COMMOBJ) dup-check.o diff --git a/state.c b/state.c @@ -0,0 +1,140 @@ +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> + +#include "misc.h" +#include "state.h" + +#define VMIN 0 +#define VMAJ 1 +#define VMINMASK 0xff +#define VMAJSHIFT 8 +#define VMAJMASK 0xff + +#define CALGOSHIFT 16 +#define CALGOMASK 0x7 +#define CNONETYPE 0 +#define CSNAPPYTYPE 1 +#define CLZ4TYPE 2 + +#define EALGOSHIFT 19 +#define EALGOMASK 0x7 +#define ENONETYPE 0 +#define ECHACHATYPE 1 + +#define SHDRSIZE 8 + +/* misc helpers */ +extern int pack(unsigned char *, char *, ...); +extern int unpack(unsigned char *, char *, ...); + +struct shdr { + uint64_t flags; +}; + +/* Read state header */ +static int +unpackshdr(int fd, struct shdr *shdr) +{ + unsigned char buf[SHDRSIZE]; + int n; + + if (xread(fd, buf, sizeof(buf)) != sizeof(buf)) + return -1; + + n = unpack(buf, "q", &shdr->flags); + assert(n == sizeof(buf)); + return n; +} + +/* Write state header */ +static int +packshdr(int fd, struct shdr *shdr) +{ + unsigned char buf[SHDRSIZE]; + int n; + + n = pack(buf, "q", shdr->flags); + assert(n == SHDRSIZE); + if (xwrite(fd, buf, n) != n) + return -1; + return n; +} + +int +savestate(int fd, struct param *par) +{ + struct shdr shdr; + + /* Set version */ + shdr.flags = (VMAJ << VMAJSHIFT) | VMIN; + + /* Set compression type */ + if (strcasecmp(par->calgo, "none") == 0) + shdr.flags |= CNONETYPE << CALGOSHIFT; + else if (strcasecmp(par->calgo, "snappy") == 0) + shdr.flags |= CSNAPPYTYPE << CALGOSHIFT; + else if (strcasecmp(par->calgo, "lz4") == 0) + shdr.flags |= CLZ4TYPE << CALGOSHIFT; + else + return -1; + + /* Set encryption type */ + if (strcasecmp(par->ealgo, "none") == 0) + shdr.flags |= ENONETYPE << EALGOSHIFT; + else if (strcasecmp(par->ealgo, "XChaCha20-Poly1305") == 0) + shdr.flags |= ECHACHATYPE << EALGOSHIFT; + else + return -1; + + if (packshdr(fd, &shdr) < 0) + return -1; + return 0; +} + +int +loadstate(int fd, struct param *par) +{ + struct shdr shdr; + int algo; + + if (unpackshdr(fd, &shdr) < 0) + return -1; + + /* If the major version is different, the format is incompatible */ + if (((shdr.flags >> VMAJSHIFT) & VMAJMASK) != VMAJ) + return -1; + + /* Populate param compression algo */ + algo = (shdr.flags >> CALGOSHIFT) & CALGOMASK; + switch (algo) { + case CNONETYPE: + par->calgo = "none"; + break; + case CSNAPPYTYPE: + par->calgo = "snappy"; + break; + case CLZ4TYPE: + par->calgo = "lz4"; + break; + default: + return -1; + } + + /* Populate param encryption algo */ + algo = (shdr.flags >> EALGOSHIFT) & EALGOMASK; + switch (algo) { + case ENONETYPE: + par->ealgo = "none"; + break; + case ECHACHATYPE: + par->ealgo = "XChaCha20-Poly1305"; + break; + default: + return -1; + } + + return 0; +} diff --git a/state.h b/state.h @@ -0,0 +1,4 @@ +struct param { + char *calgo; + char *ealgo; +};