dup-init.c - 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
       ---
       dup-init.c (2836B)
       ---
            1 #include <sys/types.h>
            2 #include <sys/stat.h>
            3 
            4 #include <err.h>
            5 #include <errno.h>
            6 #include <fcntl.h>
            7 #include <limits.h>
            8 #include <stdint.h>
            9 #include <stdio.h>
           10 #include <stdlib.h>
           11 #include <strings.h>
           12 #include <unistd.h>
           13 
           14 #include <sodium.h>
           15 
           16 #include "arg.h"
           17 #include "block.h"
           18 #include "config.h"
           19 #include "key.h"
           20 #include "lock.h"
           21 #include "misc.h"
           22 #include "snap.h"
           23 #include "state.h"
           24 
           25 struct param param;
           26 int verbose;
           27 char *argv0;
           28 
           29 static void
           30 savestate(char *repo)
           31 {
           32         char path[PATH_MAX];
           33         int fd;
           34 
           35         if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path))
           36                 errx(1, "snprintf: %s: path too long", path);
           37         fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
           38         if (fd < 0)
           39                 err(1, "open: %s", path);
           40         if (writestate(fd, &param) < 0)
           41                 printerr("writestate: %s", path);
           42         if (close(fd) < 0)
           43                 err(1, "close: %s", path);
           44 }
           45 
           46 static void
           47 loadkey(char *keyf)
           48 {
           49         int fd;
           50 
           51         if (keyf == NULL)
           52                 return;
           53 
           54         fd = open(keyf, O_RDONLY);
           55         if (fd < 0)
           56                 err(1, "open: %s", keyf);
           57         if (readkey(fd, param.key, sizeof(param.key)) < 0)
           58                 printerr("readkey: %s", keyf);
           59         param.keyloaded = 1;
           60         if (close(fd) < 0)
           61                 err(1, "close: %s", keyf);
           62 }
           63 
           64 static void
           65 usage(void)
           66 {
           67         fprintf(stderr, "usage: %s [-v] [-E algo] [-Z algo] [-k keyfile] [repo]\n", argv0);
           68         exit(1);
           69 }
           70 
           71 int
           72 main(int argc, char *argv[])
           73 {
           74         char spath[PATH_MAX];
           75         char bpath[PATH_MAX];
           76         struct bctx *bctx;
           77         char *keyf = NULL;
           78         char *repo;
           79         int lfd;
           80 
           81         param.calgo = "snappy";
           82         param.ealgo = "none";
           83 
           84         ARGBEGIN {
           85         case 'k':
           86                 keyf = EARGF(usage());
           87                 break;
           88         case 'E':
           89                 param.ealgo = EARGF(usage());
           90                 break;
           91         case 'Z':
           92                 param.calgo = EARGF(usage());
           93                 break;
           94         case 'v':
           95                 verbose++;
           96                 break;
           97         default:
           98                 usage();
           99         } ARGEND
          100 
          101         switch (argc) {
          102         case 0:
          103                 repo = ".";
          104                 break;
          105         case 1:
          106                 repo = argv[0];
          107                 break;
          108         default:
          109                 usage();
          110         };
          111 
          112         if (sodium_init() < 0)
          113                 errx(1, "sodium_init: failed");
          114 
          115         if (strcasecmp(param.ealgo, "none") == 0) {
          116                 param.seed = 0;
          117         } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) {
          118                 if (keyf == NULL)
          119                         errx(1, "expected encryption key");
          120                 param.seed = randombytes_uniform(0xffffffff);
          121         }
          122 
          123         if (snprintf(spath, sizeof(spath), "%s/%s",
          124                      repo, ARCHIVEPATH) >= sizeof(spath))
          125                 errx(1, "snprintf: %s: path too long", spath);
          126         if (snprintf(bpath, sizeof(bpath), "%s/%s",
          127                      repo, STORAGEPATH) >= sizeof(bpath))
          128                 errx(1, "snprintf: %s: path too long", bpath);
          129 
          130         if (mkdir(repo, 0700) < 0 && errno != EEXIST)
          131                 err(1, "mkdir: %s", repo);
          132 
          133         if ((lfd = lockrepo(repo)) < 0)
          134                 errx(1, "failed to lock repository");
          135 
          136         if (mkdir(spath, 0700) < 0)
          137                 err(1, "mkdir: %s", spath);
          138 
          139         loadkey(keyf);
          140         savestate(repo);
          141 
          142         if (bcreat(bpath, 0600, &bctx) < 0)
          143                 printerr("bcreat: %s", bpath);
          144         if (bclose(bctx) < 0)
          145                 printerr("bclose: %s", bpath);
          146 
          147         if (unlockrepo(lfd) < 0)
          148                 errx(1, "failed to unlock repository");
          149         return 0;
          150 }