dup-pack.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-pack.c (2805B)
---
1 #include <sys/types.h>
2 #include <sys/stat.h>
3
4 #include <err.h>
5 #include <fcntl.h>
6 #include <limits.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include "arg.h"
13 #include "block.h"
14 #include "chunker.h"
15 #include "config.h"
16 #include "key.h"
17 #include "lock.h"
18 #include "misc.h"
19 #include "snap.h"
20 #include "state.h"
21
22 struct param param;
23 int verbose;
24 char *argv0;
25
26 static void
27 loadstate(char *repo)
28 {
29 char path[PATH_MAX];
30 int fd;
31
32 if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path))
33 errx(1, "snprintf: %s: path too long", path);
34 fd = open(path, O_RDONLY);
35 if (fd < 0)
36 err(1, "open: %s", path);
37 if (readstate(fd, ¶m) < 0)
38 printerr("readstate: %s", path);
39 if (close(fd) < 0)
40 err(1, "close: %s", path);
41 }
42
43 static void
44 loadkey(char *keyfile)
45 {
46 int fd;
47
48 if (keyfile == NULL)
49 return;
50
51 fd = open(keyfile, O_RDONLY);
52 if (fd < 0)
53 err(1, "open: %s", keyfile);
54 if (readkey(fd, param.key, sizeof(param.key)) < 0)
55 printerr("readkey: %s", keyfile);
56 param.keyloaded = 1;
57 if (close(fd) < 0)
58 err(1, "close: %s", keyfile);
59 }
60
61 static void
62 pack(struct sctx *sctx, struct bctx *bctx)
63 {
64 struct chunker *c;
65
66 if ((c = copen(0, BSIZEMIN, BSIZEMAX, HMASKBITS, WINSIZE,
67 param.seed)) == NULL)
68 printerr("copen");
69
70 while (cfill(c) > 0) {
71 unsigned char md[MDSIZE];
72 void *buf;
73 size_t n;
74
75 buf = cget(c, &n);
76 if (buf == NULL)
77 printerr("cget");
78 if (bput(bctx, buf, n, md) < 0)
79 printerr("bput");
80 if (sput(sctx, md) < 0)
81 printerr("sput");
82 cdrain(c);
83 }
84 cclose(c);
85 }
86
87 static void
88 usage(void)
89 {
90 fprintf(stderr, "usage: %s [-v] [-k keyfile] [-r repo] name\n", argv0);
91 exit(1);
92 }
93
94 int
95 main(int argc, char *argv[])
96 {
97 char spath[PATH_MAX];
98 char bpath[PATH_MAX];
99 struct sctx *sctx;
100 struct bctx *bctx;
101 char *keyfile = NULL;
102 char *repo = ".";
103 int lfd;
104
105 ARGBEGIN {
106 case 'k':
107 keyfile = EARGF(usage());
108 break;
109 case 'r':
110 repo = EARGF(usage());
111 break;
112 case 'v':
113 verbose++;
114 break;
115 default:
116 usage();
117 } ARGEND
118
119 if (argc != 1)
120 usage();
121
122 if (snprintf(spath, sizeof(spath), "%s/archive/%s",
123 repo, argv[0]) >= sizeof(spath))
124 errx(1, "snprintf: %s: path too long", spath);
125 if (snprintf(bpath, sizeof(bpath), "%s/storage",
126 repo) >= sizeof(bpath))
127 errx(1, "snprintf: %s: path too long", bpath);
128
129 if ((lfd = lockrepo(repo)) < 0)
130 errx(1, "failed to lock repository");
131
132 loadkey(keyfile);
133 loadstate(repo);
134
135 if (screat(spath, 0600, &sctx) < 0)
136 printerr("screat: %s", spath);
137 if (bopen(bpath, B_RDWR, 0600, &bctx) < 0)
138 printerr("bopen: %s", bpath);
139
140 pack(sctx, bctx);
141
142 if (bclose(bctx) < 0)
143 printerr("bclose: %s", bpath);
144 if (sclose(sctx) < 0)
145 printerr("sclose: %s", spath);
146
147 if (unlockrepo(lfd) < 0)
148 errx(1, "failed to unlock repository");
149 return 0;
150 }