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 }