2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
19 #include <sys/queue.h>
23 #define BIGSIZE (1024 * 1024)
24 #define MEDIUMSIZE (64 * 1024)
31 TAILQ_ENTRY(lump) list;
34 static TAILQ_HEAD(, lump) lumps = TAILQ_HEAD_INITIALIZER(lumps);
38 new_lump(off_t start, off_t len, int state)
42 lp = malloc(sizeof *lp);
44 err(1, "Malloc failed");
48 TAILQ_INSERT_TAIL(&lumps, lp, list);
52 main(int argc, const char **argv)
60 u_int sectorsize, minsize;
66 errx(1, "Usage: %s source-drive [destination]", argv[0]);
68 buf = malloc(BIGSIZE);
70 err(1, "Cannot allocate %d bytes buffer", BIGSIZE);
71 fdr = open(argv[1], O_RDONLY);
73 err(1, "Cannot open read descriptor %s", argv[1]);
75 error = fstat(fdr, &sb);
77 err(1, "fstat failed");
79 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
80 error = ioctl(fdr, DIOCGSECTORSIZE, §orsize);
82 err(1, "DIOCGSECTORSIZE failed");
85 error = ioctl(fdr, DIOCGMEDIASIZE, &t);
87 err(1, "DIOCGMEDIASIZE failed");
92 flags |= O_CREAT | O_TRUNC;
96 fdw = open(argv[2], flags, DEFFILEMODE);
98 err(1, "Cannot open write descriptor %s", argv[2]);
108 lp = TAILQ_FIRST(&lumps);
111 TAILQ_REMOVE(&lumps, lp, list);
112 while (lp->len > 0) {
114 if (lp->len < BIGSIZE)
121 if (t1 != t2 || lp->len < BIGSIZE) {
122 printf("\r%13jd %7zu %13jd %3d %13jd %13jd %.8f",
129 (double)d/(double)t);
133 errx(1, "BOGUS i %10jd", (intmax_t)i);
136 j = pread(fdr, buf, i, lp->start);
140 j = pwrite(fdw, buf, i, lp->start);
144 printf("\nWrite error at %jd/%zu\n",
150 printf("\n%jd %zu failed %d\n", lp->start, i, errno);
151 new_lump(lp->start, i, lp->state + 1);
157 printf("\nCompleted\n");