dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | 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 }