Hello community, here is the log from the commit of package dd_rescue for openSUSE:Factory checked in at 2013-02-11 10:59:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dd_rescue (Old) and /work/SRC/openSUSE:Factory/.dd_rescue.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dd_rescue", Maintainer is "" Changes: -------- --- /work/SRC/openSUSE:Factory/dd_rescue/dd_rescue.changes 2013-02-04 19:29:56.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.dd_rescue.new/dd_rescue.changes 2013-02-11 10:59:07.000000000 +0100 @@ -1,0 +2,8 @@ +Mon Feb 11 00:15:58 CET 2013 - [email protected] + +- Update to dd_rescue-1.32: + * New option -x to append to outfile. + * New option -Y (can be used multiple times) to specify 2ndary + output files. + +------------------------------------------------------------------- Old: ---- dd_rescue-1.31.tar.gz New: ---- dd_rescue-1.32.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dd_rescue.spec ++++++ --- /var/tmp/diff_new_pack.CsfUSS/_old 2013-02-11 10:59:08.000000000 +0100 +++ /var/tmp/diff_new_pack.CsfUSS/_new 2013-02-11 10:59:08.000000000 +0100 @@ -17,7 +17,7 @@ Name: dd_rescue -Version: 1.31 +Version: 1.32 Release: 0 Summary: Data Copying in the Presence of I/O Errors License: GPL-2.0 or GPL-3.0 ++++++ dd_rescue-1.31.tar.gz -> dd_rescue-1.32.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/Makefile new/dd_rescue/Makefile --- old/dd_rescue/Makefile 2013-02-03 14:32:29.000000000 +0100 +++ new/dd_rescue/Makefile 2013-02-10 09:12:28.000000000 +0100 @@ -1,8 +1,8 @@ # Makefile for dd_rescue # (c) [email protected], 99/10/09, GNU GPL -# $Id: Makefile,v 1.46 2013/02/03 13:32:29 garloff Exp $ +# $Id: Makefile,v 1.48 2013/02/10 08:12:28 garloff Exp $ -VERSION = 1.31 +VERSION = 1.32 DESTDIR = @@ -59,7 +59,7 @@ rm -f *~ dist: distclean - tar cvzf ../dd_rescue-$(VERSION).tar.gz -C.. --exclude=$(MYDIR)/CV* --exclude $(MYDIR)/dd_rescue2* --exclude $(MYDIR)/.*.sw? $(MYDIR) + tar cvzf ../dd_rescue-$(VERSION).tar.gz -C.. --exclude=$(MYDIR)/CV* --exclude $(MYDIR)/dd_rescue2* --exclude $(MYDIR)/.* $(MYDIR) install: $(TARGETS) mkdir -p $(INSTALLDIR) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/README.dd_rescue new/dd_rescue/README.dd_rescue --- old/dd_rescue/README.dd_rescue 2013-02-03 19:05:29.000000000 +0100 +++ new/dd_rescue/README.dd_rescue 2013-02-08 00:59:53.000000000 +0100 @@ -157,6 +157,10 @@ (option -4); this option has been designed to meet the BSI GSDS M7.15 criteria for safe deletion of data. https://www.bsi.bund.de/ContentBSI/grundschutz/baustein-datenschutz/html/m07015.html +* Starting with 1.32, you can write the data to multiple output files + at once (option -Y); it can be used more than once. + Also, if you want to concatenate data from multiple input files, + the option -x (extend/append) may prove useful. Copyright @@ -199,4 +203,4 @@ Kurt Garloff <[email protected]>, 2000-08-30 -$Id: README.dd_rescue,v 1.23 2013/02/03 18:03:26 garloff Exp $ +$Id: README.dd_rescue,v 1.24 2013/02/07 23:59:53 garloff Exp $ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/dd_rescue.c new/dd_rescue/dd_rescue.c --- old/dd_rescue/dd_rescue.c 2013-02-03 19:05:29.000000000 +0100 +++ new/dd_rescue/dd_rescue.c 2013-02-10 22:37:10.000000000 +0100 @@ -37,7 +37,6 @@ * - Optional colors * - Use dlopen to open libfallocate rather than linking to it ... * - Display more infos on errors by collecting info from syslog - * - Allow seoncdary output file */ #ifndef VERSION @@ -47,7 +46,7 @@ # define "(unknown compiler)" #endif -#define ID "$Id: dd_rescue.c,v 1.149 2013/02/03 18:03:26 garloff Exp $" +#define ID "$Id: dd_rescue.c,v 1.166 2013/02/10 21:37:10 garloff Exp $" #ifndef BUF_SOFTBLOCKSIZE # define BUF_SOFTBLOCKSIZE 65536 @@ -80,10 +79,12 @@ #include <signal.h> #include <time.h> #include <utime.h> +#include <limits.h> #include <sys/time.h> #include <sys/stat.h> #include "frandom.h" +#include "list.h" #ifdef HAVE_GETOPT_H #include <getopt.h> @@ -140,6 +141,7 @@ char noextend, avoidwrite; char prng_libc, prng_frnd; char bsim715, bsim715_4, bsim715_2ndpass; +char extend; char* prng_sfile; void *prng_state, *prng_state2; @@ -152,6 +154,19 @@ unsigned int pagesize = 4096; +/* multiple output files */ +typedef struct _ofile { + char* name; + int fd; + char cdev; +} ofile_t; +LISTDECL(ofile_t); +LISTTYPE(ofile_t) *ofiles; + +typedef char* charp; +LISTDECL(charp); +LISTTYPE(charp) *freenames; + #ifndef UP # define UP "\x1b[A" # define DOWN "\n" @@ -254,24 +269,19 @@ return fdes; } -/** Checks whether files are seekable */ -static void check_seekable(const int id, const int od) +/** Checks whether file is seekable */ +static void check_seekable(const int fd, char *ischr, char* msg) { errno = 0; - if (!i_chr && lseek(id, (off_t)0, SEEK_SET) != 0) { - fplog(stderr, "dd_rescue: (warning): input file is not seekable!\n"); - fplog(stderr, "dd_rescue: (warning): %s\n", strerror(errno)); - i_chr = 1; + if (!*ischr && lseek(fd, (off_t)0, SEEK_SET) != 0) { + if (msg) { + fplog(stderr, "dd_rescue: (warning): file %s is not seekable!\n", msg); + fplog(stderr, "dd_rescue: (warning): %s\n", strerror(errno)); + } + *ischr = 1; } //else // lseek(id, (off_t)0, SEEK_SET); errno = 0; - if (!o_chr && lseek(od, (off_t)0, SEEK_SET) != 0) { - fplog(stderr, "dd_rescue: (warning): output file is not seekable!\n"); - fplog(stderr, "dd_rescue: (warning): %s\n", strerror(errno)); - o_chr = 1; - } //else - // lseek(od, (off_t)0, SEEK_SET); - errno = 0; } /** Calc position in graph */ @@ -368,7 +378,8 @@ if (!quiet) fplog(stderr, "dd_rescue: (info): expect to copy %LikB from %s\n", estxfer/1024, iname); - preparegraph(); + if (!graph) + preparegraph(); } int output_length() @@ -441,22 +452,20 @@ fplog(stderr, "dd_rescue: (warning): %s is a block device; -a not recommended; -A recommended\n", oname); return; } - eff_opos = opos == -1? ipos: opos; + eff_opos = opos == -INT_MAX? ipos: opos; if (sparse && (eff_opos < stbuf.st_size)) fplog(stderr, "dd_rescue: (warning): write into %s (@%li/%li): sparse not recommended\n", oname, eff_opos, stbuf.st_size); } #ifdef HAVE_FALLOCATE -static void do_fallocate() +static void do_fallocate(int fd, char* onm) { struct stat stbuf; off_t to_falloc, alloced; - if (o_chr) - return; if (!estxfer) return; - if (fstat(odes, &stbuf)) + if (fstat(fd, &stbuf)) return; if (!S_ISREG(stbuf.st_mode)) return; @@ -465,13 +474,13 @@ if (to_falloc <= 0) return; #ifdef HAVE_LIBFALLOCATE - if (linux_fallocate64(odes, FALLOC_FL_KEEP_SIZE, + if (linux_fallocate64(fd, FALLOC_FL_KEEP_SIZE, opos, to_falloc)) #else - if (fallocate64(odes, 1, opos, to_falloc)) + if (fallocate64(fd, 1, opos, to_falloc)) #endif fplog(stderr, "dd_rescue: (warning): fallocate %s (%Li, %Li) failed: %s\n", - oname, opos, to_falloc, strerror(errno)); + onm, opos, to_falloc, strerror(errno)); } #endif @@ -568,8 +577,13 @@ FILE *report = (!quiet || nrerr)? stderr: 0; in_report = 1; if (report) { - fplog(report, "dd_rescue: (info): Summary for %s -> %s:\n", iname, oname); - fprintf(report, "%s%s%s%s", down, down, down, down); + fplog(report, "dd_rescue: (info): Summary for %s -> %s", iname, oname); + LISTTYPE(ofile_t) *of; + LISTFOREACH(ofiles, of) + fplog(report, "; %s", LISTDATA(of).name); + if (logfd > 0) + fprintf(logfd, ":\n"); + fprintf(report, ":\n%s%s%s%s", down, down, down, down); printstatus(report, logfd, 0, 1); if (avoidwrite) fplog(report, "dd_rescue: (info): Avoided %LikB of writes (performed %LikB)\n", axfer/1024, (sxfer-axfer)/1024); @@ -607,56 +621,65 @@ return err; } -static int mayexpandfile() -{ +static int mayexpandfile(char* onm) +{ struct stat st; off_t maxopos = opos; if (init_opos > opos) maxopos = init_opos; - stat(oname, &st); + stat(onm, &st); if (!S_ISREG(st.st_mode)) return 0; if (st.st_size < maxopos) - return truncate(oname, maxopos); + return truncate(onm, maxopos); else return 0; } -#define ZFREE(ptr) \ - do { \ - if(ptr) \ - free(ptr); \ - ptr = 0; \ - } while(0) - -int cleanup() +int sync_close(int fd, char* nm, char chr) { - int rc, errs = 0; - if (odes != -1) { + int rc, err = 0; + if (fd != -1) { /* Make sure, the output file is expanded to the last (first) position * FIXME: 0 byte writes do NOT expand file -- mayexpandfile() will * take care of that. */ if (!avoidwrite) - rc = pwrite(odes, buf, 0, opos); - rc = fsync(odes); - if (rc && !o_chr) { + rc = pwrite(fd, buf, 0, opos); + rc = fsync(fd); + if (rc && !chr) { fplog(stderr, "dd_rescue: (warning): fsync %s (%.1fk): %s!\n", - oname, (float)opos/1024, strerror(errno)); - ++errs; + nm, (float)opos/1024, strerror(errno)); + ++err; errno = 0; } - rc = close(odes); + rc = close(fd); if (rc) { fplog(stderr, "dd_rescue: (warning): close %s (%.1fk): %s!\n", - oname, (float)opos/1024, strerror(errno)); - ++errs; + nm, (float)opos/1024, strerror(errno)); + ++err; } - if (sparse) - rc = mayexpandfile(); + if (sparse) { + rc = mayexpandfile(nm); if (rc) fplog(stderr, "dd_rescue: (warning): seek %s (%1.fk): %s!\n", - oname, (float)opos/1024, strerror(errno)); + nm, (float)opos/1024, strerror(errno)); + } + } + return err; +} + +#define ZFREE(ptr) \ + do { \ + if (ptr) \ + free(ptr); \ + ptr = 0; \ + } while(0) + +int cleanup() +{ + int rc, errs = 0; + errs += sync_close(odes, oname, o_chr); if (ides != -1) { rc = close(ides); if (rc) { @@ -667,12 +690,19 @@ } if (logfd) fclose(logfd); + LISTTYPE(ofile_t) *of; + LISTFOREACH(ofiles, of) { + ofile_t *oft = &(LISTDATA(of)); + rc = sync_close(oft->fd, oft->name, oft->cdev); + } ZFREE(buf2); ZFREE(buf); ZFREE(graph); if (preserve) copytimes(iname, oname); - ZFREE(oname); + LISTFOREACH(ofiles, of) + if (preserve) + copytimes(iname, LISTDATA(of).name); if (prng_state2) { frandom_release(prng_state2); prng_state2 = 0; @@ -681,6 +711,13 @@ frandom_release(prng_state); prng_state = 0; } + LISTTREEDEL(ofiles, ofile_t); + LISTTYPE(charp) *onl; + LISTFOREACH(freenames, onl) { + free(LISTDATA(onl)); + LISTDATA(onl) = 0; + } + LISTTREEDEL(freenames, charp); return errs; } @@ -784,6 +821,25 @@ } nrerr++; } + int oldeno = errno; + char oldochr = o_chr; + LISTTYPE(ofile_t) *of; + LISTFOREACH(ofiles, of) { + ssize_t e2, w2 = 0; + ofile_t *oft = &(LISTDATA(of)); + o_chr = oft->cdev; + do { + w2 += (e2 = mypwrite(oft->fd, buf+w2, towrite-w2, opos+w2-reverse*towrite)); + if (e2 == -1) + w2++; + } while ((e2 == -1 && (errno == EINTR || errno == EAGAIN)) + || (w2 < towrite && e2 > 0 && errno == 0)); + if (w2 < towrite && e2 != 0) + fplog(stderr, "dd_rescue: (warning): 2ndary write %s (%.1fk): %s\n", + oft->name, (float)opos/1024, strerror(errno)); + } + o_chr = oldochr; + errno = oldeno; return (/*err == -1? err:*/ wr); } @@ -1059,24 +1115,25 @@ { ssize_t toread; int fd_pipe[2]; + LISTTYPE(ofile_t) *oft; if (pipe(fd_pipe) < 0) return copyfile_softbs(max); while ((toread = blockxfer(max, softbs)) > 0) { + off_t old_ipos = ipos, old_opos = opos; ssize_t rd = splice(ides, &ipos, fd_pipe[1], NULL, toread, SPLICE_F_MOVE | SPLICE_F_MORE); if (rd < 0) { - close(fd_pipe[0]); close(fd_pipe[1]); if (!quiet) fplog(stderr, "dd_rescue: (info): %s (%.1fk): fall back to userspace copy\n%s%s%s%s", iname, (float)ipos/1024, down, down, down, down); + close(fd_pipe[0]); close(fd_pipe[1]); return copyfile_softbs(max); } if (rd == 0) { if (!quiet) fplog(stderr, "dd_rescue: (info): read %s (%.1fk): EOF (splice)\n", iname, (float)ipos/1024); - close(fd_pipe[0]); close(fd_pipe[1]); - return 0; + break; } while (rd) { ssize_t wr = splice(fd_pipe[0], NULL, odes, &opos, rd, @@ -1087,6 +1144,37 @@ } rd -= wr; xfer += wr; sxfer += wr; } + off_t new_ipos = ipos, new_opos = opos; + LISTFOREACH(ofiles, oft) { + ipos = old_ipos; opos = old_opos; + rd = splice(ides, &ipos, fd_pipe[1], NULL, toread, + SPLICE_F_MOVE | SPLICE_F_MORE); + /* Simplify error handling, it worked before ... */ + if (rd <= 0) { + fplog(stderr, "dd_rescue: (error): Confused: splice() failed unexpectedly: %s\n%s%s%s%s", + strerror(errno), down, down, down, down); + /* We should abort here .... */ + ipos = new_ipos; opos = new_opos; + continue; + } + while (rd) { + ssize_t wr = splice(fd_pipe[0], NULL, LISTDATA(oft).fd, &opos, rd, + SPLICE_F_MOVE | SPLICE_F_MORE); + if (wr < 0) { + fplog(stderr, "dd_rescue: (error): Confused: splice() failed unexpectedly: %s\n%s%s%s%s", + strerror(errno), down, down, down, down); + /* We should abort here .... */ + ipos = new_ipos; opos = new_opos; + continue; + } + rd -= wr; + } + } + if (ipos != new_ipos || opos != new_opos) { + fplog(stderr, "dd_rescue: (error): Confused: splice progress inconsistent: %zi %zi %zi %zi\n%s%s%s%s", + ipos, new_ipos, opos, new_opos, down, down, down, down); + ipos = new_ipos; opos = new_opos; + } advancepos(0, 0); if (syncfreq && !(xfer % (syncfreq*softbs))) printstatus((quiet? 0: stderr), 0, softbs, 1); @@ -1105,11 +1193,14 @@ void* prng_state2 = frandom_stdup(prng_state); clock_t orig_startclock = startclock; struct timeval orig_starttime; + LISTTYPE(ofile_t) *of; memcpy(&orig_starttime, &starttime, sizeof(starttime)); fprintf(stderr, "%s%s%s%sdd_rescue: (info): Triple overwrite (BSI M7.15): first pass ... (frandom) \n\n\n\n\n", up, up, up, up); ret += copyfile_softbs(max); fprintf(stderr, "syncing ... \n%s", up); ret += fsync(odes); + LISTFOREACH(ofiles, of) + fsync(LISTDATA(of).fd); /* TODO: better error handling */ frandom_release(prng_state); prng_state = prng_state2; prng_state2 = 0; @@ -1120,6 +1211,8 @@ ret += copyfile_softbs(max); fprintf(stderr, "syncing ... \n%s", up); ret += fsync(odes); + LISTFOREACH(ofiles, of) + fsync(LISTDATA(of).fd); /* TODO: better error handling */ bsim715_2ndpass = 0; if (bsim715_4) { @@ -1130,6 +1223,8 @@ ret += copyfile_softbs(max); fprintf(stderr, "syncing ... \n%s", up); ret += fsync(odes); + LISTFOREACH(ofiles, of) + fsync(LISTDATA(of).fd); bsim715_2ndpass = 1; iname = "FRND+invFRND+FRND2+ZERO"; } else @@ -1191,7 +1286,7 @@ fplog(stderr, "dd_rescue: (fatal): failed to read 4 bytes from \"%s\"!\n", prng_sfile); cleanup(); exit(29); } - srand(*sval); + srand(*sval); rand(); } else { ln = read(fd, sbf, 256); if (ln != 256) { @@ -1202,10 +1297,10 @@ } } else { if (!prng_seed) - prng_seed = time(0) - getpid(); - if (prng_libc) - srand(prng_seed); - else + prng_seed = frandom_getseedval(); + if (prng_libc) { + srand(prng_seed); rand(); + } else prng_state = frandom_init_lrand(prng_seed); } } @@ -1245,6 +1340,7 @@ fprintf(stderr, " -e maxerr exit after maxerr errors (def=0=infinite),\n"); fprintf(stderr, " -m maxxfer maximum amount of data to be transfered (def=0=inf),\n"); fprintf(stderr, " -M avoid extending outfile,\n"); + fprintf(stderr, " -x count opos from the end of outfile (eXtend)\n"); fprintf(stderr, " -y syncfrq frequency of fsync calls on outfile (def=512*softbs),\n"); fprintf(stderr, " -l logfile name of a file to log errors and summary to (def=\"\"),\n"); fprintf(stderr, " -o bbfile name of a file to log bad blocks numbers (def=\"\"),\n"); @@ -1267,12 +1363,13 @@ fprintf(stderr, " -i interactive: ask before overwriting data (def=no),\n"); fprintf(stderr, " -f force: skip some sanity checks (def=no),\n"); fprintf(stderr, " -p preserve: preserve ownership / perms (def=no),\n"); + fprintf(stderr, " -Y oname Secondary output file (multiple possible)\n"); fprintf(stderr, " -q quiet operation,\n"); fprintf(stderr, " -v verbose operation,\n"); fprintf(stderr, " -V display version and exit,\n"); fprintf(stderr, " -h display this help and exit.\n"); fprintf(stderr, "Instead of infile, -z/Z SEED or -z/Z SEEDFILE may be specified, taking the PRNG\n"); - fprintf(stderr, " from libc or frandom (RC4 based) as input. SEED = 0 means time(0)-getpid();\n"); + fprintf(stderr, " from libc or frandom (RC4 based) as input. SEED = 0 means a time based seed;\n"); fprintf(stderr, " Using /dev/urandom as SEEDFILE gives good pseudo random numbers.\n"); fprintf(stderr, "Likewise, -3 SEED/SEEDFILE will overwrite ofile 3 times (r,ir,0, BSI M7.15).\n"); fprintf(stderr, " With -4 SEED/SEEDFILE you get an additional random pass (r,ir,r2,0).\n\n"); @@ -1348,7 +1445,53 @@ return 0; return 1; } - + +char* retstrdupcat3(const char* dir, char dirsep, const char* inm) +{ + const char* ibase = basename(inm); + const int dlen = strlen(dir) + (dirsep>0? 1: dirsep); + char* ret = malloc(dlen + strlen(inm) + 1); + strcpy(ret, dir); + if (dirsep > 0) { + ret[dlen-1] = dirsep; + ret[dlen] = 0; + } + strcpy(ret+dlen, ibase); + LISTAPPEND(freenames, ret, charp); + return ret; +} + + +/** Fix output filename if it's a directory */ +char* dirappfile(char* onm) +{ + size_t oln = strlen(onm); + if (!strcmp(onm, ".")) { + char* ret = strdup(basename(iname)); + LISTAPPEND(freenames, ret, charp); + return ret; + } + if (oln > 0) { + char lastchr = onm[oln-1]; + if (lastchr == '/') + return retstrdupcat3(onm, 0, iname); + else if ((lastchr == '.') && + (oln > 1 && onm[oln-2] == '/')) + return retstrdupcat3(onm, -1, iname); + else if ((lastchr == '.') && + (oln > 2 && onm[oln-2] == '.' && onm[oln-3] == '/')) + return retstrdupcat3(onm, '/', iname); + else { /* Not clear by name, so test */ + struct stat stbuf; + int err = stat(onm, &stbuf); + if (!err && S_ISDIR(stbuf.st_mode)) + return retstrdupcat3(onm, '/', iname); + } + } + return onm; +} + + int main(int argc, char* argv[]) { int c; @@ -1356,7 +1499,7 @@ /* defaults */ softbs = 0; hardbs = 0; /* marker for defaults */ - maxerr = 0; ipos = (off_t)-1; opos = (off_t)-1; maxxfer = 0; + maxerr = 0; ipos = (off_t)-INT_MAX; opos = (off_t)-INT_MAX; maxxfer = 0; reverse = 0; dotrunc = 0; abwrerr = 0; sparse = 0; nosparse = 0; verbose = 0; quiet = 0; interact = 0; force = 0; preserve = 0; lname = 0; iname = 0; oname = 0; o_dir_in = 0; o_dir_out = 0; @@ -1370,15 +1513,18 @@ i_repeat = 0; i_rep_init = 0; i_rep_zero = 0; noextend = 0; avoidwrite = 0; bsim715 = 0; bsim715_4 = 0; bsim715_2ndpass = 0; + extend = 0; prng_libc = 0; prng_frnd = 0; prng_seed = 0; prng_sfile = 0; prng_state = 0; prng_state2 = 0; + ofiles = NULL; + #ifdef _SC_PAGESIZE pagesize = sysconf(_SC_PAGESIZE); #endif - while ((c = getopt(argc, argv, ":rtfihqvVwWaAdDkMRpPb:B:m:e:s:S:l:o:y:z:Z:3:4:")) != -1) { + while ((c = getopt(argc, argv, ":rtfihqvVwWaAdDkMRpPb:B:m:e:s:S:l:o:y:z:Z:3:4:xY:")) != -1) { switch (c) { case 'r': reverse = 1; break; case 'R': i_repeat = 1; break; @@ -1412,6 +1558,8 @@ case 'S': opos = readint(optarg); break; case 'l': lname = optarg; break; case 'o': bbname = optarg; break; + case 'x': extend = 1; break; + case 'Y': do { ofile_t of; of.name = optarg; of.fd = -1; of.cdev = 0; LISTAPPEND(ofiles, of, ofile_t); } while (0); break; case 'z': prng_libc = 1; if (is_filename(optarg)) prng_sfile = optarg; else prng_seed = readint(optarg); break; case 'Z': prng_frnd = 1; if (is_filename(optarg)) prng_sfile = optarg; else prng_seed = readint(optarg); break; case '3': prng_frnd = 1; if (is_filename(optarg)) prng_sfile = optarg; else prng_seed = readint(optarg); bsim715 = 1; break; @@ -1437,7 +1585,7 @@ iname = argv[optind++]; if (optind < argc) - oname = strdup(argv[optind++]); + oname = argv[optind++]; if (optind < argc) { fplog(stderr, "dd_rescue: (fatal): spurious options: %s ...\n", argv[optind]); printhelp(); @@ -1499,7 +1647,7 @@ syncfreq = (syncsz + softbs - 1) / softbs; /* Have those been set by cmdline params? */ - if (ipos == (off_t)-1) + if (ipos == (off_t)-INT_MAX) ipos = 0; if (dosplice && avoidwrite) { @@ -1515,33 +1663,11 @@ i_repeat = 1; } - /* Special case '.': same as iname (w/o path) */ - if (!strcmp(oname, ".")) { - free(oname); - oname = strdup(basename(iname)); - } else { /* Is oname a directory? */ - size_t oln = strlen(oname); - if (oln > 0) { - char lastchr = oname[oln-1]; - if (lastchr == '/') - oname = safe_strcat(oname, basename(iname)); - else if ((lastchr == '.') && - ((oln > 1 && oname[oln-2] == '/') || - (oln > 2 && oname[oln-2] == '.' && oname[oln-3] == '/'))) { - oname = safe_strcat(oname, "/"); - oname = safe_strcat(oname, basename(iname)); - } else { /* Not clear by name, so test */ - struct stat stbuf; - int err = stat(oname, &stbuf); - if (!err && S_ISDIR(stbuf.st_mode)) { - oname = safe_strcat(oname, "/"); - oname = safe_strcat(oname, basename(iname)); - } - } - } - } + /* Properly append input basename if output name is dir */ + oname = dirappfile(oname); identical = check_identical(iname, oname); + if (identical && dotrunc && !force) { fplog(stderr, "dd_rescue: (fatal): infile and outfile are identical and trunc turned on!\n"); cleanup(); exit(14); @@ -1603,7 +1729,8 @@ if (preserve) copyperm(ides, odes); - check_seekable(ides, odes); + check_seekable(ides, &i_chr, "input"); + check_seekable(odes, &o_chr, "output"); sparse_output_warn(); if (o_chr) { @@ -1628,7 +1755,7 @@ fprintf(stderr, "dd_rescue: (info): ipos set to the end: %.1fk\n", (float)ipos/1024); /* if opos not set, assume same position */ - if (opos == (off_t)-1) + if (opos == (off_t)-INT_MAX) opos = ipos; /* if explicitly set to zero, assume end of _existing_ file */ if (opos == 0) { @@ -1647,15 +1774,9 @@ } /* if opos not set, assume same position */ - if (opos == (off_t)-1) + if (opos == (off_t)-INT_MAX) opos = ipos; - if (ipos < 0 || opos < 0) { - fplog(stderr, "dd_rescue: (fatal): negative position requested (%.1fk)\n", (float)ipos/1024); - cleanup(); exit(25); - } - - if (identical) { fplog(stderr, "dd_rescue: (warning): infile and outfile are identical!\n"); if (opos > ipos && !reverse && !force) { @@ -1683,17 +1804,25 @@ reverse = 0; } - if (noextend) { + if (noextend || extend) { if (output_length() == -1) { - fplog(stderr, "dd_rescue: (fatal): asked not to extend output file but can't determine size\n"); + fplog(stderr, "dd_rescue: (fatal): asked to (not) extend output file but can't determine size\n"); cleanup(); exit(19); } + if (extend) + opos += olen; } input_length(); + if (ipos < 0 || opos < 0) { + fplog(stderr, "dd_rescue: (fatal): negative position requested (%.1fk)\n", (float)ipos/1024); + cleanup(); exit(25); + } + + #ifdef HAVE_FALLOCATE - if (falloc) - do_fallocate(); + if (falloc && !o_chr) + do_fallocate(odes, oname); #endif if (verbose) { @@ -1710,6 +1839,24 @@ fplog(stderr, "dd_rescue: (warning): triple overwrite with non-seekable output!\n"); } + LISTTYPE(ofile_t) *of; + LISTFOREACH(ofiles, of) { + int id; + ofile_t *oft = &(LISTDATA(of)); + oft->name = dirappfile(oft->name); + id = check_identical(iname, oft->name); + if (id) + fplog(stderr, "dd_rescue: (warning): Input file and secondary output file %s are identical!\n", oft->name); + oft->fd = openfile(oft->name, (avoidwrite? O_RDWR: O_WRONLY) | O_CREAT | o_dir_out | dotrunc); + check_seekable(oft->fd, &(oft->cdev), NULL); + if (preserve) + copyperm(ides, oft->fd); +#ifdef HAVE_FALLOCATE + if (falloc && !oft->cdev) + do_fallocate(oft->fd, oft->name); +#endif + } + /* Install signal handler */ signal(SIGHUP , breakhandler); signal(SIGINT , breakhandler); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/frandom.c new/dd_rescue/frandom.c --- old/dd_rescue/frandom.c 2013-02-03 17:21:27.000000000 +0100 +++ new/dd_rescue/frandom.c 2013-02-10 09:06:41.000000000 +0100 @@ -19,6 +19,7 @@ #include <asm/errno.h> #include <unistd.h> #include <time.h> +#include <sys/time.h> #include "frandom.h" @@ -125,13 +126,21 @@ lbuf[i] = rand(); } +unsigned int frandom_getseedval() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_usec << 12) ^ tv.tv_sec ^ getpid(); +} + + void* frandom_init_lrand(int seedval) { u8 seedbuf[256]; if (!seedval) - seedval = time(0) - getpid(); - srand(seedval); + seedval = frandom_getseedval(); + srand(seedval); rand(); get_libc_rand_bytes(seedbuf, 256); return frandom_init(seedbuf); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/frandom.h new/dd_rescue/frandom.h --- old/dd_rescue/frandom.h 2013-02-03 14:19:43.000000000 +0100 +++ new/dd_rescue/frandom.h 2013-02-05 10:44:11.000000000 +0100 @@ -13,5 +13,6 @@ void* frandom_init(unsigned char* seedbf); void* frandom_stdup(const void* rstate); void* frandom_stcopy(void* tostate, const void* fromstate); +unsigned int frandom_getseedval(); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dd_rescue/list.h new/dd_rescue/list.h --- old/dd_rescue/list.h 1970-01-01 01:00:00.000000000 +0100 +++ new/dd_rescue/list.h 2013-02-06 11:37:25.000000000 +0100 @@ -0,0 +1,96 @@ +/** list.h + * C version of linked lists + * (ab)uing macros ... + */ + +#ifndef _LIST_H_ +#define _LIST_H + +#include <stdlib.h> + +#define LISTDECL(type) \ +struct _list_##type { \ + struct _list_##type *next; \ + type data; \ +} + + +#define LISTTYPE(type) struct _list_##type +#define LISTNEXT(x) x->next +#define LISTDATA(x) x->data + +#define LISTINSAFTER(l, x, type) do { \ + struct _list_##type *newel = malloc(sizeof(struct _list_##type)); \ + newel->data = x; \ + if (l) { \ + newel->next = l->next; \ + l->next = newel; \ + } else { \ + l = newel; \ + newel->next = 0; \ + } \ + } while(0) + +#define LISTINSBEFORE(lh, x, type) do { \ + struct _list_##type *newel = malloc(sizeof(struct _list_##type)); \ + newel->data = x; \ + newel->next = lh; \ + lh = newel; \ + } while (0) + +#define LISTAPPEND(lh, x, type) do { \ + struct _list_##type *newel = malloc(sizeof(struct _list_##type)); \ + newel->data = x; newel->next = 0; \ + if (!lh) \ + lh = newel; \ + else { \ + struct _list_##type *el = lh; \ + while(el->next) \ + el = el->next; \ + el->next = newel; \ + } \ + } while (0) + +#define LISTDELNEXT(l, type) do { \ + struct _list_##type *_nxt = l->next; \ + if (l->next) { \ + l->next = l->next->next; \ + free(_nxt); \ + } else { \ + free(l); \ + l = 0; \ + } } while(0) + +#define LISTDEL(lh,type) do { \ + struct _list_##type *_nxt = lh->next; \ + free(lh); \ + lh = _nxt; \ + } while (0) + +#define LISTTREEDEL(lh, type) do { \ + while (lh) { \ + LISTDEL(lh, type); \ + } \ + lh = 0; \ + } while (0) + +#define LISTFOREACH(lh, x) \ + for (x = lh; x; x = x->next) + +#ifdef __GNUC__ +#define LISTEL(lh, no, type) ({ \ + int _i = 0; \ + struct _list_##type *el; \ + for (el = lh; el; ++_i, el = el->next) \ + if (_i == no) break; \ + el; }) +#define LISTSIZE(lh,type) ({ \ + struct _list_##type *el; \ + int _i = 0; \ + for (el = lh; el; ++_i, el = el->next); \ + _i; }) +#else +/* TODO: create static inline functions ... */ +#endif + +#endif -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
