home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
patchbig.zip
/
PATCHBIG.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1987-03-23
|
9KB
|
300 lines
Program PatchBig;
{ programmed by David Lu and George Lerner -- Hewitt-Anderson Co. 3/23/87 }
{ written in Turbo Pascal 3.01a }
{ Designed for deleting bad data from damaged database files }
{ Use debug to find byte numbers to delete, since most editors cannot }
{ deal with 300,000 characters without line breaks }
{ run patchbig by typing
PATCHBIG
or PATCHBIG <sourcefile> <destfile> <firstdel> <lastdel> }
{ maximum file size is 4,194,176 bytes (approx. 4096 K) }
{ dBASE -- use browse to find last record that is properly aligned
USE DAMAGED.DBF
BROWSE
record 742 contains "SMITH, LARRY 1210 N. Central"
record 743 and all records afterwards are moved left 21 characters }
{ Norton Utilities Text Search -- says SMITH, LARRY is at byte 84075
in the file. 84075dec = 1486Bhex (Use Sidekick's calculator)
Or, record 742 * 113 bytes/record = 83846 (14786hex) }
{ DEBUG DAMAGED.DBF
R
File starts at CS:100. If CS=1085, file starts at 1085:100
1085:100 = 1095:0 10950 + 1486B = 251BB
Start looking for exact location of bad data at 251B:B.
D 251B:B
Bad data (a partial record) found at 251B:3B to 251B:97.
251B:3B = 251E:B, 251B:97 = 2524:7
251EB - 10950 = 1489B (offset into file of start of bad data) = 84123dec
25247 - 10950 = 148F7 (offset into file of end of bad data) = 84215dec }
{ Delete characters 84123 to 84215 }
Type
mouthful = record { 128-byte storage used in SEGMENT 5 }
chrs : array [1..128] of byte;
end;
Line = string[60];
Var
source, dest : file; { untyped files for block -read & -write }
tsource, tdest : file of byte; { files to be copied byte by byte }
msource, mdest : file of mouthful; { files to copy by 128-block records }
sourcename, destname : Line; { source and destination file names }
buffer : string[128]; { storage for block -read and -write }
recsread : integer; { counter used by block -read and -write }
check : char;
firstdel, lastdel, { first and last bytes to delete }
counter : real;
firstgb, { first good block after the bad data }
lastgb, { last good block before the bad data }
lastfb, { last full block before the end of file }
i : integer;
bytesleft, { end mark used in for-loops }
j, ch : byte;
block : mouthful;
Procedure Initialize; { initialize program variables }
Var
result : integer; { result of converting a string to a real value }
Function Upper (name : Line) : Line; { turn a filename into upper case }
Var
temp : Line;
Begin { of upper }
temp := name;
for j := 1 to length(name) do
temp[j] := upcase(name[j]);
upper := temp;
End; { of upper }
Function Exist (name : Line) : boolean; { see if a file exist on the disk }
Var
tfile : file; { test file }
Begin { of exist }
assign(tfile, name);
{$I-}
reset(tfile);
{$I+}
if IOresult<>0 then
exist := false
else
exist := true;
close(tfile);
End; { of exist }
Begin { of initialize }
if paramcount = 4 then
begin
sourcename := paramstr(1);
destname := paramstr(2);
val(paramstr(3), firstdel, result);
val(paramstr(4), lastdel, result);
if result<>0 then
begin
writeln('Command Line Parameter Must Be In The Format :');
writeln;
writeln(' SourceName TargetName FirstByte LastByte');
writeln;
writeln('where SourceName and TargetName are strings less than 60 characters each,');
writeln('and FirstByte and LastByte are both positive decimal integers.');
halt;
end;
end
else
begin
write('Copy From File: ');
readln(sourcename);
write('Copy To File : ');
readln(destname);
writeln;
write('Number of First Byte to Delete (Count in decimal starting with 1) : ');
readln(firstdel);
write('Number of Last Byte to Delete : ');
readln(lastdel);
writeln;
end;
if not exist(sourcename) then
begin
writeln('Source File ', upper(sourcename), ' Does Not Exist.');
halt;
end;
assign(source, sourcename);
reset(source);
if sourcename = destname then
begin
writeln('File Names Can Not Be The Same');
halt;
end;
if exist(destname) then
begin
writeln('Destination File ', upper(destname), ' Already Exists.');
write('Rewrite Old File ? ');
read(kbd, check);
writeln(check);
if upcase(check)<>'Y' then
halt;
end;
assign(dest, destname);
rewrite(dest);
if firstdel > lastdel then
begin
writeln('First Byte to Delete Must Be Less Than Last Byte to Delete.');
halt;
end;
writeln;
writeln('Copy from ', upper(sourcename), ' to ', upper(destname));
writeln('Delete From Character ', firstdel:0:0, ' to Character ', lastdel:0:0);
writeln;
write('press any key to continue, ^C to quit');
repeat until keypressed;
writeln;writeln;
firstgb := trunc(lastdel/128)+1; { first good block after bad data }
lastgb := trunc(firstdel/128); { last good block before bad data }
if lastgb=firstdel/128 then { if first byte to not copy is multiple }
lastgb := lastgb-1; { of the record size }
End; { of initialize }
Procedure Display (message : Line; start, finish : real );
Begin { of display }
writeln(message);
writeln('start : ', start:0:0);
writeln('end : ', finish:0:0);
End; { of display }
BEGIN { of main program }
clrscr;
writeln('This program will copy a file and skip some bytes in the middle.');
writeln('The maximum file size is 4,194,176 bytes (approx. 4096 K).');
writeln;
Initialize;
{ *** SEGMENT ONE *** copy 128-byte blocks before the bad data }
if lastgb > 0 then
begin
display('Copying Chars in Blocks Before the Bad Data.', 1, lastgb shl 7);
for i := 1 to lastgb do
begin
gotoxy(1, wherey);
write('byte # ', i shl 7);
blockread(source, buffer, 1, recsread);
blockwrite(dest, buffer, recsread);
end;
writeln;writeln;
end;
close(source);
close(dest);
{ *** SEGMENT 2 *** copying chars in same block before the bad data }
assign(tsource, sourcename);
reset(tsource);
longseek(tsource, lastgb shl 7);
lastfb := trunc(longfilesize(tsource)/128); { last full block before eof }
assign(tdest, destname);
reset(tdest);
longseek(tdest, longfilesize(tdest)); { seek dest to end of file }
display('Copying Chars in Same Block Before the Bad Data.', lastgb shl 7+1, firstdel-1);
writeln;
bytesleft := round(firstdel-lastgb shl 7)-1;
counter := 0;
while counter<bytesleft do
begin
read(tsource, ch);
write(tdest, ch);
counter := counter+1;
end;
{ *** SEGMENT 3 *** copying chars in same block after the bad data }
longseek(tsource, lastdel);
writeln('Copying Chars in Same Block After the Bad Data.');
writeln('start : ', lastdel+1:0:0);
write('end : ');
if firstgb shl 7-1 < longfilesize(tsource) then
writeln(firstgb shl 7-1)
else
writeln(longfilesize(tsource):0:0);
writeln;
if firstgb shl 7-1 < longfilesize(tsource) then
bytesleft := round(firstgb shl 7-lastdel)
else
bytesleft := round(longfilesize(tsource)-lastdel);
counter := 0;
while counter < bytesleft do
begin
read(tsource, ch);
write(tdest, ch);
counter := counter+1;
end;
if eof(tsource) then
begin
close(tsource);
halt;
end;
close(tsource);
{ *** SEGMENT 4 *** copy 128-byte blocks after bad data }
assign(msource, sourcename);
reset(msource);
longseek(msource, firstgb);
display('Copying Blocks After Bad Data.', firstgb shl 7, lastfb shl 7);
for i := firstgb to lastfb-1 do
begin
gotoxy(1, wherey);
write('byte # ', (i+1) shl 7);
read(msource, block);
for j := 1 to 128 do
write(tdest, block.chrs[j]);
end;
writeln;writeln;
close(msource);
{ *** SEGMENT 5 *** copy chars in unfilled last block }
assign(tsource, sourcename);
reset(tsource);
longseek(tsource, lastfb shl 7);
display('Copying the Chars in Unfilled Last Block.', lastfb shl 7+1, longfilesize(tsource));
bytesleft := round(longfilesize(tsource)-lastfb shl 7);
counter := 0;
while counter<bytesleft do
begin
counter := counter+1;
gotoxy(1, wherey);
write('byte # ', lastfb shl 7+counter:0:0);
read(tsource, ch);
write(tdest, ch);
end;
writeln;
END. { of PatchBig }