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