diff options
author | sobomax <sobomax@FreeBSD.org> | 2005-08-29 23:08:01 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2005-08-29 23:08:01 +0000 |
commit | b96a97ffc377d40044fc72c7f4147b6dbd1ffea0 (patch) | |
tree | 4e9d787b2273d2613b5d6bb2dd121fc1ae406970 | |
parent | 807c0b25414dae45f1b35c6e919e41947538335b (diff) | |
download | FreeBSD-src-b96a97ffc377d40044fc72c7f4147b6dbd1ffea0.zip FreeBSD-src-b96a97ffc377d40044fc72c7f4147b6dbd1ffea0.tar.gz |
Extend utility to allow recovering single file from the deffective
media.
MFC after: 2 weeks
-rw-r--r-- | sbin/recoverdisk/recoverdisk.c | 40 | ||||
-rw-r--r-- | tools/tools/recoverdisk/README | 7 | ||||
-rw-r--r-- | tools/tools/recoverdisk/recoverdisk.c | 40 |
3 files changed, 61 insertions, 26 deletions
diff --git a/sbin/recoverdisk/recoverdisk.c b/sbin/recoverdisk/recoverdisk.c index 89c2f49..d30055a 100644 --- a/sbin/recoverdisk/recoverdisk.c +++ b/sbin/recoverdisk/recoverdisk.c @@ -18,9 +18,11 @@ #include <unistd.h> #include <sys/queue.h> #include <sys/disk.h> +#include <sys/stat.h> #define BIGSIZE (1024 * 1024) #define MEDIUMSIZE (64 * 1024) +#define MINSIZE (512) struct lump { off_t start; @@ -53,10 +55,11 @@ main(int argc, const char **argv) struct lump *lp; off_t t, d; size_t i, j; - int error; + int error, flags; u_char *buf; - u_int sectorsize; + u_int sectorsize, minsize; time_t t1, t2; + struct stat sb; if (argc < 2) @@ -68,22 +71,35 @@ main(int argc, const char **argv) fdr = open(argv[1], O_RDONLY); if (fdr < 0) err(1, "Cannot open read descriptor %s", argv[1]); + + error = fstat(fdr, &sb); + if (error < 0) + err(1, "fstat failed"); + flags = O_WRONLY; + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); + if (error < 0) + err(1, "DIOCGSECTORSIZE failed"); + minsize = sectorsize; + + error = ioctl(fdr, DIOCGMEDIASIZE, &t); + if (error < 0) + err(1, "DIOCGMEDIASIZE failed"); + } else { + sectorsize = 1; + t = sb.st_size; + minsize = MINSIZE; + flags |= O_CREAT | O_TRUNC; + } + if (argc > 2) { - fdw = open(argv[2], O_WRONLY); + fdw = open(argv[2], flags, DEFFILEMODE); if (fdw < 0) err(1, "Cannot open write descriptor %s", argv[2]); } else { fdw = -1; } - error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); - if (error < 0) - err(1, "DIOCGSECTORSIZE failed"); - - error = ioctl(fdr, DIOCGMEDIASIZE, &t); - if (error < 0) - err(1, "DIOCGMEDIASIZE failed"); - new_lump(0, t, 0); d = 0; @@ -100,7 +116,7 @@ main(int argc, const char **argv) if (lp->state == 1) i = MEDIUMSIZE; if (lp->state > 1) - i = sectorsize; + i = minsize; time(&t2); if (t1 != t2 || lp->len < BIGSIZE) { printf("\r%13jd %7zu %13jd %3d %13jd %13jd %.8f", diff --git a/tools/tools/recoverdisk/README b/tools/tools/recoverdisk/README index 8766f41..4f7624a 100644 --- a/tools/tools/recoverdisk/README +++ b/tools/tools/recoverdisk/README @@ -1,7 +1,7 @@ $FreeBSD$ -This is a small tool which will read an entire disk(partition) using -1M blocks and optionally write the read data to a file or disk. +This is a small tool which will read an entire disk(partition) or file +using 1M blocks and optionally write the read data to a file or disk. If a read error happens, the 1M block gets put on the end of the worklist and will be retried with 64k blocksize. @@ -20,3 +20,6 @@ or salvage a floppy: touch myfloppy.flp recoverdisk /dev/fd0 myfloppy.flp +or recover a single file from the unreadable media: + + recoverdisk /cdrom/file.avi file.avi diff --git a/tools/tools/recoverdisk/recoverdisk.c b/tools/tools/recoverdisk/recoverdisk.c index 89c2f49..d30055a 100644 --- a/tools/tools/recoverdisk/recoverdisk.c +++ b/tools/tools/recoverdisk/recoverdisk.c @@ -18,9 +18,11 @@ #include <unistd.h> #include <sys/queue.h> #include <sys/disk.h> +#include <sys/stat.h> #define BIGSIZE (1024 * 1024) #define MEDIUMSIZE (64 * 1024) +#define MINSIZE (512) struct lump { off_t start; @@ -53,10 +55,11 @@ main(int argc, const char **argv) struct lump *lp; off_t t, d; size_t i, j; - int error; + int error, flags; u_char *buf; - u_int sectorsize; + u_int sectorsize, minsize; time_t t1, t2; + struct stat sb; if (argc < 2) @@ -68,22 +71,35 @@ main(int argc, const char **argv) fdr = open(argv[1], O_RDONLY); if (fdr < 0) err(1, "Cannot open read descriptor %s", argv[1]); + + error = fstat(fdr, &sb); + if (error < 0) + err(1, "fstat failed"); + flags = O_WRONLY; + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); + if (error < 0) + err(1, "DIOCGSECTORSIZE failed"); + minsize = sectorsize; + + error = ioctl(fdr, DIOCGMEDIASIZE, &t); + if (error < 0) + err(1, "DIOCGMEDIASIZE failed"); + } else { + sectorsize = 1; + t = sb.st_size; + minsize = MINSIZE; + flags |= O_CREAT | O_TRUNC; + } + if (argc > 2) { - fdw = open(argv[2], O_WRONLY); + fdw = open(argv[2], flags, DEFFILEMODE); if (fdw < 0) err(1, "Cannot open write descriptor %s", argv[2]); } else { fdw = -1; } - error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); - if (error < 0) - err(1, "DIOCGSECTORSIZE failed"); - - error = ioctl(fdr, DIOCGMEDIASIZE, &t); - if (error < 0) - err(1, "DIOCGMEDIASIZE failed"); - new_lump(0, t, 0); d = 0; @@ -100,7 +116,7 @@ main(int argc, const char **argv) if (lp->state == 1) i = MEDIUMSIZE; if (lp->state > 1) - i = sectorsize; + i = minsize; time(&t2); if (t1 != t2 || lp->len < BIGSIZE) { printf("\r%13jd %7zu %13jd %3d %13jd %13jd %.8f", |