Hi,
15 years ago I've accidently deleted an XFS drive full of recordings.
And even in those (*.vdr) days foremost wasn't the most successful tool
in order to recover recordings.
What I've done:
1. I've made an (dd-) image
2. I used a modified version of genindex to scan the image
The result where thousands of small video files (the number depends on
the degree of fragmentation of your drive).
This was working fairly well, but most of the recordings were not worth
recovering because I had to solve the puzzle of concatinating dozens of
files (out of the thousands) in the correct order.
But if it helps you here is my patch:
diff -ur genindex-0.1.3.orig/file.c genindex-0.1.3/file.c
--- genindex-0.1.3.orig/file.c 2006-06-01 22:09:10.0 +0200
+++ genindex-0.1.3/file.c 2008-11-19 14:59:52.0 +0100
@@ -181,16 +181,20 @@
cFileName::~cFileName()
{
+ printf(">close %s<\n", filename);
close(fd);
}
-int cFileName::Open(void)
+int cFileName::Open(off64_t xxx = 0)
{
close(fd); fd=-1;
cString filename;
if(input) filename=input;
else filename=cString::sprintf(FILENAME,fileno);
fd=open64(filename,O_RDONLY);
+ if (xxx > 0) {
+ lseek64(fd,xxx,SEEK_SET);
+ }
if(fd>=0) {
struct stat64 st;
if(fstat64(fd,&st)==0) {
diff -ur genindex-0.1.3.orig/file.h genindex-0.1.3/file.h
--- genindex-0.1.3.orig/file.h 2006-06-01 17:12:25.0 +0200
+++ genindex-0.1.3/file.h 2008-11-19 15:01:15.0 +0100
@@ -54,12 +54,13 @@
public:
cFileName(const char *Input, bool LargeOK);
~cFileName();
- int Open(void);
+ int Open(off64_t);
int NextFile(void);
int OpenWrite(void);
int NextWriteFile(void);
int Skip(int nr, int off);
int FileNumber(void) { return fileno; }
+ void SetFileNumber(int i) {fileno = i;}
long long FileSize(void) { return size; }
};
Only in genindex-0.1.3: file.o
Only in genindex-0.1.3: genindex
diff -ur genindex-0.1.3.orig/genindex.c genindex-0.1.3/genindex.c
--- genindex-0.1.3.orig/genindex.c 2006-06-02 15:44:31.0 +0200
+++ genindex-0.1.3/genindex.c 2008-11-19 15:00:58.0 +0100
@@ -41,6 +41,8 @@
char *destdir=0;
char *input=0;
int splitsize=2000;
+long long startat=0;
+int firstnum=1;
bool rewrite=false;
bool quiet=false;
@@ -61,6 +63,7 @@
//
unsigned int sSize;
int splitOffset;
+ long long startOffset;
bool pstart;
//
unsigned char buff[KILOBYTE(256)];
@@ -77,7 +80,7 @@
public:
cGenIndex(void);
~cGenIndex();
- void Work(void);
+ void Work(off64_t);
void Skip(int type);
};
@@ -86,6 +89,7 @@
index=new cIndex(destdir);
fileName=new cFileName(input,input && rewrite);
writeName=new cFileName(destdir,true);
+ writeName->SetFileNumber(firstnum);
if(rewrite) {
SetDefaultRule(prSkip);
@@ -124,7 +128,7 @@
return replayFile>=0;
}
-void cGenIndex::Work(void)
+void cGenIndex::Work(off64_t startat = 0)
{
eof=error=pstart=false;
memset(fileSize,0,sizeof(fileSize));
@@ -137,14 +141,16 @@
}
}
- replayFile=fileName->Open();
+ readOffset=startat;
+
+ replayFile=fileName->Open(readOffset);
readNo=fileName->FileNumber();
fileSize[readNo]=fileName->FileSize();
- readOffset=0;
fileNo=rewrite ? 1 : readNo;
fileOffset=0;
splitOffset=splitsize*MEGABYTE(1);
+ startOffset=startat*MEGABYTE(1);
sSize=0;
if(replayFile>=0) {
@@ -236,7 +242,7 @@
}
if(rewrite) {
- if(scan && fileOffset>=splitOffset && (pstart || sSize)) {
+ if(scan && (fileOffset>=splitOffset || nextFile) && (pstart ||
sSize)) {
if(sSize+len>sizeof(store)) {
printf("Oops! Packet buffer overflow\n");
error=true;
@@ -246,7 +252,7 @@
sSize+=len;
}
else {
- if(fileOffset>=splitOffset && sSize && ftype==I_FRAME) {
+ if((fileOffset>=splitOffset || nextFile) && sSize &&
ftype==I_FRAME) {
writeFile=writeName->NextWriteFile();
if(writeFile<0) {
printf("Failed to open output file(s)\n");
@@ -254,6 +260,7 @@
return -1;
}
packetNo=fileNo=writeName->FileNumber();
+ nextFile=false;
packetOffset=0;
fileOffset=sSize;
}
@@ -343,6 +350,8 @@
{
static struct option long_options[] = {
{ "rewrite", no_argument, NULL, 'r' },
+ { "startat", required_argument, NULL, 'a' },
+ { "firstnum", required_argument, NULL, 'f' },
{ "quiet", no_argument, NULL, 'q' },
{ "dest", required_argument, NULL, 'd' },
{ "split", required_argument, NULL, 's' },
@@ -353,8 +362,14 @@
int s=0, str[MAX_STR];
int c;
- while((c=getopt_long(argc,argv,"rqd:s:i:",long_options,NULL))!=-1) {
+ while((c=getopt_long(argc,argv,"rqd:s:i:a:f:",long_options,NULL))!=-1) {
switch (c) {
+ case 'a':
+ startat=atoll(optarg);
+ break;
+ case 'f':
+ firstnum=atoi(optarg);
+ break;
case 'r':
rewrite=true;
break;
@@