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 - kurt@garloff.de
+
+- 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) garloff@suse.de, 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/m07...
+* 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 , 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
#include
#include
+#include
#include
#include
#include "frandom.h"
+#include "list.h"
#ifdef HAVE_GETOPT_H
#include
@@ -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
#include
#include
+#include
#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
+
+#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: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org