dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | 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, &param) < 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 }