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, ¶m) < 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 }