URI: 
       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 }