Move error functions to misc.c so they can be reused - dedup - deduplicating backup program
 (HTM) git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a8beae9784fa77d57a05f35c0980d7504aea2fde
 (DIR) parent ffaf068f318e080bdf7cfaf1232836b92f779315
 (HTM) Author: sin <sin@2f30.org>
       Date:   Sun, 12 May 2019 11:52:09 +0100
       
       Move error functions to misc.c so they can be reused
       
       Diffstat:
         M bcompress.c                         |      32 ++++++++++++++++----------------
         M bencrypt.c                          |      32 ++++++++++++++++----------------
         M block.c                             |      51 +++++++------------------------
         M block.h                             |       4 ++--
         M bstorage.c                          |      70 ++++++++++++++++----------------
         M dup-check.c                         |      12 ++++++------
         M dup-gc.c                            |       6 +++---
         M dup-init.c                          |       4 ++--
         M dup-pack.c                          |      12 ++++++------
         M dup-rm.c                            |      12 ++++++------
         M dup-unpack.c                        |      12 ++++++------
         M misc.c                              |      31 +++++++++++++++++++++++++++++++
         M misc.h                              |       2 ++
         M snap.c                              |      76 ++++++++++---------------------
         M snap.h                              |       4 ++--
       
       15 files changed, 167 insertions(+), 193 deletions(-)
       ---
 (DIR) diff --git a/bcompress.c b/bcompress.c
       @@ -106,13 +106,13 @@ bccreat(struct bctx *bctx, char *path, int mode)
                } else if (strcasecmp(param.calgo, "lz4") == 0) {
                        type = CDLZ4TYPE;
                } else {
       -                bseterr("invalid compression type: %s", param.calgo);
       +                seterr("invalid compression type: %s", param.calgo);
                        return -1;
                }
        
                bctx->cctx = calloc(1, sizeof(struct cctx));
                if (bctx->cctx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                cctx = bctx->cctx;
       @@ -132,7 +132,7 @@ bcopen(struct bctx *bctx, char *path, int flags, int mode)
        
                bctx->cctx = calloc(1, sizeof(struct cctx));
                if (bctx->cctx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                cctx = bctx->cctx;
       @@ -151,7 +151,7 @@ bcopen(struct bctx *bctx, char *path, int flags, int mode)
                } else {
                        bencryptops()->close(bctx);
                        free(cctx);
       -                bseterr("invalid compression type: %s", param.calgo);
       +                seterr("invalid compression type: %s", param.calgo);
                        return -1;
                }
                return 0;
       @@ -174,13 +174,13 @@ bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                } else if (cctx->type == CDLZ4TYPE) {
                        cn = LZ4_compressBound(n);
                } else {
       -                bseterr("invalid compression type: %d", cctx->type);
       +                seterr("invalid compression type: %d", cctx->type);
                        return -1;
                }
        
                cbuf = malloc(CDSIZE + cn);
                if (cbuf == NULL) {
       -                bseterr("malloc: %s", strerror(errno));
       +                seterr("malloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -190,7 +190,7 @@ bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                } else if (cctx->type == CDSNAPPYTYPE) {
                        if (snappy_compress(buf, n, &cbuf[CDSIZE], &cn) != SNAPPY_OK) {
                                free(cbuf);
       -                        bseterr("snappy_compress: failed");
       +                        seterr("snappy_compress: failed");
                                return -1;
                        }
                } else if (cctx->type == CDLZ4TYPE) {
       @@ -199,13 +199,13 @@ bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                        ret = LZ4_compress_default(buf, &cbuf[CDSIZE], n, cn);
                        if (ret < 0) {
                                free(cbuf);
       -                        bseterr("LZ4_compress_default: failed");
       +                        seterr("LZ4_compress_default: failed");
                                return -1;
                        }
                        cn = ret;
                } else {
                        free(cbuf);
       -                bseterr("invalid compression type: %d", cctx->type);
       +                seterr("invalid compression type: %d", cctx->type);
                        return -1;
                }
        
       @@ -242,7 +242,7 @@ bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
        
                cbuf = malloc(size);
                if (cbuf == NULL) {
       -                bseterr("malloc: %s", strerror(errno));
       +                seterr("malloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -258,7 +258,7 @@ bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                        un = cd.size;
                        if (*n < un) {
                                free(cbuf);
       -                        bseterr("buffer too small");
       +                        seterr("buffer too small");
                                return -1;
                        }
                        memcpy(buf, &cbuf[CDSIZE], un);
       @@ -266,20 +266,20 @@ bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                        if (snappy_uncompressed_length(&cbuf[CDSIZE], cd.size,
                                                       &un) != SNAPPY_OK) {
                                free(cbuf);
       -                        bseterr("snappy_uncompressed_length: failed");
       +                        seterr("snappy_uncompressed_length: failed");
                                return -1;
                        }
        
                        if (*n < un) {
                                free(cbuf);
       -                        bseterr("buffer too small");
       +                        seterr("buffer too small");
                                return -1;
                        }
        
                        if (snappy_uncompress(&cbuf[CDSIZE], cd.size, buf,
                                              &un) != SNAPPY_OK) {
                                free(cbuf);
       -                        bseterr("snappy_uncompress: failed");
       +                        seterr("snappy_uncompress: failed");
                                return -1;
                        }
                } else if (cd.type == CDLZ4TYPE) {
       @@ -288,13 +288,13 @@ bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                        ret = LZ4_decompress_safe(&cbuf[CDSIZE], buf, cd.size, *n);
                        if (ret < 0) {
                                free(cbuf);
       -                        bseterr("LZ4_decompress_safe: failed");
       +                        seterr("LZ4_decompress_safe: failed");
                                return -1;
                        }
                        un = ret;
                } else {
                        free(cbuf);
       -                bseterr("invalid compression type: %d", cd.type);
       +                seterr("invalid compression type: %d", cd.type);
                        return -1;
                }
        
 (DIR) diff --git a/bencrypt.c b/bencrypt.c
       @@ -107,24 +107,24 @@ becreat(struct bctx *bctx, char *path, int mode)
                } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) {
                        type = EDCHACHATYPE;
                } else {
       -                bseterr("invalid encryption type: %s", param.ealgo);
       +                seterr("invalid encryption type: %s", param.ealgo);
                        return -1;
                }
        
                /* Ensure that if caller requested encryption, a key was provided */
                if (type != EDNONETYPE && !param.keyloaded) {
       -                bseterr("expected encryption key");
       +                seterr("expected encryption key");
                        return -1;
                }
        
                if (sodium_init() < 0) {
       -                bseterr("sodium_init: failed");
       +                seterr("sodium_init: failed");
                        return -1;
                }
        
                bctx->ectx = calloc(1, sizeof(struct ectx));
                if (bctx->ectx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                ectx = bctx->ectx;
       @@ -145,7 +145,7 @@ beopen(struct bctx *bctx, char *path, int flags, int mode)
        
                bctx->ectx = calloc(1, sizeof(struct ectx));
                if (bctx->ectx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                ectx = bctx->ectx;
       @@ -164,7 +164,7 @@ beopen(struct bctx *bctx, char *path, int flags, int mode)
                else {
                        bstorageops()->close(bctx);
                        free(ectx);
       -                bseterr("invalid encryption type: %s", param.ealgo);
       +                seterr("invalid encryption type: %s", param.ealgo);
                        return -1;
                }
        
       @@ -172,7 +172,7 @@ beopen(struct bctx *bctx, char *path, int flags, int mode)
                if (ectx->type != EDNONETYPE && !param.keyloaded) {
                        bstorageops()->close(bctx);
                        free(ectx);
       -                bseterr("expected encryption key");
       +                seterr("expected encryption key");
                        return -1;
                }
        
       @@ -194,13 +194,13 @@ beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                } else if (ectx->type == EDCHACHATYPE) {
                        en = n + crypto_aead_xchacha20poly1305_ietf_ABYTES;
                } else {
       -                bseterr("invalid encryption type: %d", ectx->type);
       +                seterr("invalid encryption type: %d", ectx->type);
                        return -1;
                }
        
                ebuf = malloc(EDSIZE + en);
                if (ebuf == NULL) {
       -                bseterr("malloc: %s", strerror(errno));
       +                seterr("malloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -214,7 +214,7 @@ beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                        randombytes_buf(ed.nonce, sizeof(ed.nonce));
                } else {
                        free(ebuf);
       -                bseterr("invalid encryption type: %d", ectx->type);
       +                seterr("invalid encryption type: %d", ectx->type);
                        return -1;
                }
                packed(ebuf, &ed);
       @@ -231,7 +231,7 @@ beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                        assert(elen == en);
                } else {
                        free(ebuf);
       -                bseterr("invalid encryption type: %d", ectx->type);
       +                seterr("invalid encryption type: %d", ectx->type);
                        return -1;
                }
        
       @@ -256,7 +256,7 @@ beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
        
                ebuf = malloc(size);
                if (ebuf == NULL) {
       -                bseterr("malloc: %s", strerror(errno));
       +                seterr("malloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -272,7 +272,7 @@ beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                        dn = ed.size;
                        if (*n < dn) {
                                free(ebuf);
       -                        bseterr("buffer too small");
       +                        seterr("buffer too small");
                                return -1;
                        }
                        memcpy(buf, &ebuf[EDSIZE], dn);
       @@ -283,7 +283,7 @@ beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                        dn = ed.size - crypto_aead_xchacha20poly1305_ietf_ABYTES;
                        if (*n < dn) {
                                free(ebuf);
       -                        bseterr("buffer too small");
       +                        seterr("buffer too small");
                                return -1;
                        }
        
       @@ -294,14 +294,14 @@ beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                                                                       ebuf, EDSIZE,
                                                                       ed.nonce, ectx->key) < 0) {
                                free(ebuf);
       -                        bseterr("authentication failed");
       +                        seterr("authentication failed");
                                return -1;
                        }
        
                        assert(dn == dlen);
                } else {
                        free(ebuf);
       -                bseterr("invalid encryption type: %d", ed.type);
       +                seterr("invalid encryption type: %d", ed.type);
                        return -1;
                }
        
 (DIR) diff --git a/block.c b/block.c
       @@ -4,7 +4,6 @@
        
        #include <errno.h>
        #include <fcntl.h>
       -#include <stdarg.h>
        #include <stdint.h>
        #include <stdio.h>
        #include <stdlib.h>
       @@ -12,22 +11,19 @@
        
        #include "block.h"
        
       -#define NERRBUF        128
       -static char errbuf[NERRBUF];
       -
        int
        bcreat(char *path, int mode, struct bctx **bctx)
        {
                struct bops *bops;
        
                if (path == NULL || bctx == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                *bctx = calloc(1, sizeof(**bctx));
                if (*bctx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -45,13 +41,13 @@ bopen(char *path, int flags, int mode, struct bctx **bctx)
                struct bops *bops;
        
                if (path == NULL || bctx == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                *bctx = calloc(1, sizeof(**bctx));
                if (*bctx == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -69,7 +65,7 @@ bput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                struct bops *bops;
        
                if (bctx == NULL || buf == NULL || n == 0 || md == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -83,7 +79,7 @@ bget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                struct bops *bops;
        
                if (bctx == NULL || md == NULL || buf == NULL || n == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -97,7 +93,7 @@ brm(struct bctx *bctx, unsigned char *md)
                struct bops *bops;
        
                if (bctx == NULL || md == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -111,7 +107,7 @@ bgc(struct bctx *bctx)
                struct bops *bops;
        
                if (bctx == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -125,7 +121,7 @@ bcheck(struct bctx *bctx, unsigned char *md)
                struct bops *bops;
        
                if (bctx == NULL || md == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -139,7 +135,7 @@ bsync(struct bctx *bctx)
                struct bops *bops;
        
                if (bctx == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -154,7 +150,7 @@ bclose(struct bctx *bctx)
                int r;
        
                if (bctx == NULL) {
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -165,28 +161,3 @@ bclose(struct bctx *bctx)
                free(bctx);
                return r;
        }
       -
       -void
       -bseterr(char *fmt, ...)
       -{
       -        va_list ap;
       -
       -        va_start(ap, fmt);
       -        vsnprintf(errbuf, NERRBUF, fmt, ap);
       -        va_end(ap);
       -}
       -
       -void
       -berr(char *fmt, ...)
       -{
       -        va_list ap;
       -
       -        va_start(ap, fmt);
       -        vfprintf(stderr, fmt, ap);
       -        if (errbuf[0] == '\0')
       -                fprintf(stderr, ": unknown error\n");
       -        else
       -                fprintf(stderr, ": %s\n", errbuf);
       -        va_end(ap);
       -        exit(1);
       -}
 (DIR) diff --git a/block.h b/block.h
       @@ -36,8 +36,8 @@ extern int bgc(struct bctx *);
        extern int bcheck(struct bctx *, unsigned char *);
        extern int bsync(struct bctx *);
        extern int bclose(struct bctx *);
       -extern void bseterr(char *, ...);
       -extern void berr(char *, ...);
       +extern void seterr(char *, ...);
       +extern void printerr(char *, ...);
        
        /* bcompat.c */
        extern int punchhole(int, off_t, off_t);
 (DIR) diff --git a/bstorage.c b/bstorage.c
       @@ -130,7 +130,7 @@ unpackbhdr(int fd, struct bhdr *bhdr)
                int n;
        
                if (xread(fd, buf, sizeof(buf)) != sizeof(buf)) {
       -                bseterr("failed to read block header: %s", strerror(errno));
       +                seterr("failed to read block header: %s", strerror(errno));
                        return -1;
                }
        
       @@ -157,7 +157,7 @@ packbhdr(int fd, struct bhdr *bhdr)
        
                assert(n == BHDRSIZE);
                if (xwrite(fd, buf, n) != n) {
       -                bseterr("failed to write block header: %s", strerror(errno));
       +                seterr("failed to write block header: %s", strerror(errno));
                        return -1;
                }
                return n;
       @@ -172,7 +172,7 @@ unpackbd(int fd, struct bd *bd)
                int n;
        
                if (xread(fd, buf, sizeof(buf)) != sizeof(buf)) {
       -                bseterr("failed to read block descriptor: %s",
       +                seterr("failed to read block descriptor: %s",
                                strerror(errno));
                        return -1;
                }
       @@ -209,7 +209,7 @@ packbd(int fd, struct bd *bd)
        
                assert(n == BDSIZE);
                if (xwrite(fd, buf, n) != n) {
       -                bseterr("failed to write block descriptor: %s",
       +                seterr("failed to write block descriptor: %s",
                                strerror(errno));
                        return -1;
                }
       @@ -224,7 +224,7 @@ loadbd(struct sctx *sctx)
        
                bd = calloc(1, sizeof(*bd));
                if (bd == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -235,14 +235,14 @@ loadbd(struct sctx *sctx)
        
                if (bd->type != BDTYPE) {
                        free(bd);
       -                bseterr("invalid block descriptor type: %d", bd->type);
       +                seterr("invalid block descriptor type: %d", bd->type);
                        return -1;
                }
        
                /* Move to the next block descriptor */
                if (lseek(sctx->fd, bd->size, SEEK_CUR) < 0) {
                        free(bd);
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
        
       @@ -303,20 +303,20 @@ bscreat(struct bctx *bctx, char *path, int mode)
                int fd;
        
                if (sodium_init() < 0) {
       -                bseterr("sodium_init: failed");
       +                seterr("sodium_init: failed");
                        return -1;
                }
        
                fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode);
                if (fd < 0) {
       -                bseterr("open: %s", strerror(errno));
       +                seterr("open: %s", strerror(errno));
                        return -1;
                }
        
                bctx->sctx = calloc(1, sizeof(struct sctx));
                if (bctx->sctx == NULL) {
                        close(fd);
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -354,25 +354,25 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode)
                        flags = O_RDWR;
                        break;
                default:
       -                bseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                if (sodium_init() < 0) {
       -                bseterr("sodium_init: failed");
       +                seterr("sodium_init: failed");
                        return -1;
                }
        
                fd = open(path, flags, mode);
                if (fd < 0) {
       -                bseterr("open: %s", strerror(errno));
       +                seterr("open: %s", strerror(errno));
                        return -1;
                }
        
                bctx->sctx = calloc(1, sizeof(struct sctx));
                if (bctx->sctx == NULL) {
                        close(fd);
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -390,7 +390,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode)
                if (memcmp(bhdr->magic, BHDRMAGIC, NBHDRMAGIC) != 0) {
                        free(sctx);
                        close(fd);
       -                bseterr("unknown block header magic");
       +                seterr("unknown block header magic");
                        return -1;
                }
        
       @@ -398,7 +398,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode)
                if (((bhdr->flags >> VMAJSHIFT) & VMAJMASK) != VMAJ) {
                        free(sctx);
                        close(fd);
       -                bseterr("block header version mismatch");
       +                seterr("block header version mismatch");
                        return -1;
                }
        
       @@ -423,7 +423,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                off_t offs;
        
                if (bhash(buf, n, key.md) < 0) {
       -                bseterr("bhash: failed");
       +                seterr("bhash: failed");
                        return -1;
                }
        
       @@ -439,7 +439,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
        
                        bdoffs = bd->offset - BDSIZE;
                        if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0) {
       -                        bseterr("lseek: %s", strerror(errno));
       +                        seterr("lseek: %s", strerror(errno));
                                return -1;
                        }
        
       @@ -456,13 +456,13 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                /* New blocks are appended at the end of storage file */
                offs = lseek(sctx->fd, 0, SEEK_END);
                if (offs < 0) {
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
        
                bd = calloc(1, sizeof(*bd));
                if (bd == NULL) {
       -                bseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                bd->type = BDTYPE;
       @@ -480,7 +480,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
                        /* Shouldn't fail but if it does rewind storage file state */
                        ftruncate(sctx->fd, offs);
                        free(bd);
       -                bseterr("failed to write block: %s", strerror(errno));
       +                seterr("failed to write block: %s", strerror(errno));
                        return -1;
                }
        
       @@ -508,21 +508,21 @@ bsget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
                memcpy(key.md, md, MDSIZE);
                bd = RB_FIND(bdcache, &sctx->bdcache, &key);
                if (bd == NULL) {
       -                bseterr("unknown block");
       +                seterr("unknown block");
                        return -1;
                }
        
                if (*n < bd->size) {
       -                bseterr("buffer too small");
       +                seterr("buffer too small");
                        return -1;
                }
        
                if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0) {
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
                if (xread(sctx->fd, buf, bd->size) != bd->size) {
       -                bseterr("failed to read block: %s", strerror(errno));
       +                seterr("failed to read block: %s", strerror(errno));
                        return -1;
                }
                *n = bd->size;
       @@ -541,13 +541,13 @@ bsrm(struct bctx *bctx, unsigned char *md)
                memcpy(key.md, md, MDSIZE);
                bd = RB_FIND(bdcache, &sctx->bdcache, &key);
                if (bd == NULL) {
       -                bseterr("unknown block");
       +                seterr("unknown block");
                        return -1;
                }
        
                bdoffs = bd->offset - BDSIZE;
                if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0) {
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
        
       @@ -569,7 +569,7 @@ bsrm(struct bctx *bctx, unsigned char *md)
                        lseek(sctx->fd, bdoffs, SEEK_SET);
                        bd->refcnt++;
                        packbd(sctx->fd, bd);
       -                bseterr("operation not supported");
       +                seterr("operation not supported");
                        return -1;
                }
        
       @@ -622,31 +622,31 @@ bscheck(struct bctx *bctx, unsigned char *md)
                memcpy(key.md, md, MDSIZE);
                bd = RB_FIND(bdcache, &sctx->bdcache, &key);
                if (bd == NULL) {
       -                bseterr("unknown block");
       +                seterr("unknown block");
                        return -1;
                }
        
                buf = malloc(bd->size);
                if (buf == NULL) {
       -                bseterr("malloc: %s", strerror(errno));
       +                seterr("malloc: %s", strerror(errno));
                        return -1;
                }
        
                if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0) {
                        free(buf);
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
        
                if (xread(sctx->fd, buf, bd->size) != bd->size) {
                        free(buf);
       -                bseterr("failed to read block: %s", strerror(errno));
       +                seterr("failed to read block: %s", strerror(errno));
                        return -1;
                }
        
                if (bhash(buf, bd->size, key.md) < 0) {
                        free(buf);
       -                bseterr("bhash: failed");
       +                seterr("bhash: failed");
                        return -1;
                }
        
       @@ -670,7 +670,7 @@ bssync(struct bctx *bctx)
                        return 0;
        
                if (lseek(sctx->fd, 0, SEEK_SET) < 0) {
       -                bseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
                bhdr = &sctx->bhdr;
       @@ -705,7 +705,7 @@ bsclose(struct bctx *bctx)
                r = close(sctx->fd);
                free(sctx);
                if (r < 0)
       -                bseterr("close: %s", strerror(errno));
       +                seterr("close: %s", strerror(errno));
                return r;
        }
        
 (DIR) diff --git a/dup-check.c b/dup-check.c
       @@ -71,14 +71,14 @@ check(struct sctx *sctx, struct bctx *bctx)
                        int r;
        
                        if ((r = bcheck(bctx, md)) < 0) {
       -                        berr("bcheck");
       +                        printerr("bcheck");
                        } else if (r > 0) {
                                sodium_bin2hex(mdstr, sizeof(mdstr), md, MDSIZE);
                                puts(mdstr);
                        }
                }
                if (n < 0)
       -                serr("sget");
       +                printerr("sget");
        }
        
        static void
       @@ -130,16 +130,16 @@ main(int argc, char *argv[])
                loadkey(keyfile);
        
                if (sopen(spath, S_READ, 0600, &sctx) < 0)
       -                serr("sopen: %s", spath);
       +                printerr("sopen: %s", spath);
                if (bopen(bpath, B_READ, 0600, &bctx) <0)
       -                berr("bopen: %s", bpath);
       +                printerr("bopen: %s", bpath);
        
                check(sctx, bctx);
        
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", bpath);
       +                printerr("bclose: %s", bpath);
                if (sclose(sctx) < 0)
       -                serr("sclose: %s", spath);
       +                printerr("sclose: %s", spath);
        
                if (unlockrepo(lfd) < 0)
                        errx(1, "failed to unlock repository");
 (DIR) diff --git a/dup-gc.c b/dup-gc.c
       @@ -104,11 +104,11 @@ main(int argc, char *argv[])
                loadkey(keyfile);
        
                if (bopen(path, B_RDWR, 0600, &bctx) < 0)
       -                berr("bopen: %s", path);
       +                printerr("bopen: %s", path);
                if (bgc(bctx) < 0)
       -                berr("bgc: %s", path);
       +                printerr("bgc: %s", path);
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", path);
       +                printerr("bclose: %s", path);
        
                if (unlockrepo(lfd) < 0)
                        errx(1, "failed to unlock repository");
 (DIR) diff --git a/dup-init.c b/dup-init.c
       @@ -124,9 +124,9 @@ main(int argc, char *argv[])
                savestate(repo);
        
                if (bcreat(bpath, 0600, &bctx) < 0)
       -                berr("bcreat: %s", bpath);
       +                printerr("bcreat: %s", bpath);
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", bpath);
       +                printerr("bclose: %s", bpath);
        
                if (unlockrepo(lfd) < 0)
                        errx(1, "failed to unlock repository");
 (DIR) diff --git a/dup-pack.c b/dup-pack.c
       @@ -73,9 +73,9 @@ pack(struct sctx *sctx, struct bctx *bctx)
                        if (buf == NULL)
                                errx(1, "cget: failed");
                        if (bput(bctx, buf, n, md) < 0)
       -                        berr("bput");
       +                        printerr("bput");
                        if (sput(sctx, md) < 0)
       -                        serr("sput");
       +                        printerr("sput");
                        if (cdrain(c) < 0)
                                errx(1, "cdrain: failed");
                }
       @@ -133,16 +133,16 @@ main(int argc, char *argv[])
                loadkey(keyfile);
        
                if (screat(spath, 0600, &sctx) < 0)
       -                serr("screat: %s", spath);
       +                printerr("screat: %s", spath);
                if (bopen(bpath, B_RDWR, 0600, &bctx) <0)
       -                berr("bopen: %s", bpath);
       +                printerr("bopen: %s", bpath);
        
                pack(sctx, bctx);
        
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", bpath);
       +                printerr("bclose: %s", bpath);
                if (sclose(sctx) < 0)
       -                serr("sclose: %s", spath);
       +                printerr("sclose: %s", spath);
        
                if (unlockrepo(lfd) < 0)
                        errx(1, "failed to unlock repository");
 (DIR) diff --git a/dup-rm.c b/dup-rm.c
       @@ -63,10 +63,10 @@ rm(struct sctx *sctx, struct bctx *bctx)
        
                while ((n = sget(sctx, md)) == MDSIZE) {
                        if (brm(bctx, md) < 0)
       -                        berr("brm");
       +                        printerr("brm");
                }
                if (n < 0)
       -                serr("sget");
       +                printerr("sget");
        }
        
        static void
       @@ -119,16 +119,16 @@ main(int argc, char *argv[])
                loadkey(keyfile);
        
                if (sopen(spath, S_READ, 0600, &sctx) < 0)
       -                serr("sopen: %s", spath);
       +                printerr("sopen: %s", spath);
                if (bopen(bpath, B_RDWR, 0600, &bctx) <0)
       -                berr("bopen: %s", bpath);
       +                printerr("bopen: %s", bpath);
        
                rm(sctx, bctx);
        
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", bpath);
       +                printerr("bclose: %s", bpath);
                if (sclose(sctx) < 0)
       -                serr("sclose: %s", spath);
       +                printerr("sclose: %s", spath);
                if (unlink(spath) < 0)
                        err(1, "unlink: %s", spath);
        
 (DIR) diff --git a/dup-unpack.c b/dup-unpack.c
       @@ -70,12 +70,12 @@ unpack(struct sctx *sctx, struct bctx *bctx)
                        size_t bn = BSIZEMAX;
        
                        if (bget(bctx, md, buf, &bn) < 0)
       -                        berr("bget");
       +                        printerr("bget");
                        if (xwrite(1, buf, bn) != bn)
                                err(1, "xwrite");
                }
                if (sn < 0)
       -                serr("sget");
       +                printerr("sget");
                free(buf);
        }
        
       @@ -129,16 +129,16 @@ main(int argc, char *argv[])
                loadkey(keyfile);
        
                if (sopen(spath, S_READ, 0600, &sctx) < 0)
       -                serr("sopen: %s", spath);
       +                printerr("sopen: %s", spath);
                if (bopen(bpath, B_READ, 0600, &bctx) <0)
       -                berr("bopen: %s", bpath);
       +                printerr("bopen: %s", bpath);
        
                unpack(sctx, bctx);
        
                if (bclose(bctx) < 0)
       -                berr("bclose: %s", bpath);
       +                printerr("bclose: %s", bpath);
                if (sclose(sctx) < 0)
       -                serr("sclose: %s", spath);
       +                printerr("sclose: %s", spath);
        
                if (unlockrepo(lfd) < 0)
                        errx(1, "failed to unlock repository");
 (DIR) diff --git a/misc.c b/misc.c
       @@ -1,7 +1,13 @@
        #include <sys/types.h>
        
       +#include <stdarg.h>
       +#include <stdio.h>
       +#include <stdlib.h>
        #include <unistd.h>
        
       +#define NERRBUF        128
       +static char errbuf[NERRBUF];
       +
        ssize_t
        xread(int fd, void *buf, size_t nbytes)
        {
       @@ -41,3 +47,28 @@ xwrite(int fd, void *buf, size_t nbytes)
                }
                return total;
        }
       +
       +void
       +seterr(char *fmt, ...)
       +{
       +        va_list ap;
       +
       +        va_start(ap, fmt);
       +        vsnprintf(errbuf, NERRBUF, fmt, ap);
       +        va_end(ap);
       +}
       +
       +void
       +printerr(char *fmt, ...)
       +{
       +        va_list ap;
       +
       +        va_start(ap, fmt);
       +        vfprintf(stderr, fmt, ap);
       +        if (errbuf[0] == '\0')
       +                fprintf(stderr, ": unknown error\n");
       +        else
       +                fprintf(stderr, ": %s\n", errbuf);
       +        va_end(ap);
       +        exit(1);
       +}
 (DIR) diff --git a/misc.h b/misc.h
       @@ -1,2 +1,4 @@
        extern ssize_t xread(int, void *, size_t);
        extern ssize_t xwrite(int, void *, size_t);
       +extern void seterr(char *, ...);
       +extern void printerr(char *, ...);
 (DIR) diff --git a/snap.c b/snap.c
       @@ -6,7 +6,6 @@
        #include <errno.h>
        #include <fcntl.h>
        #include <limits.h>
       -#include <stdarg.h>
        #include <stdint.h>
        #include <stdio.h>
        #include <stdlib.h>
       @@ -32,8 +31,6 @@
        
        #define SHDRSIZE        (NSHDRMAGIC + 24 + 24 + 8 + 8)
        
       -#define NERRBUF        128
       -
        /* misc helpers */
        extern int pack(unsigned char *, char *, ...);
        extern int unpack(unsigned char *, char *, ...);
       @@ -60,8 +57,6 @@ struct sctx {
                struct shdr shdr;                        /* snapshot header */
        };
        
       -static char errbuf[NERRBUF];
       -
        /* Read snapshot header */
        static int
        unpackshdr(int fd, struct shdr *shdr)
       @@ -70,7 +65,7 @@ unpackshdr(int fd, struct shdr *shdr)
                int n;
        
                if (xread(fd, buf, sizeof(buf)) != sizeof(buf)) {
       -                sseterr("failed to read snapshot header: %s", strerror(errno));
       +                seterr("failed to read snapshot header: %s", strerror(errno));
                        return -1;
                }
        
       @@ -101,7 +96,7 @@ packshdr(int fd, struct shdr *shdr)
        
                assert(n == SHDRSIZE);
                if (xwrite(fd, buf, n) != n) {
       -                sseterr("failed to write snapshot header: %s", strerror(errno));
       +                seterr("failed to write snapshot header: %s", strerror(errno));
                        return -1;
                }
                return n;
       @@ -114,12 +109,12 @@ loadmd(struct sctx *sctx)
        
                mdnode = calloc(1, sizeof(*mdnode));
                if (mdnode == NULL) {
       -                sseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                if (xread(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) {
                        free(mdnode);
       -                sseterr("failed to read block hash: %s", strerror(errno));
       +                seterr("failed to read block hash: %s", strerror(errno));
                        return -1;
                }
                TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e);
       @@ -157,25 +152,25 @@ screat(char *path, int mode, struct sctx **sctx)
                int fd;
        
                if (path == NULL || sctx == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                if (sodium_init() < 0) {
       -                sseterr("sodium_init: failed");
       +                seterr("sodium_init: failed");
                        return -1;
                }
        
                fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode);
                if (fd < 0) {
       -                sseterr("open: %s", strerror(errno));
       +                seterr("open: %s", strerror(errno));
                        return -1;
                }
        
                *sctx = calloc(1, sizeof(**sctx));
                if (*sctx == NULL) {
                        close(fd);
       -                sseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -204,31 +199,31 @@ sopen(char *path, int flags, int mode, struct sctx **sctx)
                int fd;
        
                if (path == NULL || sctx == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                /* Existing snapshots are immutable */
                if (flags != S_READ) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                if (sodium_init() < 0) {
       -                sseterr("sodium_init: failed");
       +                seterr("sodium_init: failed");
                        return -1;
                }
        
                fd = open(path, O_RDONLY, mode);
                if (fd < 0) {
       -                sseterr("open: %s", strerror(errno));
       +                seterr("open: %s", strerror(errno));
                        return -1;
                }
        
                *sctx = calloc(1, sizeof(**sctx));
                if (*sctx == NULL) {
                        close(fd);
       -                sseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
        
       @@ -248,7 +243,7 @@ sopen(char *path, int flags, int mode, struct sctx **sctx)
                if (memcmp(shdr->magic, SHDRMAGIC, NSHDRMAGIC) != 0) {
                        free(sctx);
                        close(fd);
       -                sseterr("unknown snapshot header magic");
       +                seterr("unknown snapshot header magic");
                        return -1;
                }
        
       @@ -256,7 +251,7 @@ sopen(char *path, int flags, int mode, struct sctx **sctx)
                if (((shdr->flags >> VMAJSHIFT) & VMAJMASK) != VMAJ) {
                        free(sctx);
                        close(fd);
       -                sseterr("snapshot header version mismatch");
       +                seterr("snapshot header version mismatch");
                        return -1;
                }
        
       @@ -275,13 +270,13 @@ sput(struct sctx *sctx, unsigned char *md)
                struct mdnode *mdnode;
        
                if (sctx == NULL || md == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
                mdnode = calloc(1, sizeof(*mdnode));
                if (mdnode == NULL) {
       -                sseterr("calloc: %s", strerror(errno));
       +                seterr("calloc: %s", strerror(errno));
                        return -1;
                }
                shdr = &sctx->shdr;
       @@ -297,7 +292,7 @@ sget(struct sctx *sctx, unsigned char *md)
                struct mdnode *mdnode;
        
                if (sctx == NULL || md == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -318,7 +313,7 @@ int
        srewind(struct sctx *sctx)
        {
                if (sctx == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
                sctx->mdnext = NULL;
       @@ -332,7 +327,7 @@ ssync(struct sctx *sctx)
                struct mdnode *mdnode;
        
                if (sctx == NULL) {
       -                sseterr("invalid params");
       +                seterr("invalid params");
                        return -1;
                }
        
       @@ -340,7 +335,7 @@ ssync(struct sctx *sctx)
                        return 0;
        
                if (lseek(sctx->fd, 0, SEEK_SET) < 0) {
       -                sseterr("lseek: %s", strerror(errno));
       +                seterr("lseek: %s", strerror(errno));
                        return -1;
                }
        
       @@ -349,7 +344,7 @@ ssync(struct sctx *sctx)
                        return -1;
                TAILQ_FOREACH(mdnode, &sctx->mdhead, e) {
                        if (xwrite(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) {
       -                        sseterr("failed to write block hash: %s",
       +                        seterr("failed to write block hash: %s",
                                        strerror(errno));
                                return -1;
                        }
       @@ -381,31 +376,6 @@ sclose(struct sctx *sctx)
                r = close(sctx->fd);
                free(sctx);
                if (r < 0)
       -                sseterr("close: %s", strerror(errno));
       +                seterr("close: %s", strerror(errno));
                return r;
        }
       -
       -void
       -sseterr(char *fmt, ...)
       -{
       -        va_list ap;
       -
       -        va_start(ap, fmt);
       -        vsnprintf(errbuf, NERRBUF, fmt, ap);
       -        va_end(ap);
       -}
       -
       -void
       -serr(char *fmt, ...)
       -{
       -        va_list ap;
       -
       -        va_start(ap, fmt);
       -        vfprintf(stderr, fmt, ap);
       -        if (errbuf[0] == '\0')
       -                fprintf(stderr, ": unknown error\n");
       -        else
       -                fprintf(stderr, ": %s\n", errbuf);
       -        va_end(ap);
       -        exit(1);
       -}
 (DIR) diff --git a/snap.h b/snap.h
       @@ -11,5 +11,5 @@ extern int sget(struct sctx *, unsigned char *);
        extern int srewind(struct sctx *);
        extern int ssync(struct sctx *);
        extern int sclose(struct sctx *);
       -extern void sseterr(char *, ...);
       -extern void serr(char *, ...);
       +extern void seterr(char *, ...);
       +extern void printerr(char *, ...);