{ --------------------------------------------------------------- }
{ Dieser Quelltext ist urheberrechtlich geschuetzt.               }
{ (c) 2003-2023      Martin Wodrich, http://www.martinwodrich.de  }
{ (c) 2008-2024      FreeXP, http://www.freexp.de                 }
{                                                                 }
{ Dieser Quelltext ist Freeware.                                  }
{                                                                 }
{ Die allgemeinen Nutzungsbedingungen fuer diesen Quelltext       }
{ finden Sie in der Datei TOUCH.TXT oder auf                      }
{ http://www.martinwodrich.de/Software/Touch/nutzung.htm          }
{ --------------------------------------------------------------- }

{$IFDEF MSDOS}{$M 32768,131072,655360}{$ENDIF}
program touch;
{$IFDEF PASCALABC}
{$DEFINE NOCRYPT}
{$ENDIF}
{$I TOUCH.INC }

{ Betriebsystemabhaeniges }
{$IFNDEF Win16 }
{$IFDEF VPOS2}
uses use32,dos,crt,touch0,touch1,dtdiff
     {$IFNDEF GPLONLY}{$IFNDEF NOCRYPT},hashfile{$ENDIF}
     {$IFNDEF freexp},freexp{$ELSE},fileio{$ENDIF}{$ENDIF};
{$ELSE }
uses {$IFNDEF PASCALABC}dos{$ENDIF}{$IFNDEF WINCE}{$IFNDEF PASCALABC},{$ENDIF}crt{$ENDIF}
     {$IFDEF BPLFN},touchlfn{$ENDIF},touch0,touch1{$IFNDEF PASCALABC},dtdiff{$ENDIF}
     {$IFNDEF GPLONLY}{$IFNDEF NOCRYPT},hashfile{$ENDIF}
     {$IFNDEF freexp}{$IFNDEF PASCALABC},freexp{$ENDIF}{$ELSE},fileio{$ENDIF}{$ENDIF}
     {$IFNDEF bp}{$IFNDEF PASCALABC},sysutils{$ENDIF}{$ENDIF};
{$ENDIF }
{$ELSE }
uses windos,wincrt,strings,touch0,touch1,dtdiff
     {$IFNDEF GPLONLY}{$IFNDEF NOCRYPT},hashfile{$ENDIF}
     {$IFNDEF freexp},freexp{$ELSE},fileio{$ENDIF}{$ENDIF};
{$ENDIF }

type
 macrop = ^macro;
 macro = record
{$IFDEF bp}
   text : string[79];
{$ELSE}
  {$ifdef CPU8086}
   text : string[79];
  {$ELSE}
   text : string;
  {$endif}
{$ENDIF}
   next : macrop;
   end;
{$IFDEF PASCALABC}
 searchrec = record
   fill: array[1..21] of byte;
   attr: byte; 
   time: longint;
   size: longint;
   name: string[12];
   end;
{$ENDIF }

var g:text;
{$IFNDEF NOCRYPT}
    md5f:text;
    sha1f:text;
{$ENDIF}
{$IFNDEF bp}
    ha:longint;
{$ENDIF}
{$IFDEF Win16 }
   dt          : TDateTime;
   DirInfo     : TSearchRec;
   FName,own   : String[79];
   FNamep      : Array[0..79] of Char;
   Dir         : Array[0..67] of Char;
   Name        : Array[0..8] of Char;
   Ext         : Array[0..4] of Char;
   sp          : Array[0..255] of Char;
   reffile     : String[79];
   nc          : boolean;
{$ELSE }
   dt          : DateTime;
   DirInfo     : SearchRec;
   {$IFDEF PASCALABC}
   FName,own   : String[79];
   Dir         : Array[0..67] of Char;
   Name        : Array[0..8] of Char;
   Ext         : Array[0..4] of Char;
   reffile     : String[79];
   {$ELSE }
   {$ifdef CPU8086}
   FName,own   : String[79];
   Dir         : DirStr;
   Name        : NameStr;
   Ext         : ExtStr;
   reffile     : String[79];
   {$ELSE}
   FName,own   : Pathstr;
   Dir         : DirStr;
   Name        : NameStr;
   Ext         : ExtStr;
   reffile     : PathStr;
   {$ENDIF }
   {$ENDIF }
{$ENDIF }
   i,t         : integer;
   h,mi,se,hund: Word;
   y,mo,d      : Word;
   ftime       : Longint;
   ref,rel     : boolean;
   rel1,rel2   : boolean;
   dire        : boolean;
{$IFDEF bp}
   s,u         : string[100];
   f           : file;
   dw          : word;
{$ELSE}
  {$ifdef CPU8086}
   s,u         : string[100];
  {$ELSE}
   s,u         : string;
  {$endif} 
{$ENDIF}
   sim,zcout   : boolean;
{$IFNDEF NOCRYPT}
   md5b        : boolean;
   sha1b       : boolean;
{$ENDIF}
   files       : byte;
   st,n        : macrop;
   dateSet,timeSet : boolean;
   findone,uc,nt : boolean;

{$IFNDEF Win16}
{$IFDEF PASCALABC}
function ownfile:String;
{$ELSE}
function ownfile:Pathstr;
{$ENDIF}
{$ELSE}
function ownfile:String;
{$ENDIF}
begin
  FName:=paramstr(0);
  {$IFDEF Win16 }
  StrPCopy(fnamep,fname);
  FileExpand(Dir,fnamep);
  StrCopy(Dir,fnamep);
  fname:=StrPas(fnamep);
  {$ELSE}
  {$IFDEF PASCALABC}  
  FileExpand(Dir,fname);
  {$ELSE}
  fname:=FExpand(fname);
  {$ENDIF}
  {$ENDIF}
  ownfile:=fname;  
end;

procedure logo;
begin
  {$IFNDEF Win16}
  writeln (touchname+pform+copyright+CR);
  writeln (''+CR);
  {$ELSE}
  StrCopy(WindowTitle,touchname+pform+copyright);
  {$ENDIF}
  own:=ownfile;
end;

procedure StandardIO;
begin
     assign( Input, '' );
     reset( Input );
     assign( Output, '' );
     rewrite( Output );
end;

procedure hilfe;
{$IFDEF BP}
var i:Char;
{$ENDIF}
begin
    writeln ('Parameter fehlt'+CR);
    writeln (''+CR);
    writeln ('touch file1 file2 ... '+Paramark+'T=[+/-]hh:mm:ss '+Paramark+'D=[+/-]tt.mm.[yy]yy '+
              Paramark+'R=refdatei '+Paramark+'H '+Paramark+'S '+Paramark+'V '+
              Paramark+'G '+Paramark+'K'+CR);
    write ('                      ');
    {$IFDEF BPLFN}
    write(Paramark+'LFN ');
    {$ENDIF}
    {$IFDEF Win16}
    write(Paramark+'NC ');
    {$ENDIF}
    writeln (Paramark+'J=Jobfile '+Paramark+'ZC '+Paramark+'I '+CR);
    writeln (''+CR);
    writeln ('Macros:'+CR);
    {$IFDEF BP}
    writeln (' #:             jedes Laufwerk'+CR);
    {$ENDIF}
    writeln (' '+OSDirSeparator+'#'+OSDirSeparator+
             '            jeder Verzeichnis einschliesslich gar keins'+CR);
    writeln (' '+OSDirSeparator+'##'+OSDirSeparator+
             '           und das ganze nochmals rekursiv'+CR);
    writeln (' #              Das aktuelle Verzeichnis und alle alle Dateien in direkten'+CR);
    writeln ('                Unterverzeichnissen touchen'+CR);
    writeln (' ##             Alle Dateien die im aktuellen Verzeichnis und rekursiv in'+CR);
    writeln ('                allen Unterverzeichnissen'+CR);
    {$IFDEF BP}
    writeln (' ###            alle verfuegbaren Dateien (Vorsicht: Auf eigene Gefahr!!!)'+CR);
    {$ENDIF}
    writeln (''+CR);
    writeln (' '+Paramark+'T=Zeitangabe  Zeit, auf das die Dateizeit gesetzt werden soll.'+CR);
    writeln (' '+Paramark+'D=Datum       Datum, auf das das Dateidatum gesetzt werden soll.'+CR);
    writeln (' '+Paramark+'R=reffile     Referenzdatei verwenden'+CR);
    writeln (' '+Paramark+'H             auch versteckte Dateien'+CR);
    writeln (' '+Paramark+'S             auch Systemdateien'+CR);
    writeln (' '+Paramark+'V             Vortaeuschmodus (Simulationslauf)'+CR);
    writeln (' '+Paramark+'G             Dateien in Grossbuchstaben wandeln'+CR);
    write   (' '+Paramark+'K             (nur bei '+Paramark+'G , '+Paramark+'MD5 und '+Paramark+'SHA1 wirksam)');
    writeln (' Dateidatum und Uhrzeit beibehalten'+CR);
    writeln ('Weiter mit beliebiger Taste'+CR);
    {$IFDEF BP}
    i:=Readkey;
    {$ELSE}
    {$IFNDEF WINCE}
    Readkey;
    {$ENDIF}	
    {$ENDIF}
    {$IFDEF BPLFN}
    writeln (' '+Paramark+'LFN           lange Dateinamen benutzen (Vorsicht: Nur bei Verwendung'+CR);
    writeln ('                eines Betriebsystems benutzen, das in seiner DOS-Emulation'+CR);
    writeln ('                lange Dateinamen unterstuetzt z.B. Windows ab 95'+CR);
    {$ENDIF}
    {$IFDEF Win16}
    writeln (' '+Paramark+'NC            Konsolenfenster nicht schliessen'+CR);
    {$ENDIF}
    writeln (' '+Paramark+'J=Jobfile     Dateiliste verwenden, statt lange Argumentliste'+CR);
    writeln (' '+Paramark+'ZC            Neue Dateien als ZConnect-PUFFER erstellen'+CR);
    writeln (' '+Paramark+'I             Interaktiver Modus (Lesen der Dateiinfos von Standard-Input)'+CR);
    {$IFNDEF GPLONLY}
    {$IFNDEF NOCRYPT}
    writeln (' '+Paramark+'MD5           Pruefsummendatei md5sums mit MD5-Summen erstellen'+CR);
    writeln (' '+Paramark+'SHA1          Pruefsummendatei sha1sums mit SHA1-Summen erstellen'+CR);
    {$ENDIF}
    {$ENDIF}
end;

procedure isok(meldung:integer);
begin
 if t<>0 then begin
    case meldung of
    1: Writeln('Datumsangabe ungueltig'+CR);
    2: Writeln('Zeitangabe ungueltig'+CR);
    end;
    halt(1);
 end;
end;

procedure newmacro;
begin
  {Dateien und Macros speichern}
  NEW(n);
  n^.text:=s;
  n^.next:=st;
  st:=n;
end;

function ismacro:boolean;
var re :boolean;
begin
 re:=false;
 {Alle Laufwerke touchen}
 if (copy(s,1,2)='#:') then re:=true;
 {\#\ = keines oder beliebiges Verzeichnis}
 if pos(OSDirSeparator+'#'+OSDirSeparator,s)<>0 then re:=true;
 {\##\ Rekursives Verzeichnisladen}
 if pos(OSDirSeparator+'##'+OSDirSeparator,s)<>0 then re:=true;
 {# entspricht .\#\*.*}
 if s='#' then re:=true;
 {## entspricht .\##\*.*}
 if s='##' then re:=true;
 {### entspricht #:\##\*.*}
 if s='###' then re:=true;
 ismacro:=re;
end;

procedure exmacro;
const test='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var x,y : string[79];
    z   : byte;

  procedure newentry;
  begin
    NEW(n);
    n^.text:=x;
    n^.next:=st;
    st:=n;
  end;

begin
y:=test;
writeln('Expandiere Makro: '+s+CR);
  if (copy(s,1,2)='#:') then begin
  {$IFDEF BP}
  if s<>'#:' then begin
     for i:=1 to 26 do begin
       {Alle Laufwerke touchen}
       {$I-}
       assign(f,y[i]+':'+OSDirSeparator+'touch.$$$');
       rewrite(f);
       {$I+}
       if ioresult=0 then begin
         x:=y[i]+copy(s,2,255);
         newentry;
         close(f);
         erase(f);
       end;
     end;
    end;
  {$ENDIF}
  end
  else if pos(OSDirSeparator+'#'+OSDirSeparator,s)<>0 then begin
   {# = keines oder beliebiges Verzeichnis}
   x:=copy(s,1,pos(OSDirSeparator+'#'+OSDirSeparator,s))+
      copy(s,pos(OSDirSeparator+'#'+OSDirSeparator,s)+3,255);
   NewEntry;
   y:=copy(s,1,pos(OSDirSeparator+'#'+OSDirSeparator,s));
   x:=copy(s,1,pos(OSDirSeparator+'#'+OSDirSeparator,s))+'*.*';
   {$IFDEF Win16 }
   StrPCopy(sp,x);
   Findfirst(sp,$10,DirInfo);
   {$ELSE}
   {$IFNDEF BPLFN}
   dos.Findfirst(x,$10,DirInfo);
   {$ELSE}
   touchlfn.Findfirst(x,$10,DirInfo);
   {$ENDIF}
   {$ENDIF}
   while DosError=0 do
    begin
      z:=(DirInfo.Attr and $10);
      if ((DirInfo.Name[1]<>'.') and (z=$10)) then begin
        x:=y+DirInfo.Name+OSDirSeparator+copy(s,pos(OSDirSeparator+'#'+
             OSDirSeparator,s)+3,255);
        NewEntry;
      end;
      {$IFNDEF BPLFN}
      {$IFNDEF Win16}
      dos.FindNext(DirInfo);
      {$ELSE}
      FindNext(DirInfo);
      {$ENDIF}
      {$ELSE}
      touchlfn.FindNext(DirInfo);
      {$ENDIF}
    end;
  end
  else if pos(OSDirSeparator+'##'+OSDirSeparator,s)<>0 then begin
   {## = keines oder beliebiges Verzeichnis recursiv}
   x:=copy(s,1,pos(OSDirSeparator+'##'+OSDirSeparator,s))+
      copy(s,pos(OSDirSeparator+'##'+OSDirSeparator,s)+4,255);
   NewEntry;
   y:=copy(s,1,pos(OSDirSeparator+'##'+OSDirSeparator,s));
   x:=copy(s,1,pos(OSDirSeparator+'##'+OSDirSeparator,s))+'*.*';
   {$IFDEF Win16 }
   StrPCopy(sp,x);
   Findfirst(sp,$10,DirInfo);
   {$ELSE }
   {$IFNDEF BPLFN}
   dos.Findfirst(x,$10,DirInfo);
   {$ELSE}
   touchlfn.Findfirst(x,$10,DirInfo);
   {$ENDIF}
   {$ENDIF }
   while DosError=0 do
   begin
     z:=(DirInfo.Attr and $10);
     if ((DirInfo.Name[1]<>'.') and (z=$10)) then begin
       x:=y+DirInfo.Name+OSDirSeparator+'##'+OSDirSeparator+
          copy(s,pos(OSDirSeparator+'##'+OSDirSeparator,s)+4,255);
       NewEntry;
     end;
     {$IFNDEF BPLFN}
     {$IFNDEF Win16}
     dos.FindNext(DirInfo);
     {$ELSE}
     FindNext(DirInfo);
     {$ENDIF}
     {$ELSE}
     touchlfn.FindNext(DirInfo);
     {$ENDIF}
   end;
  end
  else if s='#' then begin
   x:='.'+OSDirSeparator+'#'+OSDirSeparator+'*.*';
   NewEntry;
  end
  else if s='##' then begin
   x:='.'+OSDirSeparator+'##'+OSDirSeparator+'*.*';
   NewEntry;
  end
  else if s='###' then begin
   {$IFDEF BP}
   x:='#:'+OSDirSeparator+'##'+OSDirSeparator+'*.*';
   NewEntry;
   {$ENDIF}
  end;
end;

function Testtime(ftime:longint;dateset,timeset:boolean):longint;
var foldtime:longint;
{$IFDEF Win16 }
    dt2     : TDateTime;
{$ELSE }
    dt2     : DateTime;
{$ENDIF }
begin
 {dateset und timeset testtime:=ftime}
 {nur dateset       time aus Datei}
 {nur timeset       date aus Datei}
 {nichts            testtime:=ftime} 
 if not (dateset xor timeset) then testtime:=ftime else begin
 {$IFDEF bp}
 GetFTime(f,foldtime);
 {$ELSE}
 foldtime:=FileAge(fname); 
 {$ENDIF}
 UnpackTime(foldtime,dt2);
 if dateset then begin
    {zeitangaben von dt2 nach dt kopieren}
    dt.Hour:=dt2.Hour;
    dt.Min:=dt2.Min;
    dt.Sec:=dt2.Sec;
   end
   else
   begin
    {datum von dt2 nach dt kopieren}
     dt.Year:=dt2.Year;
     dt.Month:=dt2.Month;
     dt.Day:=dt2.Day;
   end;
 Packtime(dt,foldtime);
 testtime:=foldtime; 
 end;
end;

function isnoWild(fname:string):boolean;
var t : boolean;
    i : byte;
begin
  t:=true;
  for i:=1 to length(fname) do
  begin
   if fname[i]='*' then t:=false;
   if fname[i]='?' then t:=false;
  end;  
  if (fname[length(fname)]=OSDirSeparator) then t:=false;
  {weitere Wildcards?}
  isnoWild:=t;
end;

function testname(fname,reffile:string):boolean;
var i  : integer;
    a,b:string;
begin
  {Reffile im Suchautomaten?}
  for i:=1 to length(fname) do a[i]:=upcase(fname[i]);
  for i:=1 to length(reffile) do b[i]:=upcase(reffile[i]);
  if a<>b then testname:=false else testname:=true;
end;

procedure init_touch;
begin
  files:=anyfile;  
  st:=nil;
  n:=nil;
  dateSet:=false;
  timeSet:=false;
  sim:=false;
  uc:=false;
  nt:=false;
  zcout:=false;
  randomize;
  {$IFDEF Win16}
  nc:=false;
  {$ENDIF}
  {$IFNDEF NOCRYPT}
  md5b:=false;
  sha1b:=false;
  {$ENDIF}
  rel:=false;
  rel1:=false;
  rel2:=false;
  dire:=false;
end;

{$IFDEF BPLFN}
function LFNuseage:boolean;
var t:boolean;
    i:integer;
    j:byte;
    s,u:string;
begin
  if ParamCount = 0 then begin
    LFNuseage:=false;
  end
  else
  begin
   for i:=1 to ParamCount do
   begin
     t:=false;
     s:='';
     u:=ParamStr(i);
     for j:=1 to 4 do s:=s+upcase(u[j]);
     if s=Paramark+'LFN' then t:=true;
   end;
   LFNuseage:=t;
  end;
end;
{$ENDIF}

function strs(v:integer):string;
var s:string;
begin
  str(v,s);
  if length(s)=1 then strs:='0'+s else strs:=s;
end;

procedure ZC;
begin
  writeln(g,'EMP: /TEST'+CR);
  writeln(g,'ABS: TOUCH@touch.invalid'+CR);
  writeln(g,'BET: Testnachricht '+touchname+pform+CR);
  writeln(g,'EDA: '+strs(dt.Year)+strs(dt.Month)+strs(dt.Day)+
                    strs(dt.Hour)+strs(dt.Min)+strs(dt.Sec)+
                    'W+0'+CR);
  writeln(g,'MID: '+strs(dt.Year)+strs(dt.Month)+strs(dt.Day)+
                    strs(dt.Hour)+strs(dt.Min)+strs(dt.Sec)+
                    '.'+strs(random(100))+strs(random(100))+
                    strs(random(100))+strs(random(100))+'@touch.invalid'+CR);
  writeln(g,'ROT: touch.invalid!test'+CR);
  writeln(g,'MAILER: '+touchname+pform+CR);
  writeln(g,'LEN: 30'+CR);
  writeln(g,''+CR);
  writeln(g,'Dies ist eine Testnachricht.'+CR);
end;

function validparm:boolean;
begin
  {$IFDEF Win16}
  if ((ParamCount = 1) and ((ParamStr(1)=Paramark+'NC') or (ParamStr(1)=Paramark+'nc'))) then begin
      validparm:=false;
      nc:=true;
    end
  else validparm:=true;
  {$ELSE}
  validparm:=true;
  {$ENDIF}
end;

     procedure datetimepar;
     begin
       if (copy(s,2,2)='T=') then begin
         {Uhrzeit lesen}
         {/t=hh:mm:ss}
         if Copy(s,4,1)='+' then begin
           rel:=true;
           dire:=true;
           rel1:=true;
         end;
         if Copy(s,4,1)='-' then begin
           rel:=true;
           dire:=false;
           rel1:=true;
         end;
         if (rel and not rel2) then begin
           d:=0;
           mo:=0;
           y:=0;
         end;
         if rel=true then u:=Copy(s,5,255)
         else u:=Copy(s,4,255);
         s:=u;
         val(copy(s,0,(pos(':',s)-1)),h,t);
         isok(2);
         s:=Copy(s,(pos(':',s)+1),255);
         val(copy(s,0,(pos(':',s)-1)),mi,t);
         isok(2);
         s:=Copy(s,(pos(':',s)+1),255);
         val(s,se,t);
         isok(2);
         if not rel then
           if (((h<0) or (h>23)) or ((mi<0) or (mi>59)) or ((se<0) or (se>59))) then begin
             writeln('Zeitangabe ungueltig'+CR);
             halt(1);
           end;
           timeSet:=true;
         end;

       if (copy(s,2,2)='D=') then begin
         {Datum lesen}
         {/d=tt.mm.yy}
         if Copy(s,4,1)='+' then begin
           rel:=true;
           dire:=true;
           rel2:=true;
         end;
         if Copy(s,4,1)='-' then begin
           rel:=true;
           dire:=false;
           rel2:=true;
         end;
         if (rel and not rel1) then begin
           h:=0;
           mi:=0;
           se:=0;
         end;
         if rel=true then u:=Copy(s,5,255)
         else u:=Copy(s,4,255);
         s:=u;
         val(copy(s,0,(pos('.',s)-1)),d,t);
         isok(1);
         s:=Copy(s,(pos('.',s)+1),255);
         val(copy(s,0,(pos('.',s)-1)),mo,t);
         isok(1);
         s:=Copy(s,(pos('.',s)+1),255);
         val(s,y,t);
         isok(1);
         if not rel then
           if (y<100) then begin
              if (y>=80) then y:=y+1900 else y:=y+2000;
              {Kompatibilitaet zwischen Unix und DOS/Windows}
           end;
           if (((d<1) or (d>31)) or ((mo<1) or (mo>12)) or ((y<0) or ((y>99) and ((y<1980) or (y>2107))))) then begin
             Writeln('Datumsangabe ungueltig'+CR);
             halt(1);
           end;
           dateSet:=true;
         end;
       end;

begin
  {$IFNDEF BP }
    { FreePascal }
    {$IFDEF Win16 }
      {$M 65520,655360}
    {$ELSE}
      {$M 65520}
    {$ENDIF }
  {$ELSE }
    { Borland Pascal }
    {$IFDEF MSDOS}
      {$M 65520,0,655360}
    {$ENDIF}
    {$IFDEF DPMI}
      {$M 65520}
    {$ENDIF}
    {$IFDEF Win16}
      {.$M 65520,655360}
    {$ENDIF}
  {$ENDIF }
  {$IFDEF BPLFN}
  if LFNuseage then EnableLFN;
  {$ENDIF}
  {$IFDEF Win16}
  logo;
  InitWinCrt;
  {$ELSE}
  StandardIO;
  logo;
  {$ENDIF}
  init_touch;
  if ((ParamCount = 0) or (validparm=false)) then hilfe
  else
  begin
    {Aktuelle Uhrzeit ermitteln}
    {$IFDEF bp}
    GetTime(h,mi,se,hund);
    Getdate(y,mo,d,dw);
    {$ELSE}
    DeCodeDate(date,y,mo,d);
    DeCodeTime(time,h,mi,se,hund);
    {$ENDIF}
    ref:=false;
    {Erstmal nach Sonderparametern suchen ...}
    for i:=1 to paramcount do
    begin
      s:=ParamStr(i);
      if (copy(s,1,1)=Paramark) then begin
       s[2]:=UpCase(s[2]);
       s[3]:=UpCase(s[3]);
       s[4]:=UpCase(s[4]);
       {Parameter gefunden}
       datetimepar;
       {Hidden-Files auch}
       if (copy(s,2,1)='H') then files:=files or $02;
       {System-Files auch}
       if (copy(s,2,1)='S') then files:=files or $04;
       {Simulationslauf}
       if (copy(s,2,1)='V') then begin
         sim:=true;
         writeln ('Simulationslauf - keine Veraenderungen werden getaetigt'+CR);
       end;
       if (copy(s,2,2)='ZC') then begin
         zcout:=true;
         Writeln ('Neue Dateien werden als ZConnect-PUFFER erstellt.'+CR);
       end;
       if (copy(s,2,1)='G') then uc:=true;
       if (copy(s,2,1)='K') then nt:=true;
       {$IFDEF Win16}
       if (copy(s,2,2)='NC') then nc:=true;
       {$ENDIF}
       if ((copy(s,2,2)='R=') or (copy(s,2,2)='F=')) then begin
         {Referenzdatei}
         s:=copy(s,4,255);
         reffile:=s;
         {$IFDEF bp}        {DOS-Refdatei}
         filemode:=0;
         Assign(f,s);
         {$I-}
         Reset(f);
         {$I+}
         If Ioresult<>0 then begin
           Writeln('Referenzdatei nicht gefunden'+CR);
           halt(1);
         end;
         GetFTime(f,ftime);
         Close(f);
         filemode:=2;
         {$ELSE}               {Unix-Refdatei}
         ftime:=FileAge(reffile);
         if ftime=-1 then begin
           Writeln('Referenzdatei nicht gefunden'+CR);
           halt(1);          
         end;
         {$ENDIF}
         ref:=true;
        end;
       if (copy(s,2,2)='J=') then begin
         {Jobfile}
         filemode:=0;
         s:=copy(s,4,255);
         Assign(g,s);
         {$I-}
         Reset(g);
         {$I+}
         If Ioresult<>0 then begin
           Writeln('Jobdatei nicht gefunden'+CR);
           halt(1);
         end;
         while not EOF(g) do
         begin
           Readln(g,s);
           newmacro;
         end;
         Close(g);
         filemode:=2;
       end;
       if (copy(s,2,1)='I') then begin
        {Interaktiver Modus}
        Readln(s);
        while not (s='') do
        begin
          newmacro;
          Readln(s);
        end;
       end;
       {$IFNDEF GPLONLY}
       {$IFNDEF NOCRYPT}
       if (copy(s,2,3)='MD5') then begin
         {MD5-Summen einschalten}
         md5b:=true;
         {$IFDEF unix}
         if exist('md5sums') then begin
              assign(md5f,'md5sums');
              append(md5f);
         end else
         begin
              assign(md5f,'md5sums');
              rewrite(md5f);
         end;
         {$ELSE}
         if exist('MD5SUMS') then begin
              assign(md5f,'MD5SUMS');
              append(md5f);
         end else
         begin
              assign(md5f,'MD5SUMS');
              rewrite(md5f);
         end;
         {$ENDIF}
       end;

       if (copy(s,2,4)='SHA1') then begin
         {SHA1-Summen einschalten}
         sha1b:=true;
         {$IFDEF unix}
         if exist('sha1sums') then begin
              assign(sha1f,'sha1sums');
              append(sha1f);
         end else
         begin
              assign(sha1f,'sha1sums');
              rewrite(sha1f);
         end;
         {$ELSE}
         if exist('SHA1SUMS') then begin
              assign(sha1f,'SHA1SUMS');
              append(sha1f);
         end else
         begin
              assign(sha1f,'SHA1SUMS');
              rewrite(sha1f);
         end;
         {$ENDIF}
       end;
       {$ENDIF}
       {$ENDIF}
      end
      else newmacro;
    end;
    if ((ref and dateset) or (ref and timeset)) then begin
      Writeln('Entweder Datum/Uhrzeit oder Referenzdatei'+CR);
      halt(1);
    end;
    {$IFNDEF NOCRYPT}
    if not (nt and uc) and not (nt and (md5b or sha1b)) then begin
    {$ELSE}
    if not (nt and uc) and not (nt and (1=2)) then begin
    {$ENDIF}
       if dateset then writeln('Datei-Datum wird gesetzt'+CR);
       if timeset then writeln('Datei-Zeit wird gesetzt'+CR);
       if not (dateset or timeset) then writeln ('Datei-Datum und Datei-Zeit werden aktualisiert'+CR);
    end;
    if uc then writeln('Dateinamen grossschreiben'+CR);
    {$IFNDEF NOCRYPT}
    if md5b then writeln('MD5-Pruefsummen berechnen'+CR);
    if sha1b then writeln('SHA1-Pruefsummen berechnen'+CR);
    {$ENDIF}
    {Datetime packen}
    if not ref then begin
       dt.Year:=y;
       dt.Month:=mo;
       dt.Day:=d;
       dt.Hour:=h;
       dt.Min:=mi;
       dt.Sec:=se;
       PackTime(dt,Ftime);
    end;
    {Dateien verarbeiten}
    if st=nil then begin
      writeln('Dateiangabe fehlt'+CR);
      halt(1);
    end;
    n:=st;
    repeat
      s:=n^.text;
      st:=n^.next;
      dispose(n);
      n:=st;
      if ismacro then exmacro else
      begin
       {kein Sonderparameter also Dateiname}
       if (s[length(s)]=OSDirSeparator) then s:=s else begin
         findone:=false;
         {$IFDEF Win16 }
         StrPCopy(sp,s);
         FileSplit(sp,Dir,Name,Ext);
         FindFirst(sp,files,DirInfo);
         {$ELSE}
         {$IFNDEF BPLFN}
         FSplit(s,Dir,Name,Ext);
         dos.FindFirst(s,files,DirInfo);
         {$ELSE}
         touchlfn.FSplit(s,Dir,Name,Ext);
         touchlfn.FindFirst(s,files,DirInfo);             
         {$ENDIF}
         {$ENDIF}
         while DosError = 0 do
         begin           
           fname:=DirInfo.name;
           findone:=true;
           {$IFDEF Win16 }
           If StrPas(Dir)='' then begin
             StrPCopy(fnamep,fname);
             FileExpand(Dir,fnamep);
             StrCopy(Dir,fnamep);
             fname:=StrPas(fnamep);
           end
           {$ELSE}
           If Dir='' then begin
             fname:=FExpand(fname);
           end
           {$ENDIF}
           else fname:=Dir+fname;
           if fname<>own then begin
             write(fname);
             {$IFNDEF GPLONLY}
	     {$IFNDEF NOCRYPT}
             if md5b then writeln(md5f,md5sum_file(fname)+' *'+fname);             
             if sha1b then writeln(sha1f,sha1sum_file(fname)+' *'+fname);
             {$ENDIF}
	     {$ENDIF}
             {Nur MD5/SHA1-Betrieb erlauben mit /MD5 & /K bzw. /SHA1 & /K}
             {$IFNDEF NOCRYPT}
             if not (((md5b or sha1b) and nt) and (not uc)) then begin
             {$ELSE}
             if not (((1=2) and nt) and (not uc)) then begin
             {$ENDIF}
             {Refdatei nicht touchen}
             if ref and testname(reffile,fname) then writeln(' Referenz'+CR)
             else begin
               if (sim=false) then begin
                  {$IFDEF bp}                
                  Assign(f,fname);                  
                  if (nt and uc) then GetFtime(f,ftime);
                  {$I-}
                  if uc then begin
                     rename(f,'temp.$$$');
                     if IOResult <> 0 then writeln(' Umbenennen der Datei fehlgeschlagen'+CR);
                     for i:=1 to length(fname) do fname[i]:=upcase(fname[i]);
                     rename(f,fname);
                     if IOResult <> 0 then begin
                       writeln(' Umbenennen der Datei kritisch fehlgeschlagen'+CR);
                       halt(1);
                     end;
                  end;
                  Reset(f,1);
                  {$I+}
                  if IOResult <> 0 then writeln(' Oeffnen der Datei fehlgeschlagen'+CR);
                  if not (nt and uc) then ftime:=Testtime(ftime,dateset,timeset);                  
                  if rel then begin
                    GetFTime(f,ftime);
                    Ftime:=calcdt(Ftime,y,mo,d,h,mi,se,dire);
                  end;
                  SetFtime(f,Ftime);
                  if Doserror<>0 then writeln('!'+CR) else writeln(''+CR);
                  close(f);
                  {$ELSE}
		  {$I-}   
                  ha:=FileOpen(fname,fmOpenRead);
                  if (nt and uc) then ftime:=FileGetDate(ha);
                  FileClose(ha);
                  if uc then begin
                       
                       if not RenameFile(fname,'temp.$$$') then begin
                              writeln(' Umbenennen der Datei fehlgeschlagen'+CR);
                       end; 
                       for i:=1 to length(fname) do fname[i]:=upcase(fname[i]);
                       if not RenameFile('temp.$$$',fname) then begin
                              writeln(' Umbenennen der Datei kritisch fehlgeschlagen'+CR);
                              halt(1);
                       end;
                  end;                  
                  if not (nt and uc) then ftime:=Testtime(ftime,dateset,timeset);
                  if rel then begin
                     ftime:=FileAge(fname);
                     Ftime:=calcdt(Ftime,y,mo,d,h,mi,se,dire);
                  end;
                  {$IFDEF unix1}
                  if unixsetftime(s,ftime2epoch(ftime)) then writeln(''+CR) else writeln('!'+CR);
                  {$ELSE}
                  ha:=FileOpen(fname,fmOpenReadWrite);
                  if FileSetDate(ha,ftime)=0 then writeln(''+CR) else writeln('!'+CR);
                  FileClose(ha);
		  {$ENDIF}
                  {$I+}
                  {$ENDIF}
               end
               else writeln(''+CR);
             end;
             end else writeln;
           end;
           {$IFNDEF BPLFN}
           {$IFNDEF Win16}
           dos.FindNext(DirInfo);
           {$ELSE}
           FindNext(DirInfo);
           {$ENDIF}
           {$ELSE}
           touchlfn.FindNext(DirInfo);
           {$ENDIF}
         end;         
         {Keine Datei gefunden ? Dann neu anlegen!!}
         if findone=false then begin
          if isnoWild(fname) then begin
           writeln(s+CR);
           if (sim=false) then begin             
                 Assign(g,s);
                 {$I-}
                 Rewrite(g);
                 {$I+}
                 if IOResult <> 0 then writeln(' Anlegen der neuen Datei fehlgeschlagen'+CR)
                 else if zcout=true then ZC;
                 {$IFNDEF unix1}
                 {$I-}
                 Reset(g);
                 {$I+}
                 if IOResult <> 0 then writeln(' Anlegen der neuen Datei fehlgeschlagen'+CR);
                 {$I-}                                  
                 SetFtime(g,Ftime);
                 {$I+}
                 if IOResult <> 0 then writeln (' Touchen der neuen Datei fehlgeschlagen'+CR);
                 {$ENDIF}
                 {$I-}
                 close(g);
                 {$I+}
                 if ioresult <> 0 then writeln (' Schliessen der neuen Datei fehlgeschlagen'+CR);
                 {$IFDEF unix1}                 
                 if unixsetftime(s,ftime2epoch(ftime)) then write('') 
                 else writeln(' Touchen der neuen Datei fehlgeschlagen'+CR);
                 {$ENDIF}
           end;
          end;
         end;
         {$IFNDEF BP }
         {FP needs Findclose, BP has no Findclose}
         dos.Findclose(DirInfo);
         {$ENDIF }
        end;
      end;
    until n=nil;
  end;
  {$IFDEF Win16}
  if nc then Readln;
  DoneWinCrt;
  {$ENDIF}
  {$IFNDEF GPLONLY}
  {$IFNDEF NOCRYPT}
  if md5b then close(md5f);
  if sha1b then close(sha1f);
  {$ENDIF}
  {$ENDIF}
end.
