"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "debug.c" between
dvdisaster-0.79.3.tar.gz and dvdisaster-0.79.5.tar.gz

About: dvdisaster provides a margin of safety against data loss on CD, DVD and BD media caused by aging or scratches. Development version.

debug.c  (dvdisaster-0.79.3):debug.c  (dvdisaster-0.79.5)
/* dvdisaster: Additional error correction for optical media. /* dvdisaster: Additional error correction for optical media.
* Copyright (C) 2004-2010 Carsten Gnoerlich. * Copyright (C) 2004-2015 Carsten Gnoerlich.
* Project home page: http://www.dvdisaster.com
* Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org
* *
* This program is free software; you can redistribute it and/or modify * Email: carsten@dvdisaster.org -or- cgnoerlich@fsfe.org
* Project homepage: http://www.dvdisaster.org
*
* This file is part of dvdisaster.
*
* dvdisaster is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * dvdisaster is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with dvdisaster. If not, see <http://www.gnu.org/licenses/>.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
* or direct your browser at http://www.gnu.org.
*/ */
#include "dvdisaster.h" #include "dvdisaster.h"
#include "rs02-includes.h" #include "rs02-includes.h"
#include "rs03-includes.h" #include "rs03-includes.h"
#include "udf.h" #include "udf.h"
#include <time.h> #include <time.h>
/*** /***
*** Debugging functions. *** Debugging functions.
***/ ***/
/* /*
* Debugging function to seed the image with random correctable errors * Debugging function to seed the image with random correctable errors
*/ */
/* RS01-style files */ /* RS01-style files */
static void random_error1(char *prefix, char *arg) static void random_error1(Image *image, char *arg)
{ ImageInfo *ii; { EccHeader *eh;
gint64 block_idx[255]; gint64 block_idx[255];
gint64 s,si; gint64 s,si;
int block_sel[255]; int block_sel[255];
int i,percent,last_percent = 0; int i,percent,last_percent = 0;
int n_data,n_eras,n_errors; int n_data,n_errors;
double eras_scale, blk_scale; double eras_scale, blk_scale;
char *cpos = NULL;
SRandom(Closure->randomSeed); SRandom(Closure->randomSeed);
eh = image->eccFileHeader;
cpos = strchr(arg,','); n_errors = atoi(arg);
if(!cpos) Stop(_("2nd argument is missing"));
*cpos = 0;
n_eras = atoi(arg);
n_errors = atoi(cpos+1);
if(n_eras < 8 || n_eras > 100 || n_errors < 1|| n_errors > n_eras) if(n_errors < 1|| n_errors > eh->eccBytes)
Stop(_("Number of roots must be 8..100;\n" Stop(_("Number of erasures must be > 0 and <= %d\n"), eh->eccBytes);
"the number of erasures must be > 0 and less than the number of roots
.\n"));
n_data = 255-n_eras; n_data = 255-eh->eccBytes;
eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0); eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0);
blk_scale = (double)n_data/((double)MY_RAND_MAX+1.0); blk_scale = (double)n_data/((double)MY_RAND_MAX+1.0);
/*** Open the image file */
ii = OpenImageFile(NULL, WRITEABLE_IMAGE);
/*** Setup block pointers */ /*** Setup block pointers */
s = (ii->sectors+n_data-1)/n_data; s = (image->sectorSize+n_data-1)/n_data;
for(si=0, i=0; i<n_data; si+=s, i++) for(si=0, i=0; i<n_data; si+=s, i++)
block_idx[i] = si; block_idx[i] = si;
PrintLog(_("\nGenerating random correctable erasures (for %d roots, max erasu PrintLog(_("\nGenerating random correctable erasures (%s; for %d roots, max e
res = %d).\n"),n_eras, n_errors); rasures = %d).\n"),
"RS01", eh->eccBytes, n_errors);
/*** Randomly delete the blocks */ /*** Randomly delete the blocks */
for(si=0; si<s; si++) for(si=0; si<s; si++)
{ int n_erasures = (int)(eras_scale*(double)Random()); { int n_erasures = (int)(eras_scale*(double)Random());
/* Reset the block selector */ /* Reset the block selector */
for(i=0; i<n_data; i++) for(i=0; i<n_data; i++)
block_sel[i] = 0; block_sel[i] = 0;
skipping to change at line 106 skipping to change at line 98
{ idx = (int)(blk_scale*(double)Random()); { idx = (int)(blk_scale*(double)Random());
} while(block_sel[idx]); } while(block_sel[idx]);
block_sel[idx] = 1; block_sel[idx] = 1;
} }
/* Delete the randomly picked blocks */ /* Delete the randomly picked blocks */
for(i=0; i<n_data; i++) for(i=0; i<n_data; i++)
{ unsigned char missing[2048]; { unsigned char missing[2048];
int write_size = 2048;
if(block_sel[i] && block_idx[i]<ii->sectors) if(block_sel[i] && block_idx[i]<image->sectorSize)
{ if(!LargeSeek(ii->file, (gint64)(2048*block_idx[i]))) { if(!LargeSeek(image->file, (gint64)(2048*block_idx[i])))
Stop(_("Failed seeking to sector %lld in image: %s"),block_idx[i], strerror(errno)); Stop(_("Failed seeking to sector %lld in image: %s"),block_idx[i], strerror(errno));
CreateMissingSector(missing, block_idx[i], ii->mediumFP, FINGERPRINT_ CreateMissingSector(missing, block_idx[i], image->imageFP, FINGERPRIN
SECTOR, NULL); T_SECTOR, NULL);
if(block_idx[i] == image->sectorSize - 1 && image->inLast < 2048)
write_size = image->inLast;
if(LargeWrite(ii->file, missing, 2048) != 2048) if(LargeWrite(image->file, missing, write_size) != write_size)
Stop(_("Failed writing to sector %lld in image: %s"),block_idx[i], strerror(errno)); Stop(_("Failed writing to sector %lld in image: %s"),block_idx[i], strerror(errno));
} }
block_idx[i]++; block_idx[i]++;
} }
percent = (100*si)/s; percent = (100*si)/s;
if(last_percent != percent) if(last_percent != percent)
{ PrintProgress(_("Progress: %3d%%"),percent); { PrintProgress(_("Progress: %3d%%"),percent);
last_percent = percent; last_percent = percent;
} }
} }
PrintProgress(_("Progress: 100%%\n" PrintProgress(_("Progress: 100%%\n"
"Recover the image using the --fix option before doing another --random-e rrors run.\n" "Recover the image using the --fix option before doing another --random-e rrors run.\n"
"Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"), "Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"),
n_errors); n_errors);
FreeImageInfo(ii);
} }
/* RS02 ecc images */ /* RS02 ecc images */
static void random_error2(EccHeader *eh, char *prefix, char *arg) static void random_error2(Image *image, char *arg)
{ RS02Layout *lay; { EccHeader *eh = image->eccHeader;
ImageInfo *ii; RS02Layout *lay;
gint64 si; gint64 si;
guint64 hpos; guint64 hpos;
guint64 end; guint64 end;
guint64 header[42]; guint64 header[42];
int block_sel[255]; int block_sel[255];
int i,percent,last_percent = 0; int i,percent,last_percent = 0;
int hidx,n_errors,erase_max = 0; int hidx,n_errors,erase_max = 0;
double eras_scale, blk_scale, hdr_scale; double eras_scale, blk_scale, hdr_scale;
SRandom(Closure->randomSeed); SRandom(Closure->randomSeed);
lay = CalcRS02Layout(uchar_to_gint64(eh->sectors), eh->eccBytes); lay = RS02LayoutFromImage(image);
n_errors = atoi(arg); n_errors = atoi(arg);
if(n_errors < 0) if(n_errors < 0)
{ erase_max = 1; { erase_max = 1;
n_errors = -n_errors; n_errors = -n_errors;
} }
if(n_errors <= 0 || n_errors > eh->eccBytes) if(n_errors <= 0 || n_errors > eh->eccBytes)
Stop(_("Number of erasures must be > 0 and <= %d\n"), eh->eccBytes); Stop(_("Number of erasures must be > 0 and <= %d\n"), eh->eccBytes);
eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0); eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0);
blk_scale = (double)255.0/((double)MY_RAND_MAX+1.0); blk_scale = (double)255.0/((double)MY_RAND_MAX+1.0);
/*** Open the image file */ PrintLog(_("\nGenerating random correctable erasures (%s; for %d roots, max e
rasures = %d).\n"),
ii = OpenImageFile(NULL, WRITEABLE_IMAGE); "RS02", eh->eccBytes, n_errors);
PrintLog(_("\nGenerating random correctable erasures (for %d roots, max erasu
res = %d).\n"), eh->eccBytes, n_errors);
/*** Randomly delete some ecc headers */ /*** Randomly delete some ecc headers */
header[0] = lay->firstEccHeader; header[0] = lay->firstEccHeader;
hidx = 1; hidx = 1;
hpos = (lay->protectedSectors + lay->headerModulo - 1) / lay->headerModulo; hpos = (lay->protectedSectors + lay->headerModulo - 1) / lay->headerModulo;
hpos *= lay->headerModulo; hpos *= lay->headerModulo;
end = lay->eccSectors+lay->dataSectors-2; end = lay->eccSectors+lay->dataSectors-2;
skipping to change at line 198 skipping to change at line 189
Currently this must be one of the repeated headers */ Currently this must be one of the repeated headers */
hdr_scale = (double)(hidx-1)/((double)MY_RAND_MAX+1.0); hdr_scale = (double)(hidx-1)/((double)MY_RAND_MAX+1.0);
header[(int)(hdr_scale*(double)Random())+1] = 0; header[(int)(hdr_scale*(double)Random())+1] = 0;
for(i=0; i<hidx; i++) for(i=0; i<hidx; i++)
{ gint64 s = header[i]; { gint64 s = header[i];
if(s>0) if(s>0)
{ unsigned char missing[2048]; { unsigned char missing[2048];
if(!LargeSeek(ii->file, (gint64)(2048*s))) if(!LargeSeek(image->file, (gint64)(2048*s)))
Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror(err no)); Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror(err no));
CreateMissingSector(missing, s, ii->mediumFP, FINGERPRINT_SECTOR, NULL); CreateMissingSector(missing, s, image->imageFP, image->fpSector, NULL);
if(LargeWrite(ii->file, missing, 2048) != 2048) if(LargeWrite(image->file, missing, 2048) != 2048)
Stop(_("Failed writing to sector %lld in image: %s"), s, strerror(err no)); Stop(_("Failed writing to sector %lld in image: %s"), s, strerror(err no));
} }
} }
/*** Randomly delete the blocks */ /*** Randomly delete the blocks */
for(si=0; si<lay->sectorsPerLayer; si++) for(si=0; si<lay->sectorsPerLayer; si++)
{ int n_erasures = (int)(eras_scale*(double)Random()); { int n_erasures = (int)(eras_scale*(double)Random());
if(erase_max) if(erase_max)
n_erasures = n_errors; n_erasures = n_errors;
skipping to change at line 246 skipping to change at line 237
{ unsigned char missing[2048]; { unsigned char missing[2048];
gint64 s; gint64 s;
if(i<eh->dataBytes) if(i<eh->dataBytes)
{ s = si + i * lay->sectorsPerLayer; { s = si + i * lay->sectorsPerLayer;
if(s >= lay->protectedSectors) /* exclude the padding area */ if(s >= lay->protectedSectors) /* exclude the padding area */
continue; /* respective sectors do not ex ist */ continue; /* respective sectors do not ex ist */
} }
else s = RS02EccSectorIndex(lay, i-eh->dataBytes, si); else s = RS02EccSectorIndex(lay, i-eh->dataBytes, si);
if(!LargeSeek(ii->file, (gint64)(2048*s))) if(!LargeSeek(image->file, (gint64)(2048*s)))
Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror( errno)); Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror( errno));
CreateMissingSector(missing, s, ii->mediumFP, FINGERPRINT_SECTOR, NUL CreateMissingSector(missing, s, image->imageFP, image->fpSector, NULL
L); );
if(LargeWrite(image->file, missing, 2048) != 2048)
if(LargeWrite(ii->file, missing, 2048) != 2048)
Stop(_("Failed writing to sector %lld in image: %s"), s, strerror( errno)); Stop(_("Failed writing to sector %lld in image: %s"), s, strerror( errno));
} }
} }
percent = (100*si)/lay->sectorsPerLayer; percent = (100*si)/lay->sectorsPerLayer;
if(last_percent != percent) if(last_percent != percent)
{ PrintProgress(_("Progress: %3d%%"),percent); { PrintProgress(_("Progress: %3d%%"),percent);
last_percent = percent; last_percent = percent;
} }
} }
PrintProgress(_("Progress: 100%%\n" PrintProgress(_("Progress: 100%%\n"
"Recover the image using the --fix option before doing another --random-e rrors run.\n" "Recover the image using the --fix option before doing another --random-e rrors run.\n"
"Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"), "Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"),
n_errors); n_errors);
FreeImageInfo(ii);
g_free(lay); g_free(lay);
} }
/* RS03 ecc images */ /* RS03 ecc images */
static void random_error3(EccHeader *eh, char *prefix, char *arg) static void random_error3(Image *image, char *arg)
{ RS03Layout *lay; { EccHeader *eh;
ImageInfo *ii; RS03Layout *lay;
LargeFile *eccfile = NULL;
gint64 si; gint64 si;
int block_sel[255]; int block_sel[255];
int i,percent,last_percent = 0; int i,percent,last_percent = 0;
int n_errors,erase_max = 0; int n_errors,erase_max = 0;
double eras_scale, blk_scale; double eras_scale, blk_scale;
SRandom(Closure->randomSeed); SRandom(Closure->randomSeed);
/*** Calculate the layout */ /*** Calculate the layout */
if(eh->methodFlags[0] & MFLAG_ECC_FILE) if(image->eccFileState == ECCFILE_PRESENT)
lay = CalcRS03Layout(uchar_to_gint64(eh->sectors), eh, ECC_FILE); { eh = image->eccFileHeader;
else lay = CalcRS03Layout(uchar_to_gint64(eh->sectors), eh, ECC_IMAGE); lay = CalcRS03Layout(image, ECC_FILE);
}
else
{ eh = image->eccHeader;
lay = CalcRS03Layout(image, ECC_IMAGE);
}
n_errors = atoi(arg); n_errors = atoi(arg);
if(n_errors < 0) if(n_errors < 0)
{ erase_max = 1; { erase_max = 1;
n_errors = -n_errors; n_errors = -n_errors;
} }
if(n_errors <= 0 || n_errors > eh->eccBytes) if(n_errors <= 0 || n_errors > eh->eccBytes)
Stop(_("Number of erasures must be > 0 and <= %d\n"), eh->eccBytes); Stop(_("Number of erasures must be > 0 and <= %d\n"), eh->eccBytes);
eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0); eras_scale = (n_errors+1)/((double)MY_RAND_MAX+1.0);
blk_scale = (double)255.0/((double)MY_RAND_MAX+1.0); blk_scale = (double)255.0/((double)MY_RAND_MAX+1.0);
/*** Open the image file */
ii = OpenImageFile(NULL, WRITEABLE_IMAGE);
if(lay->target == ECC_FILE)
{ eccfile = LargeOpen(Closure->eccName, O_RDWR, IMG_PERMS);
if(!eccfile)
Stop(_("Could not open %s: %s"),Closure->eccName, strerror(errno));
}
if(lay->target == ECC_FILE) if(lay->target == ECC_FILE)
PrintLog(_("\nRS03 error correction file with %d roots.\n"), eh->eccByt es); PrintLog(_("\nRS03 error correction file with %d roots.\n"), eh->eccByt es);
else PrintLog(_("\nRS03 augmented image with %d roots.\n"), eh->eccBytes); else PrintLog(_("\nRS03 augmented image with %d roots.\n"), eh->eccBytes);
PrintLog(_("Generating at most %d random correctable erasures.\n"), n_errors) ; PrintLog(_("Generating at most %d random correctable erasures.\n"), n_errors) ;
/*** Randomly delete the blocks */ /*** Randomly delete the blocks */
for(si=0; si<lay->sectorsPerLayer; si++) for(si=0; si<lay->sectorsPerLayer; si++)
{ int n_erasures = (int)(eras_scale*(double)Random()); { int n_erasures = (int)(eras_scale*(double)Random());
skipping to change at line 348 skipping to change at line 330
{ idx = (int)(blk_scale*(double)Random()); { idx = (int)(blk_scale*(double)Random());
} while(block_sel[idx]); } while(block_sel[idx]);
block_sel[idx] = 1; block_sel[idx] = 1;
} }
/* Delete the randomly picked blocks */ /* Delete the randomly picked blocks */
for(i=0; i<255; i++) for(i=0; i<255; i++)
{ if(block_sel[i]) { if(block_sel[i])
{ LargeFile *file = ii->file; { LargeFile *file;
unsigned char missing[2048]; unsigned char missing[2048];
gint64 s; gint64 s,file_s;
s = RS03SectorIndex(lay, i, si); s = RS03SectorIndex(lay, i, si);
if(s == 16) /* FIXME: not implemented */ if(s == 16) /* FIXME: not implemented */
continue; continue;
if(s == lay->eccHeaderPos || s == lay->eccHeaderPos+1) if(s == lay->eccHeaderPos || s == lay->eccHeaderPos+1)
continue; /* FIXME: not implemented */ continue; /* FIXME: not implemented */
/* Do not write out the virtual padding sectors /* Do not write out the virtual padding sectors
in ecc file case */ in ecc file case */
if(lay->target == ECC_FILE if(lay->target == ECC_FILE
&& i<=lay->ndata-1 && i<=lay->ndata-1
&& s>=lay->dataSectors) && s>=lay->dataSectors)
continue; continue;
if(lay->target == ECC_FILE && i>=lay->ndata-1) if(lay->target == ECC_FILE && i>=lay->ndata-1)
file = eccfile; { file = image->eccFile;
if(i == lay->ndata-1)
file_s = lay->firstCrcPos + si;
else file_s = lay->firstEccPos + (i-lay->ndata)*lay->sectorsPerL
ayer + si;
}
else
{ file = image->file;
file_s = s;
}
if(!LargeSeek(file, (gint64)(2048*s))) if(!LargeSeek(file, (gint64)(2048*file_s))) // FIXME: wrong for ecc files
Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror( errno)); Stop(_("Failed seeking to sector %lld in image: %s"), s, strerror( errno));
CreateMissingSector(missing, s, ii->mediumFP, FINGERPRINT_SECTOR, NUL L); CreateMissingSector(missing, s, image->imageFP, image->fpSector, NULL );
if(LargeWrite(file, missing, 2048) != 2048) if(LargeWrite(file, missing, 2048) != 2048)
Stop(_("Failed writing to sector %lld in image: %s"), s, strerror( errno)); Stop(_("Failed writing to sector %lld in image: %s"), s, strerror( errno));
} }
} }
percent = (100*si)/lay->sectorsPerLayer; percent = (100*si)/lay->sectorsPerLayer;
if(last_percent != percent) if(last_percent != percent)
{ PrintProgress(_("Progress: %3d%%"),percent); { PrintProgress(_("Progress: %3d%%"),percent);
last_percent = percent; last_percent = percent;
} }
} }
PrintProgress(_("Progress: 100%%\n" PrintProgress(_("Progress: 100%%\n"
"Recover the image using the --fix option before doing another --random-e rrors run.\n" "Recover the image using the --fix option before doing another --random-e rrors run.\n"
"Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"), "Otherwise you'll accumulate >= %d erasures/ECC block and the image will be lost.\n"),
n_errors); n_errors);
if(eccfile)
LargeClose(eccfile);
FreeImageInfo(ii);
g_free(lay); g_free(lay);
} }
void RandomError(char *prefix, char *arg) void RandomError(char *arg)
{ Method *method = EccMethod(TRUE); { Image *image;
Method *method = NULL;
char buf[5]; char buf[5];
image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS);
image = OpenEccFileForImage(image, Closure->eccName, O_RDWR, IMG_PERMS);
ReportImageEccInconsistencies(image);
/* Determine method. Ecc files win over augmented ecc. */
if(image && image->eccFileMethod) method = image->eccFileMethod;
else if(image && image->eccMethod) method = image->eccMethod;
else Stop("Internal error: No ecc method identified.");
if(!strncmp(method->name, "RS01", 4)) if(!strncmp(method->name, "RS01", 4))
{ random_error1(prefix, arg); { random_error1(image, arg);
CloseImage(image);
return; return;
} }
if(!strncmp(method->name, "RS02", 4)) if(!strncmp(method->name, "RS02", 4))
{ random_error2(method->lastEh, prefix, arg); { random_error2(image, arg);
CloseImage(image);
return; return;
} }
/* FIXME: currently only handles augmented images */
if(!strncmp(method->name, "RS03", 4)) if(!strncmp(method->name, "RS03", 4))
{ random_error3(method->lastEh, prefix, arg); { random_error3(image, arg);
CloseImage(image);
return; return;
} }
CloseImage(image);
strncpy(buf, method->name, 4); buf[4] = 0; strncpy(buf, method->name, 4); buf[4] = 0;
Stop("Don't know how to handle codec %s\n", buf); Stop("Don't know how to handle codec %s\n", buf);
} }
/* /*
* Debugging function to simulate images with single * Debugging function to simulate images with single
* byte errors (except for faulty cabling and/or controllers, * byte errors (except for faulty cabling and/or controllers,
* this should never happen) * this should never happen)
*/ */
void Byteset(char *arg) void Byteset(char *arg)
{ ImageInfo *ii; { Image *image;
gint64 s; gint64 s;
int i,byte; int i,byte;
char *cpos = NULL; char *cpos = NULL;
unsigned char buf[1];
/*** Open the image file */ /*** Open the image file */
ii = OpenImageFile(NULL, WRITEABLE_IMAGE); image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
/*** See which byte to set */ /*** See which byte to set */
cpos = strchr(arg,','); cpos = strchr(arg,',');
if(!cpos) Stop(_("2nd argument is missing")); if(!cpos) Stop(_("2nd argument is missing"));
*cpos = 0; *cpos = 0;
s = atoi(arg); s = atoi(arg);
arg = cpos+1; arg = cpos+1;
cpos = strchr(arg,','); cpos = strchr(arg,',');
if(!cpos) Stop(_("3rd argument is missing")); if(!cpos) Stop(_("3rd argument is missing"));
*cpos = 0; *cpos = 0;
i = atoi(arg); i = atoi(arg);
byte = atoi(cpos+1); byte = atoi(cpos+1);
if(s<0 || s>ii->sectors-1) if(s<0 || s>=image->sectorSize)
Stop(_("Sector must be in range [0..%lld]\n"),ii->sectors-1); Stop(_("Sector must be in range [0..%lld]\n"),image->sectorSize-1);
if(i<0 || i>=2048) if(i<0 || i>=2048)
Stop(_("Byte position must be in range [0..2047]")); Stop(_("Byte position must be in range [0..2047]"));
if(byte<0 || byte>=256) if(byte<0 || byte>=256)
Stop(_("Byte value must be in range [0..255]")); Stop(_("Byte value must be in range [0..255]"));
PrintLog(_("Setting byte %d in sector %lld to value %d.\n"), i, s, byte); PrintLog(_("Setting byte %d in sector %lld to value %d.\n"), i, s, byte);
/*** Set the byte */ /*** Set the byte */
s = 2048*s + i; s = 2048*s + i;
if(!LargeSeek(ii->file, (gint64)s)) if(!LargeSeek(image->file, (gint64)s))
Stop(_("Failed seeking to start of image: %s\n"),strerror(errno)); Stop(_("Failed seeking to start of image: %s\n"),strerror(errno));
if(LargeWrite(ii->file, &byte, 1) != 1) buf[0] = byte;
if(LargeWrite(image->file, buf, 1) != 1)
Stop(_("Could not write the new byte value")); Stop(_("Could not write the new byte value"));
FreeImageInfo(ii); CloseImage(image);
} }
/* /*
* Debugging function to simulate medium with unreadable sectors * Debugging function to simulate medium with unreadable sectors
*/ */
void Erase(char *arg) void Erase(char *arg)
{ ImageInfo *ii; { Image *image;
gint64 start,end,s; gint64 start,end,s;
char *dashpos = NULL; char *dashpos = NULL;
char *colonpos = NULL;
char *simulation_hint = NULL;
/*** Open the image file */ /*** Open the image file */
ii = OpenImageFile(NULL, WRITEABLE_IMAGE); image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
ExamineUDF(image); /* get the volume label */
/** See if there is a special debugging option following
the sector range. This is intentionally an undocumented feature. */
colonpos = strchr(arg,':');
if(colonpos)
{ *colonpos = 0;
simulation_hint=colonpos+1;
}
/*** See which sectors to erase */ /*** See which sectors to erase */
dashpos = strchr(arg,'-'); dashpos = strchr(arg,'-');
if(dashpos) if(dashpos)
{ *dashpos = 0; { *dashpos = 0;
start = atoi(arg); start = atoi(arg);
end = atoi(dashpos+1); end = atoi(dashpos+1);
} }
else start = end = atoi(arg); else start = end = atoi(arg);
if(start>end || start < 0 || end >= ii->sectors) if(start>end || start < 0 || end >= image->sectorSize)
Stop(_("Sectors must be in range [0..%lld].\n"),ii->sectors-1); Stop(_("Sectors must be in range [0..%lld].\n"),image->sectorSize-1);
PrintLog(_("Erasing sectors [%lld,%lld]\n"),start,end); PrintLog(_("Erasing sectors [%lld,%lld]\n"),start,end);
/*** Erase them. */ /*** Erase them. */
if(!LargeSeek(ii->file, (gint64)(2048*start))) if(!LargeSeek(image->file, (gint64)(2048*start)))
Stop(_("Failed seeking to start of image: %s\n"),strerror(errno)); Stop(_("Failed seeking to start of image: %s\n"),strerror(errno));
for(s=start; s<=end; s++) for(s=start; s<=end; s++)
{ unsigned char missing[2048]; { unsigned char missing[2048];
int m = (end == ii->sectors-1) ? ii->inLast : 2048; int m = (end == image->sectorSize-1) ? image->inLast : 2048;
int n; int n;
CreateMissingSector(missing, s, ii->mediumFP, FINGERPRINT_SECTOR, NULL); CreateDebuggingSector(missing, s, image->imageFP, FINGERPRINT_SECTOR,
image->isoInfo ? image->isoInfo->volumeLabel : NULL,
simulation_hint);
n = LargeWrite(ii->file, missing, m); n = LargeWrite(image->file, missing, m);
if(n != m) if(n != m)
Stop(_("Failed writing to sector %lld in image: %s"),s,strerror(errno)); Stop(_("Failed writing to sector %lld in image: %s"),s,strerror(errno));
} }
/*** Clean up */ /*** Clean up */
FreeImageInfo(ii); CloseImage(image);
} }
/* /*
* Debugging function for truncating images * Debugging function for truncating images
*/ */
void TruncateImage(char *arg) void TruncateImageFile(char *arg)
{ ImageInfo *ii; { Image *image;
gint64 end; gint64 end;
/*** Open the image file */ /*** Open the image file */
ii = OpenImageFile(NULL, WRITEABLE_IMAGE); image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
/*** Determine last sector */ /*** Determine last sector */
end = atoi(arg); end = atoi(arg);
if(end >= ii->sectors) if(end >= image->sectorSize)
Stop(_("New length must be in range [0..%lld].\n"),ii->sectors-1); Stop(_("New length must be in range [0..%lld].\n"),image->sectorSize-1);
PrintLog(_("Truncating image to %lld sectors.\n"),end); PrintLog(_("Truncating image to %lld sectors.\n"),end);
/*** Truncate it. */ /*** Truncate it. */
if(!LargeTruncate(ii->file, (gint64)(2048*end))) if(!LargeTruncate(image->file, (gint64)(2048*end)))
Stop(_("Could not truncate %s: %s\n"),Closure->imageName,strerror(errno)); Stop(_("Could not truncate %s: %s\n"),Closure->imageName,strerror(errno));
/*** Clean up */ /*** Clean up */
FreeImageInfo(ii); CloseImage(image);
} }
/* /*
* Debugging function to create an ISO image filled with random numbers * Debugging function to create an ISO image filled with random numbers
*/ */
void RandomImage(char *image_name, char *n_sectors, int mark) void RandomImage(char *image_name, char *n_sectors, int mark)
{ LargeFile *image; { LargeFile *image;
IsoHeader *ih; IsoHeader *ih;
gint64 sectors,s = 0; gint64 sectors;
gint64 s = 25; /* number of ISO headers */
int percent, last_percent = 0; int percent, last_percent = 0;
guint32 invert; guint32 size,invert;
sectors = atoi(n_sectors); sectors = atoi(n_sectors);
if(sectors < 64) sectors = 64; if(sectors < 64) sectors = 64;
/*** Open the image file */ /*** Open the image file */
LargeUnlink(image_name); LargeUnlink(image_name);
if(!(image = LargeOpen(image_name, O_RDWR | O_CREAT, IMG_PERMS))) if(!(image = LargeOpen(image_name, O_RDWR | O_CREAT, IMG_PERMS)))
Stop(_("Can't open %s:\n%s"),image_name,strerror(errno)); Stop(_("Can't open %s:\n%s"),image_name,strerror(errno));
skipping to change at line 606 skipping to change at line 630
} }
else else
{ SRandom(-Closure->randomSeed); { SRandom(-Closure->randomSeed);
invert = 0xffffffff; invert = 0xffffffff;
} }
/*** Create and write the ISO file system. /*** Create and write the ISO file system.
Otherwise some writing software will not recognize the image. */ Otherwise some writing software will not recognize the image. */
ih = InitIsoHeader(); ih = InitIsoHeader();
for(s=25; s<sectors; s+=524288) size = sectors-s;
{ int size = 524288; if(size>=2048*1024)
char name[40]; size=2048*1024-1;
AddFile(ih, "random.data", 2048*size);
if(s+size >= sectors)
size = sectors-s;
sprintf(name, "random%02d.data", (int)(s/524288)+1);
AddFile(ih, name, 2048*size);
}
WriteIsoHeader(ih, image); WriteIsoHeader(ih, image);
FreeIsoHeader(ih); FreeIsoHeader(ih);
s = 25; /* number of ISO headers */
/*** Create it */ /*** Create it */
while(s<sectors) while(s<sectors)
{ guint32 buf[512]; { guint32 buf[512];
int i=511; int i=511;
int n; int n;
#ifdef HAVE_LITTLE_ENDIAN #ifdef HAVE_LITTLE_ENDIAN
do buf[i--] = (Random32() ^ invert); while(i>=0); do buf[i--] = (Random32() ^ invert); while(i>=0);
#else #else
skipping to change at line 665 skipping to change at line 681
if(!LargeClose(image)) if(!LargeClose(image))
Stop(_("Error closing image file:\n%s"), strerror(errno)); Stop(_("Error closing image file:\n%s"), strerror(errno));
} }
/* /*
* Replaces the "unreadable sector" marker with zeros. * Replaces the "unreadable sector" marker with zeros.
*/ */
void ZeroUnreadable(void) void ZeroUnreadable(void)
{ ImageInfo *ii; { Image *image;
unsigned char buf[2048],zeros[2048]; unsigned char buf[2048],zeros[2048];
gint64 s,cnt=0; gint64 s,cnt=0;
int percent, last_percent = 0; int percent, last_percent = 0;
ii = OpenImageFile(NULL, WRITEABLE_IMAGE); image = OpenImageFromFile(Closure->imageName, O_RDWR, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
PrintLog(_("Replacing the \"unreadable sector\" markers with zeros.\n")); PrintLog(_("Replacing the \"unreadable sector\" markers with zeros.\n"));
memset(zeros, 0, 2048); memset(zeros, 0, 2048);
for(s=0; s<ii->sectors; s++) if(!LargeSeek(image->file, (gint64)0))
{ int n = LargeRead(ii->file, buf, 2048); Stop(_("Failed seeking to start of image: %s\n"),strerror(errno));
for(s=0; s<image->sectorSize; s++)
{ int n = LargeRead(image->file, buf, 2048);
if(n != 2048) if(n != 2048)
Stop(_("Could not read image sector %lld:\n%s\n"),s,strerror(errno)); Stop(_("Could not read image sector %lld:\n%s\n"),s,strerror(errno));
/* Replace the dead sector marker */ /* Replace the dead sector marker */
if(CheckForMissingSector(buf, s, ii->mediumFP, FINGERPRINT_SECTOR) != SECT OR_PRESENT) if(CheckForMissingSector(buf, s, image->imageFP, FINGERPRINT_SECTOR) != SE CTOR_PRESENT)
{ {
if(!LargeSeek(ii->file, (gint64)(2048*s))) if(!LargeSeek(image->file, (gint64)(2048*s)))
Stop(_("Failed seeking to sector %lld in image: %s"),s,strerror(errno)) ; Stop(_("Failed seeking to sector %lld in image: %s"),s,strerror(errno)) ;
n = LargeWrite(ii->file, zeros, 2048); n = LargeWrite(image->file, zeros, 2048);
n=2048;
if(n != 2048) if(n != 2048)
Stop(_("Failed writing to sector %lld in image: %s"),s,strerror(errno)) ; Stop(_("Failed writing to sector %lld in image: %s"),s,strerror(errno)) ;
cnt++; cnt++;
} }
percent = (100*s)/ii->sectors; percent = (100*s)/image->sectorSize;
if(last_percent != percent) if(last_percent != percent)
{ PrintProgress(_("Progress: %3d%%"),percent); { PrintProgress(_("Progress: %3d%%"),percent);
last_percent = percent; last_percent = percent;
} }
} }
PrintProgress(_("%lld \"unreadable sector\" markers replaced.\n"), cnt); PrintProgress(_("%lld \"unreadable sector\" markers replaced.\n"), cnt);
FreeImageInfo(ii); CloseImage(image);
} }
/** /**
** Debugging functions to show contents of a given sector ** Debugging functions to show contents of a given sector
**/ **/
/* /*
* produce a hex dump * produce a hex dump
*/ */
skipping to change at line 759 skipping to change at line 781
{ g_printf("%3d%c ", *buf++, i==len ? ' ' : ','); { g_printf("%3d%c ", *buf++, i==len ? ' ' : ',');
if(i%step == (step-1)) if(i%step == (step-1))
g_printf("\n"); g_printf("\n");
} }
printf("};\n"); printf("};\n");
} }
/* /*
* Show Ecc header from image file
*/
void ShowHeader(char *arg)
{ Image *image;
gint64 sector;
int n;
EccHeader *eh = alloca(4096);
/*** Open the image file */
image = OpenImageFromFile(Closure->imageName, O_RDONLY, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
/*** Determine sector to show */
sector = atoi(arg);
if(sector < 0 || sector >= image->sectorSize)
Stop(_("Sector must be in range [0..%lld]\n"),image->sectorSize-1);
/*** Load it. */
if(!LargeSeek(image->file, (gint64)(2048*sector)))
Stop(_("Failed seeking to sector %lld in image: %s"),sector,strerror(errno)
);
n = LargeRead(image->file, eh, 2048);
if(n != 2048)
Stop(_("Failed reading sector %lld in image: %s"),sector,strerror(errno));
/*** Clean up */
CloseImage(image);
/*** Show it */
PrintEccHeader(eh);
}
/*
* Show sector from image file * Show sector from image file
*/ */
void ShowSector(char *arg) void ShowSector(char *arg)
{ ImageInfo *ii; { Image *image;
gint64 sector; gint64 sector;
int n; int n;
unsigned char buf[2048]; unsigned char buf[2048];
/*** Open the image file */ /*** Open the image file */
ii = OpenImageFile(NULL, READABLE_IMAGE); image = OpenImageFromFile(Closure->imageName, O_RDONLY, IMG_PERMS);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
/*** Determine sector to show */ /*** Determine sector to show */
sector = atoi(arg); sector = atoi(arg);
if(sector < 0 || sector >= ii->sectors) if(sector < 0 || sector >= image->sectorSize)
Stop(_("Sector must be in range [0..%lld]\n"),ii->sectors-1); Stop(_("Sector must be in range [0..%lld]\n"),image->sectorSize-1);
PrintLog(_("Contents of sector %lld:\n\n"),sector); PrintLog(_("Contents of sector %lld:\n\n"),sector);
/*** Show it. */ /*** Show it. */
if(!LargeSeek(ii->file, (gint64)(2048*sector))) if(!LargeSeek(image->file, (gint64)(2048*sector)))
Stop(_("Failed seeking to sector %lld in image: %s"),sector,strerror(errno) ); Stop(_("Failed seeking to sector %lld in image: %s"),sector,strerror(errno) );
n = LargeRead(ii->file, buf, 2048); n = LargeRead(image->file, buf, 2048);
if(n != 2048) if(n != 2048)
Stop(_("Failed reading sector %lld in image: %s"),sector,strerror(errno)); Stop(_("Failed reading sector %lld in image: %s"),sector,strerror(errno));
if(Closure->debugCDump) if(Closure->debugCDump)
CDump(buf, sector, 2048, 16); CDump(buf, sector, 2048, 16);
else else
{ HexDump(buf, 2048, 32); { HexDump(buf, 2048, 32);
g_printf("CRC32 = %04x\n", Crc32(buf, 2048)); g_printf("CRC32 = %04x\n", Crc32(buf, 2048));
} }
/*** Clean up */ /*** Clean up */
FreeImageInfo(ii); CloseImage(image);
} }
/* /*
* Read sector from drive * Read sector from drive
*/ */
void ReadSector(char *arg) void ReadSector(char *arg)
{ AlignedBuffer *ab = CreateAlignedBuffer(2048); { AlignedBuffer *ab = CreateAlignedBuffer(2048);
DeviceHandle *dh; Image *image;
gint64 sector; gint64 sector;
int status; int status;
/*** Open the device */ /*** Open the device */
dh = OpenAndQueryDevice(Closure->device); image = OpenImageFromDevice(Closure->device);
if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
/*** Determine sector to show */ /*** Determine sector to show */
sector = atoi(arg); sector = atoi(arg);
if(sector < 0 || sector >= dh->sectors) if(sector < 0 || sector >= image->dh->sectors)
{ CloseDevice(dh); { CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
Stop(_("Sector must be in range [0..%lld]\n"),dh->sectors-1); Stop(_("Sector must be in range [0..%lld]\n"),image->dh->sectors-1);
} }
PrintLog(_("Contents of sector %lld:\n\n"),sector); PrintLog(_("Contents of sector %lld:\n\n"),sector);
/*** Read it. */ /*** Read it. */
status = ReadSectors(dh, ab->buf, sector, 1); status = ReadSectors(image->dh, ab->buf, sector, 1);
/*** Print results */ /*** Print results */
if(status) if(status)
{ CloseDevice(dh); { CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
Stop(_("Failed reading sector %lld: %s"),sector,strerror(errno)); Stop(_("Failed reading sector %lld: %s"),sector,strerror(errno));
} }
if(Closure->debugCDump) if(Closure->debugCDump)
CDump(ab->buf, sector, 2048, 16); CDump(ab->buf, sector, 2048, 16);
else else
{ HexDump(ab->buf, 2048, 32); { HexDump(ab->buf, 2048, 32);
g_printf("CRC32 = %04x\n", Crc32(ab->buf, 2048)); g_printf("CRC32 = %04x\n", Crc32(ab->buf, 2048));
} }
CloseDevice(dh); CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
} }
/*** /***
*** Read a raw CD sector *** Read a raw CD sector
***/ ***/
void RawSector(char *arg) void RawSector(char *arg)
{ AlignedBuffer *ab = CreateAlignedBuffer(4096); { AlignedBuffer *ab = CreateAlignedBuffer(4096);
Sense *sense; Sense *sense;
unsigned char cdb[MAX_CDB_SIZE]; unsigned char cdb[MAX_CDB_SIZE];
DeviceHandle *dh; Image *image;
gint64 lba; gint64 lba;
int length=0,status; int length=0,status;
int offset=16; int offset=16;
/*** Open the device */ /*** Open the device */
dh = OpenAndQueryDevice(Closure->device); image = OpenImageFromDevice(Closure->device);
sense = &dh->sense; if(!image)
Stop(_("Can't open %s:\n%s"), Closure->imageName, strerror(errno));
sense = &image->dh->sense;
/*** Only CD can be read in raw mode */ /*** Only CD can be read in raw mode */
if(dh->mainType != CD) if(image->dh->mainType != CD)
{ CloseDevice(dh); { CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
Stop(_("Raw reading only possible on CD media\n")); Stop(_("Raw reading only possible on CD media\n"));
} }
/*** Determine sector to show */ /*** Determine sector to show */
lba = atoi(arg); lba = atoi(arg);
if(lba < 0 || lba >= dh->sectors) if(lba < 0 || lba >= image->dh->sectors)
{ CloseDevice(dh); { CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
Stop(_("Sector must be in range [0..%lld]\n"),dh->sectors-1); Stop(_("Sector must be in range [0..%lld]\n"),image->dh->sectors-1);
} }
PrintLog(_("Contents of sector %lld:\n\n"),lba); PrintLog(_("Contents of sector %lld:\n\n"),lba);
/*** Try the raw read */ /*** Try the raw read */
memset(cdb, 0, MAX_CDB_SIZE); memset(cdb, 0, MAX_CDB_SIZE);
cdb[0] = 0xbe; /* READ CD */ cdb[0] = 0xbe; /* READ CD */
switch(dh->subType) /* Expected sector type */ switch(image->dh->subType) /* Expected sector type */
{ case DATA1: /* data mode 1 */ { case DATA1: /* data mode 1 */
cdb[1] = 2<<2; cdb[1] = 2<<2;
#if 1 #if 1
cdb[9] = 0xb8; /* we want Sync + Header + User data + EDC/ECC */ cdb[9] = 0xb8; /* we want Sync + Header + User data + EDC/ECC */
length=MAX_RAW_TRANSFER_SIZE; length=MAX_RAW_TRANSFER_SIZE;
#else #else
cdb[9] = 0xba; /* we want Sync + Header + User data + EDC/ECC + C2 */ cdb[9] = 0xba; /* we want Sync + Header + User data + EDC/ECC + C2 */
length=2646; length=2646;
#endif #endif
offset=16; offset=16;
skipping to change at line 926 skipping to change at line 995
cdb[4] = (lba >> 8) & 0xff; cdb[4] = (lba >> 8) & 0xff;
cdb[5] = lba & 0xff; cdb[5] = lba & 0xff;
cdb[6] = 0; /* number of sectors to read (3 bytes) */ cdb[6] = 0; /* number of sectors to read (3 bytes) */
cdb[7] = 0; cdb[7] = 0;
cdb[8] = 1; /* read nsectors */ cdb[8] = 1; /* read nsectors */
cdb[10] = 0; /* reserved stuff */ cdb[10] = 0; /* reserved stuff */
cdb[11] = 0; /* no special wishes for the control byte */ cdb[11] = 0; /* no special wishes for the control byte */
CreateMissingSector(ab->buf, lba, NULL, 0, NULL); CreateMissingSector(ab->buf, lba, NULL, 0, NULL);
status = SendPacket(dh, cdb, 12, ab->buf, length, sense, DATA_READ); status = SendPacket(image->dh, cdb, 12, ab->buf, length, sense, DATA_READ);
if(status<0) /* Read failed */ if(status<0) /* Read failed */
{ RememberSense(sense->sense_key, sense->asc, sense->ascq); { RememberSense(sense->sense_key, sense->asc, sense->ascq);
CloseDevice(dh); CloseImage(image);
FreeAlignedBuffer(ab); FreeAlignedBuffer(ab);
Stop("Sector read failed: %s\n", GetLastSenseString(FALSE)); Stop("Sector read failed: %s\n", GetLastSenseString(FALSE));
} }
else else
{ if(Closure->debugCDump) { if(Closure->debugCDump)
CDump(ab->buf, lba, length, 16); CDump(ab->buf, lba, length, 16);
else else
{ HexDump(ab->buf, length, 32); { HexDump(ab->buf, length, 32);
g_printf("CRC32 = %04x\n", Crc32(ab->buf+offset, 2048)); g_printf("CRC32 = %04x\n", Crc32(ab->buf+offset, 2048));
} }
skipping to change at line 1063 skipping to change at line 1132
return bm; return bm;
} }
/*** /***
*** Copy a sector between two image files. *** Copy a sector between two image files.
***/ ***/
void CopySector(char *arg) void CopySector(char *arg)
{ LargeFile *from, *to; { LargeFile *from, *to;
char *from_path, *to_path; char *from_path, *to_path;
gint64 from_sector, to_sector, sectors; guint64 from_sector, to_sector, sectors;
unsigned char buf[2048]; unsigned char buf[2048];
char *cpos = NULL; char *cpos = NULL;
/*** Evaluate arguments */ /*** Evaluate arguments */
cpos = strchr(arg,','); cpos = strchr(arg,',');
if(!cpos) Stop(_("2nd argument is missing")); if(!cpos) Stop(_("2nd argument is missing"));
*cpos = 0; *cpos = 0;
from_path = arg; from_path = arg;
arg = cpos+1; arg = cpos+1;
skipping to change at line 1138 skipping to change at line 1207
LargeClose(to); LargeClose(to);
} }
/*** /***
*** Compare or merge images *** Compare or merge images
***/ ***/
void MergeImages(char *arg, int mode) void MergeImages(char *arg, int mode)
{ LargeFile *left, *right; { LargeFile *left, *right;
char *left_path, *right_path; char *left_path, *right_path;
gint64 left_sectors, right_sectors,min_sectors,s; guint64 left_sectors, right_sectors,min_sectors,s;
int percent,last_percent = 0; int percent,last_percent = 0;
gint64 left_missing, right_missing, mismatch;
char *cpos = NULL; char *cpos = NULL;
/*** Evaluate arguments */ /*** Evaluate arguments */
cpos = strchr(arg,','); cpos = strchr(arg,',');
if(!cpos) Stop(_("2nd argument is missing")); if(!cpos) Stop(_("2nd argument is missing"));
*cpos = 0; *cpos = 0;
left_path = arg; left_path = arg;
right_path = cpos+1; right_path = cpos+1;
skipping to change at line 1173 skipping to change at line 1241
/*** Compare/merge the images */ /*** Compare/merge the images */
if(!mode) PrintLog("Comparing %s (%lld sectors) with %s (%lld sectors).\n", if(!mode) PrintLog("Comparing %s (%lld sectors) with %s (%lld sectors).\n",
left_path, left_sectors, right_path, right_sectors); left_path, left_sectors, right_path, right_sectors);
else PrintLog("Merging %s (%lld sectors) with %s (%lld sectors).\n", else PrintLog("Merging %s (%lld sectors) with %s (%lld sectors).\n",
left_path, left_sectors, right_path, right_sectors); left_path, left_sectors, right_path, right_sectors);
/*** Compare them */ /*** Compare them */
left_missing = right_missing = mismatch = 0;
if(left_sectors < right_sectors) if(left_sectors < right_sectors)
min_sectors = left_sectors; min_sectors = left_sectors;
else min_sectors = right_sectors; else min_sectors = right_sectors;
for(s=0; s<min_sectors; s++) for(s=0; s<min_sectors; s++)
{ unsigned char left_buf[2048], right_buf[2048]; { unsigned char left_buf[2048], right_buf[2048];
if(LargeRead(left, left_buf, 2048) != 2048) if(LargeRead(left, left_buf, 2048) != 2048)
Stop(_("Failed reading sector %lld in image: %s"), Stop(_("Failed reading sector %lld in image: %s"),
s, strerror(errno)); s, strerror(errno));
skipping to change at line 1195 skipping to change at line 1262
if(LargeRead(right, right_buf, 2048) != 2048) if(LargeRead(right, right_buf, 2048) != 2048)
Stop(_("Failed reading sector %lld in image: %s"), Stop(_("Failed reading sector %lld in image: %s"),
s, strerror(errno)); s, strerror(errno));
if(memcmp(left_buf, right_buf, 2048)) if(memcmp(left_buf, right_buf, 2048))
{ {
if(CheckForMissingSector(left_buf, s, NULL, 0) != SECTOR_PRESENT) if(CheckForMissingSector(left_buf, s, NULL, 0) != SECTOR_PRESENT)
{ if(!mode) PrintLog("< Sector %lld missing\n", s); { if(!mode) PrintLog("< Sector %lld missing\n", s);
else else
{ PrintLog("< Sector %lld missing; copied from %s.\n", s, right_path ); { PrintLog("< Sector %lld missing; copied from %s.\n", s, right_path );
#if 0 /* Remove this */ if(!LargeSeek(left, (2048*s)))
int dbl = FALSE;
{ LargeFile *file;
gint64 si;
unsigned char buf[2048];
file = LargeOpen(right_path, O_RDONLY, IMG_PERMS);
for(si=0; si<right_sectors; si++)
{ LargeRead(file, buf, 2048);
if(s!=si && !memcmp(right_buf, buf, 2048))
{ PrintLog("... double sector in %s at %lld\n", right_path,
si);
dbl = TRUE;
}
}
LargeClose(file);
file = LargeOpen(left_path, O_RDONLY, IMG_PERMS);
for(si=0; si<left_sectors; si++)
{ LargeRead(file, buf, 2048);
if(s!=si && !memcmp(right_buf, buf, 2048))
{ PrintLog("... double sector in %s at %lld\n", left_path,
si);
dbl = TRUE;
}
}
LargeClose(file);
}
if(dbl) { PrintLog("NOT copying sector\n"); continue; }
#endif
if(!LargeSeek(left, (gint64)(2048*s)))
Stop(_("Failed seeking to sector %lld in image: %s"), Stop(_("Failed seeking to sector %lld in image: %s"),
s, strerror(errno)); s, strerror(errno));
if(LargeWrite(left, right_buf, 2048) != 2048) if(LargeWrite(left, right_buf, 2048) != 2048)
Stop(_("Failed writing to sector %lld in image: %s"), Stop(_("Failed writing to sector %lld in image: %s"),
s, strerror(errno)); s, strerror(errno));
} }
} }
else if(CheckForMissingSector(right_buf, s, NULL, 0) != SECTOR_PRESENT) else if(CheckForMissingSector(right_buf, s, NULL, 0) != SECTOR_PRESENT)
{ PrintLog("> Sector %lld missing\n", s); { PrintLog("> Sector %lld missing\n", s);
skipping to change at line 1306 skipping to change at line 1345
for(y=0; y<rows; y++) for(y=0; y<rows; y++)
{ printf("%02x &",16*y); { printf("%02x &",16*y);
for(x=0; x<columns; x++) for(x=0; x<columns; x++)
printf("%c %02x ", x==0?' ':'&', *table++); printf("%c %02x ", x==0?' ':'&', *table++);
printf("\\\\\n\\hline\n"); printf("\\\\\n\\hline\n");
} }
printf("\\end{tabular}\n"); printf("\\end{tabular}\n");
} }
/*
* Append a text to a file in printf() manner,
* not keeping it open.
*/
void AppendToTextFile(char* filename, char *format, ...)
{ va_list argp;
FILE *file;
file = fopen(filename, "a");
if(!file)
Stop("Could not open %s: %s\n", filename, strerror(errno));
va_start(argp, format);
g_vfprintf(file, format, argp);
va_end(argp);
if(fclose(file))
Stop("Could not close %s: %s\n", filename, strerror(errno));
}
 End of changes. 107 change blocks. 
198 lines changed or deleted 236 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS