dedup

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

commit 6b21cc335d619eb1bdf2ea285087e98e4c78d7e4
parent 8ef5e9d6666a818d610e1e1b1ffefa552f2c76f6
Author: sin <sin@2f30.org>
Date:   Sun, 12 May 2019 10:03:14 +0100

Use a state file to store repository settings

Diffstat:
Mbcompress.c | 32++++++++++++++++++--------------
Mbencrypt.c | 37+++++++++++++++++++------------------
Mblock.c | 25+++++--------------------
Mblock.h | 15++++-----------
Mbstorage.c | 80++++---------------------------------------------------------------------------
Mdup-check.c | 61+++++++++++++++++++++++++++++++++++++++++++------------------
Mdup-gc.c | 61+++++++++++++++++++++++++++++++++++++++++++------------------
Mdup-init.c | 66++++++++++++++++++++++++++++++++++++++++++++----------------------
Mdup-keygen.c | 2++
Mdup-pack.c | 60+++++++++++++++++++++++++++++++++++++++++++-----------------
Mdup-rm.c | 60+++++++++++++++++++++++++++++++++++++++++++-----------------
Mdup-unpack.c | 60+++++++++++++++++++++++++++++++++++++++++++-----------------
Mstate.c | 1+
Mstate.h | 5+++++
14 files changed, 317 insertions(+), 248 deletions(-)

diff --git a/bcompress.c b/bcompress.c @@ -16,17 +16,21 @@ #include <snappy-c.h> #include "block.h" +#include "config.h" +#include "state.h" #define CDNONETYPE 0x200 #define CDSNAPPYTYPE 0x201 #define CDLZ4TYPE 0x202 #define CDSIZE (8 + 8) +extern struct param param; + extern int pack(unsigned char *, char *, ...); extern int unpack(unsigned char *, char *, ...); -static int bccreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar); -static int bcopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar); +static int bccreat(struct bctx *bctx, char *path, int mode); +static int bcopen(struct bctx *bctx, char *path, int flags, int mode); static int bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); static int bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); static int bcrm(struct bctx *bctx, unsigned char *md); @@ -90,19 +94,19 @@ packcd(void *buf, struct cd *cd) } static int -bccreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) +bccreat(struct bctx *bctx, char *path, int mode) { struct cctx *cctx; int type; - if (strcasecmp(bpar->calgo, "none") == 0) { + if (strcasecmp(param.calgo, "none") == 0) { type = CDNONETYPE; - } else if (strcasecmp(bpar->calgo, "snappy") == 0) { + } else if (strcasecmp(param.calgo, "snappy") == 0) { type = CDSNAPPYTYPE; - } else if (strcasecmp(bpar->calgo, "lz4") == 0) { + } else if (strcasecmp(param.calgo, "lz4") == 0) { type = CDLZ4TYPE; } else { - bseterr("invalid compression type: %s", bpar->calgo); + bseterr("invalid compression type: %s", param.calgo); return -1; } @@ -114,7 +118,7 @@ bccreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) cctx = bctx->cctx; cctx->type = type; - if (bencryptops()->creat(bctx, path, mode, bpar) < 0) { + if (bencryptops()->creat(bctx, path, mode) < 0) { free(cctx); return -1; } @@ -122,7 +126,7 @@ bccreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) } static int -bcopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) +bcopen(struct bctx *bctx, char *path, int flags, int mode) { struct cctx *cctx; @@ -133,21 +137,21 @@ bcopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) } cctx = bctx->cctx; - if (bencryptops()->open(bctx, path, flags, mode, bpar) < 0) { + if (bencryptops()->open(bctx, path, flags, mode) < 0) { free(cctx); return -1; } - if (strcasecmp(bpar->calgo, "none") == 0) { + if (strcasecmp(param.calgo, "none") == 0) { cctx->type = CDNONETYPE; - } else if (strcasecmp(bpar->calgo, "snappy") == 0) { + } else if (strcasecmp(param.calgo, "snappy") == 0) { cctx->type = CDSNAPPYTYPE; - } else if (strcasecmp(bpar->calgo, "lz4") == 0) { + } else if (strcasecmp(param.calgo, "lz4") == 0) { cctx->type = CDLZ4TYPE; } else { bencryptops()->close(bctx); free(cctx); - bseterr("invalid compression type: %s", bpar->calgo); + bseterr("invalid compression type: %s", param.calgo); return -1; } return 0; diff --git a/bencrypt.c b/bencrypt.c @@ -16,6 +16,9 @@ #include "block.h" #include "config.h" +#include "state.h" + +extern struct param param; #define EDNONETYPE 0x300 #define EDCHACHATYPE 0x301 @@ -24,8 +27,8 @@ extern int pack(unsigned char *, char *, ...); extern int unpack(unsigned char *, char *, ...); -static int becreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar); -static int beopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar); +static int becreat(struct bctx *bctx, char *path, int mode); +static int beopen(struct bctx *bctx, char *path, int flags, int mode); static int beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); static int beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); static int berm(struct bctx *bctx, unsigned char *md); @@ -93,23 +96,23 @@ packed(void *buf, struct ed *ed) } static int -becreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) +becreat(struct bctx *bctx, char *path, int mode) { struct ectx *ectx; int type; /* Determine algorithm type */ - if (strcasecmp(bpar->ealgo, "none") == 0) { + if (strcasecmp(param.ealgo, "none") == 0) { type = EDNONETYPE; - } else if (strcasecmp(bpar->ealgo, "XChaCha20-Poly1305") == 0) { + } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) { type = EDCHACHATYPE; } else { - bseterr("invalid encryption type: %s", bpar->ealgo); + bseterr("invalid encryption type: %s", param.ealgo); return -1; } /* Ensure that if caller requested encryption, a key was provided */ - if (type != EDNONETYPE && bpar->key == NULL) { + if (type != EDNONETYPE && !param.keyloaded) { bseterr("expected encryption key"); return -1; } @@ -126,10 +129,9 @@ becreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) } ectx = bctx->ectx; ectx->type = type; - if (bpar->key != NULL) - memcpy(ectx->key, bpar->key, KEYSIZE); + memcpy(ectx->key, param.key, KEYSIZE); - if (bstorageops()->creat(bctx, path, mode, bpar) < 0) { + if (bstorageops()->creat(bctx, path, mode) < 0) { free(ectx); return -1; } @@ -137,7 +139,7 @@ becreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) } static int -beopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) +beopen(struct bctx *bctx, char *path, int flags, int mode) { struct ectx *ectx; @@ -147,28 +149,27 @@ beopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) return -1; } ectx = bctx->ectx; - if (bpar->key != NULL) - memcpy(ectx->key, bpar->key, KEYSIZE); + memcpy(ectx->key, param.key, KEYSIZE); - if (bstorageops()->open(bctx, path, flags, mode, bpar) < 0) { + if (bstorageops()->open(bctx, path, flags, mode) < 0) { free(ectx); return -1; } /* Determine algorithm type */ - if (strcasecmp(bpar->ealgo, "none") == 0) + if (strcasecmp(param.ealgo, "none") == 0) ectx->type = EDNONETYPE; - else if (strcasecmp(bpar->ealgo, "XChaCha20-Poly1305") == 0) + else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) ectx->type = EDCHACHATYPE; else { bstorageops()->close(bctx); free(ectx); - bseterr("invalid encryption type: %s", bpar->ealgo); + bseterr("invalid encryption type: %s", param.ealgo); return -1; } /* Ensure that if repo is encrypted, a key was provided */ - if (ectx->type != EDNONETYPE && bpar->key == NULL) { + if (ectx->type != EDNONETYPE && !param.keyloaded) { bstorageops()->close(bctx); free(ectx); bseterr("expected encryption key"); diff --git a/block.c b/block.c @@ -16,7 +16,7 @@ static char errbuf[NERRBUF]; int -bcreat(char *path, int mode, struct bparam *bpar, struct bctx **bctx) +bcreat(char *path, int mode, struct bctx **bctx) { struct bops *bops; @@ -25,9 +25,6 @@ bcreat(char *path, int mode, struct bparam *bpar, struct bctx **bctx) return -1; } - if (bpar == NULL) - bpar = bparamdef(); - *bctx = calloc(1, sizeof(**bctx)); if (*bctx == NULL) { bseterr("calloc: %s", strerror(errno)); @@ -35,7 +32,7 @@ bcreat(char *path, int mode, struct bparam *bpar, struct bctx **bctx) } bops = bcompressops(); - if (bops->creat(*bctx, path, mode, bpar) < 0) { + if (bops->creat(*bctx, path, mode) < 0) { free(*bctx); return -1; } @@ -43,11 +40,11 @@ bcreat(char *path, int mode, struct bparam *bpar, struct bctx **bctx) } int -bopen(char *path, int flags, int mode, struct bparam *bpar, struct bctx **bctx) +bopen(char *path, int flags, int mode, struct bctx **bctx) { struct bops *bops; - if (path == NULL || bpar == NULL || bctx == NULL) { + if (path == NULL || bctx == NULL) { bseterr("invalid params"); return -1; } @@ -59,7 +56,7 @@ bopen(char *path, int flags, int mode, struct bparam *bpar, struct bctx **bctx) } bops = bcompressops(); - if (bops->open(*bctx, path, flags, mode, bpar) < 0) { + if (bops->open(*bctx, path, flags, mode) < 0) { free(*bctx); return -1; } @@ -169,18 +166,6 @@ bclose(struct bctx *bctx) return r; } -struct bparam * -bparamdef(void) -{ - static struct bparam bpar = { - .calgo = "snappy", - .ealgo = "none", - .key = NULL - }; - - return &bpar; -} - void bseterr(char *fmt, ...) { diff --git a/block.h b/block.h @@ -10,19 +10,13 @@ struct bctx { void *sctx; /* storage layer context */ }; -struct bparam { - char *calgo; - char *ealgo; - unsigned char *key; -}; - /* * Block operations structure. * This is implemented by each of the block layers. */ struct bops { - int (*creat)(struct bctx *, char *, int, struct bparam *); - int (*open)(struct bctx *, char *, int, int, struct bparam *); + int (*creat)(struct bctx *, char *, int); + int (*open)(struct bctx *, char *, int, int); int (*put)(struct bctx *, void *, size_t, unsigned char *); int (*get)(struct bctx *, unsigned char *, void *, size_t *); int (*rm)(struct bctx *, unsigned char *); @@ -33,8 +27,8 @@ struct bops { }; /* block.c */ -extern int bcreat(char *, int, struct bparam *, struct bctx **); -extern int bopen(char *, int, int, struct bparam *, struct bctx **); +extern int bcreat(char *, int, struct bctx **); +extern int bopen(char *, int, int, struct bctx **); extern int bput(struct bctx *, void *, size_t, unsigned char *); extern int bget(struct bctx *, unsigned char *, void *, size_t *); extern int brm(struct bctx *, unsigned char *); @@ -42,7 +36,6 @@ extern int bgc(struct bctx *); extern int bcheck(struct bctx *, unsigned char *); extern int bsync(struct bctx *); extern int bclose(struct bctx *); -extern struct bparam *bparamdef(void); extern void bseterr(char *, ...); extern void berr(char *, ...); diff --git a/bstorage.c b/bstorage.c @@ -40,17 +40,6 @@ #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 BHDRSIZE (NBHDRMAGIC + 8 + 8) /* block descriptor constants */ @@ -61,8 +50,8 @@ extern int pack(unsigned char *, char *, ...); extern int unpack(unsigned char *, char *, ...); -static int bscreat(struct bctx *, char *, int, struct bparam *); -static int bsopen(struct bctx *, char *, int, int, struct bparam *); +static int bscreat(struct bctx *, char *, int); +static int bsopen(struct bctx *, char *, int, int); static int bsput(struct bctx *, void *, size_t, unsigned char *); static int bsget(struct bctx *, unsigned char *, void *, size_t *); static int bsrm(struct bctx *, unsigned char *); @@ -307,7 +296,7 @@ initbdcache(struct sctx *sctx) /* Create storage file */ static int -bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) +bscreat(struct bctx *bctx, char *path, int mode) { struct sctx *sctx; struct bhdr *bhdr; @@ -339,32 +328,6 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) bhdr = &sctx->bhdr; memcpy(bhdr->magic, BHDRMAGIC, NBHDRMAGIC); bhdr->flags = (VMAJ << VMAJSHIFT) | VMIN; - - /* Set compression type */ - if (strcasecmp(bpar->calgo, "none") == 0) { - bhdr->flags |= CNONETYPE << CALGOSHIFT; - } else if (strcasecmp(bpar->calgo, "snappy") == 0) { - bhdr->flags |= CSNAPPYTYPE << CALGOSHIFT; - } else if (strcasecmp(bpar->calgo, "lz4") == 0) { - bhdr->flags |= CLZ4TYPE << CALGOSHIFT; - } else { - free(sctx); - close(fd); - bseterr("invalid compression type: %s", bpar->calgo); - return -1; - } - - /* Set encryption type */ - if (strcasecmp(bpar->ealgo, "none") == 0) { - bhdr->flags |= ENONETYPE << EALGOSHIFT; - } else if (strcasecmp(bpar->ealgo, "XChaCha20-Poly1305") == 0) { - bhdr->flags |= ECHACHATYPE << EALGOSHIFT; - } else { - free(sctx); - close(fd); - bseterr("invalid encryption type: %s", bpar->ealgo); - return -1; - } bhdr->nbd = 0; if (packbhdr(fd, bhdr) < 0) { @@ -377,7 +340,7 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar) /* Open storage file */ static int -bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) +bsopen(struct bctx *bctx, char *path, int flags, int mode) { struct sctx *sctx; struct bhdr *bhdr; @@ -439,41 +402,6 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar) return -1; } - /* Populate bparam compression algo */ - algo = (bhdr->flags >> CALGOSHIFT) & CALGOMASK; - switch (algo) { - case CNONETYPE: - bpar->calgo = "none"; - break; - case CSNAPPYTYPE: - bpar->calgo = "snappy"; - break; - case CLZ4TYPE: - bpar->calgo = "lz4"; - break; - default: - free(sctx); - close(fd); - bseterr("invalid compression type: %d", algo); - return -1; - } - - /* Populate bparam encryption algo */ - algo = (bhdr->flags >> EALGOSHIFT) & EALGOMASK; - switch (algo) { - case ENONETYPE: - bpar->ealgo = "none"; - break; - case ECHACHATYPE: - bpar->ealgo = "XChaCha20-Poly1305"; - break; - default: - free(sctx); - close(fd); - bseterr("invalid encryption type: %d", algo); - return -1; - } - sctx->fd = fd; sctx->rdonly = flags == O_RDONLY; diff --git a/dup-check.c b/dup-check.c @@ -16,11 +16,48 @@ #include "key.h" #include "lock.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDONLY); + if (fd < 0) + err(1, "open: %s", path); + if (loadstate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void check(struct sctx *sctx, struct bctx *bctx) { unsigned char md[MDSIZE]; @@ -56,10 +93,8 @@ main(int argc, char *argv[]) { char spath[PATH_MAX]; char bpath[PATH_MAX]; - unsigned char key[KEYSIZE]; struct sctx *sctx; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo = "."; int lfd; @@ -81,21 +116,6 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(spath, sizeof(spath), "%s/archive/%s", repo, argv[0]) >= sizeof(spath)) errx(1, "snprintf: %s: path too long", spath); @@ -105,9 +125,13 @@ main(int argc, char *argv[]) if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); + + initparam(repo); + initkey(keyfile); + if (sopen(spath, S_READ, 0600, &sctx) < 0) serr("sopen: %s", spath); - if (bopen(bpath, B_READ, 0600, &bpar, &bctx) <0) + if (bopen(bpath, B_READ, 0600, &bctx) <0) berr("bopen: %s", bpath); check(sctx, bctx); @@ -116,6 +140,7 @@ main(int argc, char *argv[]) berr("bclose: %s", bpath); if (sclose(sctx) < 0) serr("sclose: %s", spath); + if (unlockrepo(lfd) < 0) errx(1, "failed to unlock repository"); diff --git a/dup-gc.c b/dup-gc.c @@ -14,11 +14,48 @@ #include "key.h" #include "lock.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDONLY); + if (fd < 0) + err(1, "open: %s", path); + if (loadstate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void usage(void) { fprintf(stderr, "usage: %s [-v] [-k keyfile] [repo]\n", argv0); @@ -29,9 +66,7 @@ int main(int argc, char *argv[]) { char path[PATH_MAX]; - unsigned char key[KEYSIZE]; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo; int lfd; @@ -58,33 +93,23 @@ main(int argc, char *argv[]) usage(); }; - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(path, sizeof(path), "%s/%s", repo, STORAGEPATH) >= sizeof(path)) errx(1, "snprintf: %s: path too long", path); if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); - if (bopen(path, B_RDWR, 0600, &bpar, &bctx) < 0) + + initparam(repo); + initkey(keyfile); + + if (bopen(path, B_RDWR, 0600, &bctx) < 0) berr("bopen: %s", path); if (bgc(bctx) < 0) berr("bgc: %s", path); if (bclose(bctx) < 0) berr("bclose: %s", path); + if (unlockrepo(lfd) < 0) errx(1, "failed to unlock repository"); return 0; diff --git a/dup-init.c b/dup-init.c @@ -15,11 +15,48 @@ #include "lock.h" #include "misc.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd < 0) + err(1, "open: %s", path); + if (savestate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void usage(void) { fprintf(stderr, "usage: %s [-v] [-E algo] [-Z algo] [-k keyfile] [repo]\n", argv0); @@ -31,25 +68,23 @@ main(int argc, char *argv[]) { char spath[PATH_MAX]; char bpath[PATH_MAX]; - unsigned char key[KEYSIZE]; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo; int lfd; - bpar.calgo = bparamdef()->calgo; - bpar.ealgo = bparamdef()->ealgo; + param.calgo = "snappy"; + param.ealgo = "none"; ARGBEGIN { case 'k': keyfile = EARGF(usage()); break; case 'E': - bpar.ealgo = EARGF(usage()); + param.ealgo = EARGF(usage()); break; case 'Z': - bpar.calgo = EARGF(usage()); + param.calgo = EARGF(usage()); break; case 'v': verbose++; @@ -69,21 +104,6 @@ main(int argc, char *argv[]) usage(); }; - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(spath, sizeof(spath), "%s/%s", repo, ARCHIVEPATH) >= sizeof(spath)) errx(1, "snprintf: %s: path too long", spath); @@ -91,13 +111,15 @@ main(int argc, char *argv[]) repo, STORAGEPATH) >= sizeof(bpath)) errx(1, "snprintf: %s: path too long", bpath); + initkey(keyfile); if (mkdir(repo, 0700) < 0) err(1, "mkdir: %s", repo); if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); if (mkdir(spath, 0700) < 0) err(1, "mkdir: %s", spath); - if (bcreat(bpath, 0600, &bpar, &bctx) < 0) + initparam(repo); + if (bcreat(bpath, 0600, &bctx) < 0) berr("bcreat: %s", bpath); if (bclose(bctx) < 0) berr("bclose: %s", bpath); diff --git a/dup-keygen.c b/dup-keygen.c @@ -10,7 +10,9 @@ #include "arg.h" #include "config.h" #include "key.h" +#include "state.h" +struct param param; /* unused */ int verbose; char *argv0; diff --git a/dup-pack.c b/dup-pack.c @@ -15,11 +15,48 @@ #include "key.h" #include "lock.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDONLY); + if (fd < 0) + err(1, "open: %s", path); + if (loadstate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void pack(struct sctx *sctx, struct bctx *bctx) { struct chunker *c; @@ -61,7 +98,6 @@ main(int argc, char *argv[]) unsigned char key[KEYSIZE]; struct sctx *sctx; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo = "."; int lfd; @@ -83,21 +119,6 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(spath, sizeof(spath), "%s/archive/%s", repo, argv[0]) >= sizeof(spath)) errx(1, "snprintf: %s: path too long", spath); @@ -107,9 +128,13 @@ main(int argc, char *argv[]) if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); + + initparam(repo); + initkey(keyfile); + if (screat(spath, 0600, &sctx) < 0) serr("screat: %s", spath); - if (bopen(bpath, B_RDWR, 0600, &bpar, &bctx) <0) + if (bopen(bpath, B_RDWR, 0600, &bctx) <0) berr("bopen: %s", bpath); pack(sctx, bctx); @@ -118,6 +143,7 @@ main(int argc, char *argv[]) berr("bclose: %s", bpath); if (sclose(sctx) < 0) serr("sclose: %s", spath); + if (unlockrepo(lfd) < 0) errx(1, "failed to unlock repository"); return 0; diff --git a/dup-rm.c b/dup-rm.c @@ -14,11 +14,48 @@ #include "key.h" #include "lock.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDONLY); + if (fd < 0) + err(1, "open: %s", path); + if (loadstate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void rm(struct sctx *sctx, struct bctx *bctx) { unsigned char md[MDSIZE]; @@ -47,7 +84,6 @@ main(int argc, char *argv[]) unsigned char key[KEYSIZE]; struct sctx *sctx; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo = "."; int lfd; @@ -69,21 +105,6 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(spath, sizeof(spath), "%s/archive/%s", repo, argv[0]) >= sizeof(spath)) errx(1, "snprintf: %s: path too long", spath); @@ -93,9 +114,13 @@ main(int argc, char *argv[]) if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); + + initparam(repo); + initkey(keyfile); + if (sopen(spath, S_READ, 0600, &sctx) < 0) serr("sopen: %s", spath); - if (bopen(bpath, B_RDWR, 0600, &bpar, &bctx) <0) + if (bopen(bpath, B_RDWR, 0600, &bctx) <0) berr("bopen: %s", bpath); rm(sctx, bctx); @@ -106,6 +131,7 @@ main(int argc, char *argv[]) serr("sclose: %s", spath); if (unlink(spath) < 0) err(1, "unlink: %s", spath); + if (unlockrepo(lfd) < 0) errx(1, "failed to unlock repository"); diff --git a/dup-unpack.c b/dup-unpack.c @@ -15,11 +15,48 @@ #include "lock.h" #include "misc.h" #include "snap.h" +#include "state.h" +struct param param; int verbose; char *argv0; static void +initparam(char *repo) +{ + char path[PATH_MAX]; + int fd; + + if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path)) + errx(1, "snprintf: %s: path too long", path); + fd = open(path, O_RDONLY); + if (fd < 0) + err(1, "open: %s", path); + if (loadstate(fd, &param) < 0) + errx(1, "loadstate: failed"); + if (close(fd) < 0) + err(1, "close: %s", path); +} + +static void +initkey(char *keyfile) +{ + int fd; + + if (keyfile == NULL) + return; + + fd = open(keyfile, O_RDONLY); + if (fd < 0) + err(1, "open: %s", keyfile); + if (loadkey(fd, param.key, sizeof(param.key)) < 0) + errx(1, "loadkey: failed"); + param.keyloaded = 1; + if (close(fd) < 0) + err(1, "close: %s", keyfile); +} + +static void unpack(struct sctx *sctx, struct bctx *bctx) { unsigned char md[MDSIZE]; @@ -57,7 +94,6 @@ main(int argc, char *argv[]) unsigned char key[KEYSIZE]; struct sctx *sctx; struct bctx *bctx; - struct bparam bpar; char *keyfile = NULL; char *repo = "."; int lfd; @@ -79,21 +115,6 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - if (keyfile != NULL) { - int fd; - - fd = open(keyfile, O_RDONLY); - if (fd < 0) - err(1, "open: %s", keyfile); - if (loadkey(fd, key, sizeof(key)) < 0) - errx(1, "loadkey: failed"); - bpar.key = key; - if (close(fd) < 0) - err(1, "close: %s", keyfile); - } else { - bpar.key = NULL; - } - if (snprintf(spath, sizeof(spath), "%s/archive/%s", repo, argv[0]) >= sizeof(spath)) errx(1, "snprintf: %s: path too long", spath); @@ -103,9 +124,13 @@ main(int argc, char *argv[]) if ((lfd = lockrepo(repo)) < 0) errx(1, "failed to lock repository"); + + initparam(repo); + initkey(keyfile); + if (sopen(spath, S_READ, 0600, &sctx) < 0) serr("sopen: %s", spath); - if (bopen(bpath, B_READ, 0600, &bpar, &bctx) <0) + if (bopen(bpath, B_READ, 0600, &bctx) <0) berr("bopen: %s", bpath); unpack(sctx, bctx); @@ -114,6 +139,7 @@ main(int argc, char *argv[]) berr("bclose: %s", bpath); if (sclose(sctx) < 0) serr("sclose: %s", spath); + if (unlockrepo(lfd) < 0) errx(1, "failed to unlock repository"); diff --git a/state.c b/state.c @@ -4,6 +4,7 @@ #include <string.h> #include <strings.h> +#include "config.h" #include "misc.h" #include "state.h" diff --git a/state.h b/state.h @@ -1,4 +1,9 @@ struct param { char *calgo; char *ealgo; + unsigned char key[KEYSIZE]; + int keyloaded; }; + +int savestate(int, struct param *); +int loadstate(int fd, struct param *);