URI: 
       Implement state file - dedup - deduplicating backup program
  HTML git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
   DIR commit 8ef5e9d6666a818d610e1e1b1ffefa552f2c76f6
   DIR parent a54afccf81b4152c8767ea4eaee2f93e39ac9eba
  HTML Author: sin <sin@2f30.org>
       Date:   Wed,  8 May 2019 01:14:33 +0100
       
       Implement state file
       
       Diffstat:
         M Makefile                            |       2 ++
         A state.c                             |     140 +++++++++++++++++++++++++++++++
         A state.h                             |       4 ++++
       
       3 files changed, 146 insertions(+), 0 deletions(-)
       ---
   DIR 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
   DIR 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;
       +}
   DIR diff --git a/state.h b/state.h
       @@ -0,0 +1,4 @@
       +struct param {
       +        char *calgo;
       +        char *ealgo;
       +};