dup-init.c - 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
---
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, ¶m) < 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 }