[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]