dedup

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

dup-pack.c (2805B)


      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 "chunker.h"
     15 #include "config.h"
     16 #include "key.h"
     17 #include "lock.h"
     18 #include "misc.h"
     19 #include "snap.h"
     20 #include "state.h"
     21 
     22 struct param param;
     23 int verbose;
     24 char *argv0;
     25 
     26 static void
     27 loadstate(char *repo)
     28 {
     29 	char path[PATH_MAX];
     30 	int fd;
     31 
     32 	if (snprintf(path, sizeof(path), "%s/state", repo) >= sizeof(path))
     33 		errx(1, "snprintf: %s: path too long", path);
     34 	fd = open(path, O_RDONLY);
     35 	if (fd < 0)
     36 		err(1, "open: %s", path);
     37 	if (readstate(fd, &param) < 0)
     38 		printerr("readstate: %s", path);
     39 	if (close(fd) < 0)
     40 		err(1, "close: %s", path);
     41 }
     42 
     43 static void
     44 loadkey(char *keyfile)
     45 {
     46 	int fd;
     47 
     48 	if (keyfile == NULL)
     49 		return;
     50 
     51 	fd = open(keyfile, O_RDONLY);
     52 	if (fd < 0)
     53 		err(1, "open: %s", keyfile);
     54 	if (readkey(fd, param.key, sizeof(param.key)) < 0)
     55 		printerr("readkey: %s", keyfile);
     56 	param.keyloaded = 1;
     57 	if (close(fd) < 0)
     58 		err(1, "close: %s", keyfile);
     59 }
     60 
     61 static void
     62 pack(struct sctx *sctx, struct bctx *bctx)
     63 {
     64 	struct chunker *c;
     65 
     66 	if ((c = copen(0, BSIZEMIN, BSIZEMAX, HMASKBITS, WINSIZE,
     67 	               param.seed)) == NULL)
     68 		printerr("copen");
     69 
     70 	while (cfill(c) > 0) {
     71 		unsigned char md[MDSIZE];
     72 		void *buf;
     73 		size_t n;
     74 
     75 		buf = cget(c, &n);
     76 		if (buf == NULL)
     77 			printerr("cget");
     78 		if (bput(bctx, buf, n, md) < 0)
     79 			printerr("bput");
     80 		if (sput(sctx, md) < 0)
     81 			printerr("sput");
     82 		cdrain(c);
     83 	}
     84 	cclose(c);
     85 }
     86 
     87 static void
     88 usage(void)
     89 {
     90 	fprintf(stderr, "usage: %s [-v] [-k keyfile] [-r repo] name\n", argv0);
     91 	exit(1);
     92 }
     93 
     94 int
     95 main(int argc, char *argv[])
     96 {
     97 	char spath[PATH_MAX];
     98 	char bpath[PATH_MAX];
     99 	struct sctx *sctx;
    100 	struct bctx *bctx;
    101 	char *keyfile = NULL;
    102 	char *repo = ".";
    103 	int lfd;
    104 
    105 	ARGBEGIN {
    106 	case 'k':
    107 		keyfile = EARGF(usage());
    108 		break;
    109 	case 'r':
    110 		repo = EARGF(usage());
    111 		break;		
    112 	case 'v':
    113 		verbose++;
    114 		break;
    115 	default:
    116 		usage();
    117 	} ARGEND
    118 
    119 	if (argc != 1)
    120 		usage();
    121 
    122 	if (snprintf(spath, sizeof(spath), "%s/archive/%s",
    123 	             repo, argv[0]) >= sizeof(spath))
    124 		errx(1, "snprintf: %s: path too long", spath);
    125 	if (snprintf(bpath, sizeof(bpath), "%s/storage",
    126 	             repo) >= sizeof(bpath))
    127 		errx(1, "snprintf: %s: path too long", bpath);
    128 
    129 	if ((lfd = lockrepo(repo)) < 0)
    130 		errx(1, "failed to lock repository");
    131 
    132 	loadkey(keyfile);
    133 	loadstate(repo);
    134 
    135 	if (screat(spath, 0600, &sctx) < 0)
    136 		printerr("screat: %s", spath);
    137 	if (bopen(bpath, B_RDWR, 0600, &bctx) < 0)
    138 		printerr("bopen: %s", bpath);
    139 
    140 	pack(sctx, bctx);
    141 
    142 	if (bclose(bctx) < 0)
    143 		printerr("bclose: %s", bpath);
    144 	if (sclose(sctx) < 0)
    145 		printerr("sclose: %s", spath);
    146 
    147 	if (unlockrepo(lfd) < 0)
    148 		errx(1, "failed to unlock repository");
    149 	return 0;
    150 }