dedup

data deduplication program
git clone git://git.2f30.org/dedup.git
Log | Files | Refs | README | LICENSE

dunpack.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 }