home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / database / patchbig.zip / PATCHBIG.PAS < prev   
Pascal/Delphi Source File  |  1987-03-23  |  9KB  |  300 lines

  1. Program PatchBig;
  2.  
  3. { programmed by David Lu and George Lerner -- Hewitt-Anderson Co.    3/23/87 }
  4. { written in Turbo Pascal 3.01a }
  5.  
  6. { Designed for deleting bad data from damaged database files }
  7. { Use debug to find byte numbers to delete, since most editors cannot }
  8. { deal with 300,000 characters without line breaks }
  9.  
  10. { run patchbig by typing
  11.      PATCHBIG
  12.   or PATCHBIG <sourcefile> <destfile> <firstdel> <lastdel> }
  13.  
  14. { maximum file size is 4,194,176 bytes (approx. 4096 K) }
  15.  
  16. { dBASE -- use browse to find last record that is properly aligned
  17.   USE DAMAGED.DBF
  18.   BROWSE
  19.   record 742 contains "SMITH, LARRY    1210 N. Central"
  20.   record 743 and all records afterwards are moved left 21 characters }
  21.  
  22. { Norton Utilities Text Search -- says SMITH, LARRY is at byte 84075
  23.   in the file.  84075dec = 1486Bhex (Use Sidekick's calculator)
  24.   Or, record 742 * 113 bytes/record = 83846 (14786hex) }
  25.  
  26. { DEBUG DAMAGED.DBF
  27.   R
  28.   File starts at CS:100.  If CS=1085, file starts at 1085:100
  29.   1085:100 = 1095:0   10950 + 1486B = 251BB
  30.   Start looking for exact location of bad data at 251B:B.
  31.   D 251B:B
  32.   Bad data (a partial record) found at 251B:3B to 251B:97.
  33.   251B:3B = 251E:B,    251B:97 = 2524:7
  34.   251EB - 10950 = 1489B (offset into file of start of bad data) = 84123dec
  35.   25247 - 10950 = 148F7 (offset into file of end of bad data) = 84215dec }
  36.  
  37. { Delete characters 84123 to 84215 }
  38.  
  39.  
  40.   Type
  41.     mouthful = record               { 128-byte storage used in SEGMENT 5 }
  42.                  chrs : array [1..128] of byte;
  43.                end;
  44.     Line = string[60];
  45.  
  46.   Var
  47.     source, dest   : file;          { untyped files for block -read & -write }
  48.     tsource, tdest : file of byte;      { files to be copied byte by byte }
  49.     msource, mdest : file of mouthful;  { files to copy by 128-block records }
  50.     sourcename, destname : Line;        { source and destination file names  }
  51.  
  52.     buffer   : string[128];             { storage for block -read and -write }
  53.     recsread : integer;             { counter used by block -read and -write }
  54.     check    : char;
  55.  
  56.     firstdel, lastdel,              { first and last bytes to delete }
  57.     counter  : real;
  58.  
  59.     firstgb,            { first good block after the bad data }
  60.     lastgb,             { last good block before the bad data }
  61.     lastfb,             { last full block before the end of file }
  62.     i         : integer;
  63.  
  64.     bytesleft,          { end mark used in for-loops }
  65.     j, ch     : byte;
  66.  
  67.     block : mouthful;
  68.  
  69.   Procedure Initialize;  { initialize program variables }
  70.  
  71.     Var
  72.       result : integer;   { result of converting a string to a real value }
  73.  
  74.     Function Upper (name : Line) : Line;  { turn a filename into upper case }
  75.  
  76.       Var
  77.         temp : Line;
  78.  
  79.       Begin { of upper }
  80.         temp := name;
  81.         for j := 1 to length(name) do
  82.           temp[j] := upcase(name[j]);
  83.         upper := temp;
  84.       End;  { of upper }
  85.  
  86.     Function Exist (name : Line) : boolean; { see if a file exist on the disk }
  87.  
  88.       Var
  89.         tfile : file;   { test file }
  90.  
  91.       Begin { of exist }
  92.         assign(tfile, name);
  93.         {$I-}
  94.         reset(tfile);
  95.         {$I+}
  96.         if IOresult<>0 then
  97.           exist := false
  98.         else
  99.           exist := true;
  100.         close(tfile);
  101.       End;  { of exist }
  102.  
  103.     Begin { of initialize }
  104.       if paramcount = 4 then
  105.         begin
  106.           sourcename := paramstr(1);
  107.           destname := paramstr(2);
  108.           val(paramstr(3), firstdel, result);
  109.           val(paramstr(4), lastdel, result);
  110.  
  111.           if result<>0 then
  112.             begin
  113.               writeln('Command Line Parameter Must Be In The Format :');
  114.               writeln;
  115.               writeln('   SourceName TargetName FirstByte LastByte');
  116.               writeln;
  117.               writeln('where SourceName and TargetName are strings less than 60 characters each,');
  118.               writeln('and FirstByte and LastByte are both positive decimal integers.');
  119.               halt;
  120.             end;
  121.         end
  122.       else
  123.         begin
  124.           write('Copy From File: ');
  125.           readln(sourcename);
  126.           write('Copy To File  : ');
  127.           readln(destname);
  128.           writeln;
  129.           write('Number of First Byte to Delete (Count in decimal starting with 1) : ');
  130.           readln(firstdel);
  131.           write('Number of Last Byte to Delete : ');
  132.           readln(lastdel);
  133.           writeln;
  134.         end;
  135.  
  136.       if not exist(sourcename) then
  137.         begin
  138.           writeln('Source File ', upper(sourcename), ' Does Not Exist.');
  139.           halt;
  140.         end;
  141.       assign(source, sourcename);
  142.       reset(source);
  143.  
  144.       if sourcename = destname then
  145.         begin
  146.           writeln('File Names Can Not Be The Same');
  147.           halt;
  148.         end;
  149.  
  150.       if exist(destname) then
  151.         begin
  152.           writeln('Destination File ', upper(destname), ' Already Exists.');
  153.           write('Rewrite Old File ? ');
  154.           read(kbd, check);
  155.           writeln(check);
  156.           if upcase(check)<>'Y' then
  157.             halt;
  158.         end;
  159.       assign(dest, destname);
  160.       rewrite(dest);
  161.  
  162.       if firstdel > lastdel then
  163.         begin
  164.           writeln('First Byte to Delete Must Be Less Than Last Byte to Delete.');
  165.           halt;
  166.         end;
  167.  
  168.       writeln;
  169.       writeln('Copy from ', upper(sourcename), ' to ', upper(destname));
  170.       writeln('Delete From Character ', firstdel:0:0, ' to Character ', lastdel:0:0);
  171.       writeln;
  172.       write('press any key to continue, ^C to quit');
  173.       repeat until keypressed;
  174.       writeln;writeln;
  175.  
  176.       firstgb := trunc(lastdel/128)+1;     { first good block after bad data }
  177.       lastgb := trunc(firstdel/128);       { last good block before bad data }
  178.       if lastgb=firstdel/128 then        { if first byte to not copy is multiple }
  179.         lastgb := lastgb-1;                    { of the record size }
  180.     End;  { of initialize }
  181.  
  182.   Procedure Display (message : Line; start, finish : real );
  183.  
  184.     Begin { of display }
  185.       writeln(message);
  186.       writeln('start : ', start:0:0);
  187.       writeln('end   : ', finish:0:0);
  188.     End;  { of display }
  189.  
  190. BEGIN { of main program }
  191.   clrscr;
  192.   writeln('This program will copy a file and skip some bytes in the middle.');
  193.   writeln('The maximum file size is 4,194,176 bytes (approx. 4096 K).');
  194.   writeln;
  195.  
  196.   Initialize;
  197.  
  198.   { *** SEGMENT ONE *** copy 128-byte blocks before the bad data }
  199.   if lastgb > 0 then
  200.     begin
  201.       display('Copying Chars in Blocks Before the Bad Data.', 1, lastgb shl 7);
  202.  
  203.       for i := 1 to lastgb do
  204.         begin
  205.           gotoxy(1, wherey);
  206.           write('byte  # ', i shl 7);
  207.           blockread(source, buffer, 1, recsread);
  208.           blockwrite(dest, buffer, recsread);
  209.         end;
  210.       writeln;writeln;
  211.     end;
  212.   close(source);
  213.   close(dest);
  214.  
  215.   { *** SEGMENT 2 *** copying chars in same block before the bad data }
  216.   assign(tsource, sourcename);
  217.   reset(tsource);
  218.   longseek(tsource, lastgb shl 7);
  219.   lastfb := trunc(longfilesize(tsource)/128);  { last full block before eof }
  220.  
  221.   assign(tdest, destname);
  222.   reset(tdest);
  223.   longseek(tdest, longfilesize(tdest));  { seek dest to end of file }
  224.   display('Copying Chars in Same Block Before the Bad Data.', lastgb shl 7+1, firstdel-1);
  225.   writeln;
  226.  
  227.   bytesleft := round(firstdel-lastgb shl 7)-1;
  228.   counter := 0;
  229.   while counter<bytesleft do
  230.     begin
  231.       read(tsource, ch);
  232.       write(tdest, ch);
  233.       counter := counter+1;
  234.     end;
  235.  
  236.   { *** SEGMENT 3 *** copying chars in same block after the bad data }
  237.   longseek(tsource, lastdel);
  238.   writeln('Copying Chars in Same Block After the Bad Data.');
  239.   writeln('start : ', lastdel+1:0:0);
  240.   write('end   : ');
  241.   if firstgb shl 7-1 < longfilesize(tsource) then
  242.     writeln(firstgb shl 7-1)
  243.   else
  244.     writeln(longfilesize(tsource):0:0);
  245.   writeln;
  246.  
  247.   if firstgb shl 7-1 < longfilesize(tsource) then
  248.     bytesleft := round(firstgb shl 7-lastdel)
  249.   else
  250.     bytesleft := round(longfilesize(tsource)-lastdel);
  251.   counter := 0;
  252.   while counter < bytesleft do
  253.     begin
  254.       read(tsource, ch);
  255.       write(tdest, ch);
  256.       counter := counter+1;
  257.     end;
  258.   if eof(tsource) then
  259.     begin
  260.       close(tsource);
  261.       halt;
  262.     end;
  263.   close(tsource);
  264.  
  265.   { *** SEGMENT 4 *** copy 128-byte blocks after bad data }
  266.   assign(msource, sourcename);
  267.   reset(msource);
  268.   longseek(msource, firstgb);
  269.   display('Copying Blocks After Bad Data.', firstgb shl 7, lastfb shl 7);
  270.  
  271.   for i := firstgb to lastfb-1 do
  272.     begin
  273.       gotoxy(1, wherey);
  274.       write('byte  # ', (i+1) shl 7);
  275.       read(msource, block);
  276.       for j := 1 to 128 do
  277.         write(tdest, block.chrs[j]);
  278.     end;
  279.   writeln;writeln;
  280.   close(msource);
  281.  
  282.   { *** SEGMENT 5 *** copy chars in unfilled last block }
  283.   assign(tsource, sourcename);
  284.   reset(tsource);
  285.   longseek(tsource, lastfb shl 7);
  286.   display('Copying the Chars in Unfilled Last Block.', lastfb shl 7+1, longfilesize(tsource));
  287.  
  288.   bytesleft := round(longfilesize(tsource)-lastfb shl 7);
  289.   counter := 0;
  290.   while counter<bytesleft do
  291.     begin
  292.       counter := counter+1;
  293.       gotoxy(1, wherey);
  294.       write('byte  # ', lastfb shl 7+counter:0:0);
  295.       read(tsource, ch);
  296.       write(tdest, ch);
  297.     end;
  298.   writeln;
  299. END. { of PatchBig }
  300.