tdunpack.c - dedup - data deduplication program
HTML git clone git://bitreich.org/dedup/ git://hg6vgqziawt5s4dj.onion/dedup/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
DIR LICENSE
---
tdunpack.c (2434B)
---
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <sys/file.h>
4
5 #include <err.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12
13 #include "arg.h"
14 #include "blake2.h"
15 #include "dedup.h"
16
17 struct extract_args {
18 uint8_t *md;
19 int fd;
20 int ret;
21 };
22
23 static struct snap_hdr snap_hdr;
24 static struct blk_hdr blk_hdr;
25 static int ifd;
26 static int sfd;
27 static int hash_algo = HASH_BLAKE2B;
28 static int compr_algo = COMPR_LZ4;
29
30 int verbose;
31 char *argv0;
32
33 static int
34 extract(struct snap *snap, void *arg)
35 {
36 uint8_t *buf[2];
37 struct extract_args *args = arg;
38 struct compr_ctx ctx;
39 uint64_t i;
40
41 if (memcmp(snap->md, args->md, sizeof(snap->md)) != 0)
42 return WALK_CONTINUE;
43
44 if (compr_init(&ctx, compr_algo) < 0)
45 errx(1, "compr_init failed");
46 buf[0] = alloc_buf(BLKSIZE_MAX);
47 buf[1] = alloc_buf(compr_size(&ctx, BLKSIZE_MAX));
48 for (i = 0; i < snap->nr_blk_descs; i++) {
49 struct blk_desc *blk_desc;
50 size_t blksize;
51
52 blk_desc = &snap->blk_desc[i];
53 read_blk(sfd, buf[1], blk_desc);
54 blksize = decompr(&ctx, buf[1], buf[0], blk_desc->size, BLKSIZE_MAX);
55 xwrite(args->fd, buf[0], blksize);
56 }
57 free_buf(buf[1]);
58 free_buf(buf[0]);
59 compr_final(&ctx);
60 args->ret = 0;
61 return WALK_STOP;
62 }
63
64 static void
65 init(void)
66 {
67 ifd = open(SNAPSF, O_RDONLY, 0600);
68 if (ifd < 0)
69 err(1, "open %s", SNAPSF);
70
71 sfd = open(STOREF, O_RDONLY, 0600);
72 if (sfd < 0)
73 err(1, "open %s", STOREF);
74
75 if (flock(ifd, LOCK_NB | LOCK_EX) < 0 ||
76 flock(sfd, LOCK_NB | LOCK_EX) < 0)
77 err(1, "flock");
78
79 xlseek(ifd, 0, SEEK_SET);
80 load_snap_hdr(ifd, &snap_hdr);
81 xlseek(sfd, 0, SEEK_SET);
82 load_blk_hdr(sfd, &blk_hdr, &compr_algo, &hash_algo);
83 }
84
85 static void
86 term(void)
87 {
88 close(ifd);
89 close(sfd);
90 }
91
92 static void
93 usage(void)
94 {
95 fprintf(stderr, "usage: %s [-v] id [repo]\n", argv0);
96 exit(1);
97 }
98
99 int
100 main(int argc, char *argv[])
101 {
102 uint8_t md[MD_SIZE];
103 char *repo, *id = NULL;
104 struct extract_args args;
105
106 ARGBEGIN {
107 case 'v':
108 verbose++;
109 break;
110 default:
111 usage();
112 } ARGEND
113
114 switch (argc) {
115 case 1:
116 id = argv[0];
117 repo = ".";
118 break;
119 case 2:
120 id = argv[0];
121 repo = argv[1];
122 break;
123 default:
124 usage();
125 };
126
127 if (chdir(repo) < 0)
128 err(1, "chdir: %s", repo);
129
130 init();
131 str2bin(id, md);
132 args.md = md;
133 args.fd = STDOUT_FILENO;
134 args.ret = -1;
135 walk_snap(ifd, &snap_hdr, extract, &args);
136 if (args.ret != 0)
137 errx(1, "unknown snapshot: %s", id);
138 term();
139 return 0;
140 }