[Back to ARCHIVES SWAG index] [Back to Main SWAG index] [Original]
Unit UnArc;
{$O+}
interface
Type
  UnCompressFileProc  = Procedure (ArcP:string);
  UnCompressFileProc2 = Procedure;
  UnCompressFileProc3 = Procedure (command,param:string);
Procedure LoadArchiveDef(fn:string);
Function UnCompressFile(  filepath    : String;
                          PreStats    : UnCompressFileProc;
                          ExecProc    : UnCompressFileProc3;
                          PreExec,
                          PostExec    : UnCompressFileProc2;
                        var
                          broken,
                          Sfx         : boolean;
                          errorstring : String):boolean;
Function CompressType:string;
function Compress(Destpath,SourcePath: String;
                          ExecProc    : UnCompressFileProc3;
                          PreExec,
                          PostExec    : UnCompressFileProc2;
                          var errstr:string ):boolean;
implementation
Uses Dos,Etc;
Const NumOfIDBytes = 20;
type
     ByteUsed = record Used: boolean;Val : byte; end;
     ToArcDefType = ^ArcDefType;
     ArcDefType = record
       Next     : ToArcDefType;
       Sfx      : boolean;
       ProgID   : String[3];
       Prog     : String[12];
       Param    : String[20];
       IDBlock  : array[1..NumOfIDBytes] of ByteUsed;
     end;
     ReCompressType = Record
       ProgID : String[3];
       Prog   : String[12];
       Param  : String[20];
       end;
Var ArcDefRoot: ToArcDefType;
    ArcP      : string[3];
    ReComp    : RecompressType;
function compresstype:string;
  begin
  compresstype := recomp.progid;
  end;
Procedure LoadArchiveDef(fn:string);
  type bt = array[1..2048] of byte;
  Var Cur: ToArcDefType;
      ADF: text;
      cl : string;
      b  : ^bt;
  procedure ProcessLine;
    var hdr:string[20];
        i  : byte;
    procedure Seek(a:char); begin cl:=copy(cl,pos(a,cl)+1,length(cl)); { seek to " } end;
    procedure Clean(a:char); begin cl:=copy(cl,pos(a,cl)+1,length(cl)) end;
    begin
    cl:=rtrim(ltrim(cl));
    if cl[1]<>';' then
      begin
      hdr:=upcasestr(copy(cl,1,pos(':',cl)));
      if copy(hdr,1,2)=copy('UN:',1,2) then {'UN'}
        begin
        if cur=nil then
             begin
             new(cur);
             cur^.next:=nil;
             ArcDefRoot:=Cur;
             end
          else
            begin
            new(cur^.next);
            cur:=cur^.next;
            cur^.next:=nil;
            end;
        Seek('"');
        Cur^.ProgID:=copy(cl,1,pos('"',cl)-1);
        Clean('"');
        Seek('"');
        Cur^.Prog:=Copy(cl,1,pos('"',cl)-1);
        clean('"');
        Seek('"');
        Cur^.Param:=copy(cl,1,pos('"',cl)-1);
        Clean('"');
        For i:=1 to NumOfIDBytes do Cur^.IDBlock[i].Used:=false;
        For i:=1 to NumOfIDBytes do
         begin
         seek('$');
         if length(cl)>0 then
           begin
           if copy(cl,1,2)<>'--' then
             begin
             Cur^.IDBlock[i].Val:=Hex2Byte(copy(cl,1,2));
             Cur^.IDBlock[i].used:=true;
             end
           else Cur^.IDblock[i].used:=false;
           delete(cl,1,2);
           end;
         end;
        if hdr='UNSFX:' then Cur^.SFX:=true else Cur^.SFX:=false;
        end
      else
       if HDR='TOARC:' then
        begin
        seek('"');
        ReComp.ProgID:=copy(cl,1,pos('"',cl)-1);
        clean('"');
        Seek('"');
        ReComp.Prog:=copy(cl,1,pos('"',cl)-1);
        Clean('"');
        seek('"');
        ReComp.Param:=copy(cl,1,pos('"',cl)-1);
        clean('"');
        end;
     end;
    end;
  begin
  new(b);
  ArcDefRoot := nil;
  cur:=ArcDefRoot;
  Assign(adf,fn);
  reset(adf);
  settextbuf(adf,b^,sizeof(b^));
  readln(adf,cl);
  processline;
  while not eof(adf) do
     begin
     Readln(adf,cl);
     processline;
     end;
  close(adf);
  Dispose(b);
  end;
  function Compress(Destpath,SourcePath: String;
                          ExecProc    : UnCompressFileProc3;
                          PreExec,
                          PostExec    : UnCompressFileProc2;
                          var errstr:string ):boolean;
    var
     Dir   : DirStr;
     Name  : NameStr;
     Ext   : ExtStr;
     a     : byte;
     f     : file;
     runstr: string;
     runparmr:string;
     runparmd:string;
     derror: integer;
    begin
    Compress := TRUE;
    runstr:=FSearch(ReComp.Prog,GetEnv('PATH'));
    if runstr='' then
     begin
     errstr:='Could not find '+recomp.prog+' in PATH';
     compress := false;
     exit;
     end;
    runparmr:=ReComp.Param+' '+destpath+' '+sourcepath;
    PreExec;
    Execproc(RunStr, RunParmR);
    postexec;
   derror:=dosexitcode;
  if not ((derror)=0) then
    begin
    errstr:='Device Error or Low Mem';
    compress := false;
    exit;
    end
    end;
Function UnCompressFile(  filepath    : String;
                          PreStats    : UnCompressFileProc;
                          ExecProc    : UnCompressFileProc3;
                          PreExec,
                          PostExec    : UnCompressFileProc2;
                        var
                          broken,
                          Sfx         : boolean;
                          errorstring : String):boolean;
  var tempfile :file;
      uncompstr:string;
      p        :string;
      bffr     :array[1..NumOfIDBytes] of byte;
      derror   :integer;
  var tts:string;
  Procedure WhichFormat;
    var cur      : ToArcDefType;
    function match:boolean;
     var i:byte;
     begin
     for i:=1 to NumOfIDBytes do
      if Cur^.IDBlock[i].Used then
       begin
       if not (bffr[i]=Cur^.IDBlock[i].Val) then
         begin
         Match:=False;
         Exit;
         end;
       end;
     Match:=true;
     end;
    begin
    { set uncompstr to '' for unrecognized compression }
    UnCompStr:='';
    Cur:=ArcDefRoot;
    while cur<>nil do
      begin
      if Match then begin
       UnCompStr:=Cur^.Prog;
       Sfx:=Cur^.Sfx;
       ArcP:=Cur^.ProgID;
       P:=Cur^.param;
       end;
      Cur:=Cur^.Next;
      end;
    end;
  var SizeToRead:word;
  begin
  errorstring:= '';
  assign(tempfile,filepath);
  reset(tempfile,1);
  if filesize(tempfile)<sizeof(bffr) then
      begin
      fillchar(bffr,sizeof(bffr),#0);
      sizetoread:=filesize(tempfile)-1;
      end
  else SizeToRead:=Sizeof(Bffr);
  blockread(tempfile,bffr,sizetoread);
  close(tempfile);
  Sfx:=false;
  WhichFormat;
  if UnCompStr='' then
     begin
     Broken:=False;
     errorstring :=  'Unknown Format';
     UnCompressFile:=False;
     Exit;
     end;
   uncompstr:=FSearch(UnCompStr,GetEnv('PATH'));
   if uncompstr='' then
     begin
     broken := false;
     ErrorString := 'Can''t Find UN-ARCHIVER for: '+ArcP;
     UnCompressFile := false;
     exit;
     end;
  PreStats (ArcP);
  tts:=fexpand('.\TEMP$$.$$');
  mkdir(tts);
  chdir( tts );
  PreExec;
  ExecProc(uncompstr,p+' '+filepath+' *.*');
  PostExec;
  derror:=dosexitcode;
  if not (hi(derror)=0) then
    begin
    ErrorString := 'Device Error - ^C or Low Memory';
    broken := false;
    UnCompressFile := false;
    exit;
    end;
  UnCompressFile := DError=0;
  Broken:=Not (DError=0);
  chdir( fexpand ('..') );
  end;
begin
 ArcDefRoot := nil;
end.
[Back to ARCHIVES SWAG index] [Back to Main SWAG index] [Original]