
(*$S+*)

{ This unit allows the users to access the directory information
  held on each disk }
Unit SysUnit;


  Interface
 
 
  Uses
     M2Types,M2IpRoot,M2Sys;
 
  type
    FileType = String[15];
    Volume = 4..12;
 
  var
    D      : File;
 
 
  procedure DelFile( G  : FileType;
                     Vol : Volume );
 
  procedure PrintNames( Vol   : Volume;
                       var NbrOfFiles : integer );
 

Implementation

{ These are the declerations that we don't really want the
  user to see, as they may do silly things }
 
   const
     FirstBlk = 8;
     LastBlk  = 839;
 
   type
     FileArray = Packed array[0..77] of FileType;
 
     Daterec = packed record
                  Month  : 0..12;
                  Day    : 0..31;
                  Year   : 0..100
                  end;
 
     FileKind = (UnTyped,XDsk,Code,Text,Info,Data,Graf,Foto,
                 SecureDir);
 
     DirEntry = Packed Record
                   DFirstBlk  : integer;
                   DLastBlk   : integer;
                   case DFKind : FileKind of
 
                      SecureDir,UnTyped : (Filler1 : 0..2048;
                                           Dvid    : String[7];
                                           DevoBlk : integer;
                                           DNumFiles: 0..77;
                                           DLoadTime: integer;
                                           DLastBoot: DateRec );
 
                      XDsk,Code,Text,Info,Data,Graf,Foto :
                                        (Filler  : 0..1024;
                                         Status  : Boolean;
                                         Dtid    : String[15];
                                         DLastByte: 1..512;
                                         DAccess : DateRec )
                      end;
 
     Directory = array[0..77] of DirEntry;
 

(* ---------------------------------------------------- *)

function IsFile(Name  : FileType;
                Vol   : Volume ) : Boolean;
 This checks if the file, name, exists on the disk, vol 

var
  G  : String;
  i  : integer;

begin
if (Not ( Vol in [4,5,11,12] )) or (Length(Name) < 1) then
  begin
  IsFile := False;
  Exit(IsFile)
  end;

case Vol of
   4  : G := Concat('#4:',Name);
   5  : G := Concat('#5:',Name);
   11 : G := Concat('#11:',Name);
   12 : G := Concat('#12:',Name);
   end;

(*$I-*)
Reset(D,g);
i := IOResult;
if i = 0 then Close(D,lock);
(*$I+*)
IsFile := i = 0
end{IsFile};

(* ---------------------------------------------------- *)

procedure DelFile;
 This procedure deletes a file from disk 

var
  i,j,NbrOfFiles  : Integer;
  DD              : Directory;
  Dummy           : DirEntry;
  Found           : Boolean;
  Key             : char;

begin

 Tell the user what we are doing 
write('#',vol,':',G,' =====> ');
 Check that the name is valid and exists 
if (Not (Vol in [4,5,11,12])) or (Length(G)<1)
    or Not (IsFile(G,Vol)) then
  begin
  writeln('Does not exist');
  Exit(DelFile);
  end;

 Inform that it has been deleted ! 
writeln('Deleted');
{ Ask if the user wishes to update the directory,
  this will do the actual delete ! }
write('Update Directory (Y/N) ?');
repeat
  read(keyboard,Key)
until Key in ['Y','y','N','n'];
writeln(Key);

 If we do update the directory then we have to delete 
if Key in ['Y','y'] then
  begin
  { Get the directory info }
  UnitRead(Vol,DD,SizeOf(DD),4);
  NbrOfFiles := DD[0].DNumFiles;
 
  i := 0;
  Found := False;
 
  { Find the file }
  while not Found do
    begin
    with DD[i] do
      if (Not (DFKind in [SecureDir,UnTyped])) and
        (DTid = G) then
       Found := True
       else
         i := i + 1;
    if i > NbrOfFiles then Exit(DelFile)
    end;
 
  { delete from the directory info }
  Dummy := DD[i];
  For j:= i To pred(NbrOfFiles) do
    DD[j] := DD[j+1];
  DD[NbrOfFiles] := Dummy;
  DD[0].DNumFiles := NbrOfFiles -1;
 
  { Update the actual directory on the disk }
  UnitWrite(Vol,DD,SizeOf(DD),4)
  end;
 
end{DelFile};

(* ---------------------------------------------------- *)

procedure PrintNames;
{ This procedure displays a directory on the screen for
  the user to view }

const
  StrtPos  = 20;
  FinisPos = 26;
  DatePos  = 32;
  TyPos    = 42;

var
  i,k  : integer;
  DD   : Directory;
 
  (* -------------------------------------------------- *)
 
  procedure PrintDAcc(var DAccess  : DateRec );
 
  begin
  GotoXY(DatePos,k);
  with DAccess do
    begin
    write(Day,'-');
    case Month of
      1  : write('Jan');
      2  : write('Feb');
      3  : write('Mar');
      4  : write('Apr');
      5  : write('May');
      6  : write('Jun');
      7  : write('Jul');
      8  : write('Aug');
      9  : write('Sep');
      10 : write('Oct');
      11 : write('Nov');
      12 : write('Dec')
      end{case};
    write('-',Year)
    end{with};
  end{PrintDAcc};
 
  (* -------------------------------------------------- *)
 
  procedure PrintTy( DFKind  : FileKind );
 
  begin
  GotoXY(TyPos,k);
  case DFKind of
     SecureDir : write(' SecureDir ');
     UnTyped   : write(' UnTyped   ');
     XDsk      : write(' XDsk      ');
     Code      : write(' Code      ');
     Text      : write(' Text      ');
     Info      : write(' Info      ');
     Data      : write(' Data      ');
     Graf      : write(' Graf      ');
     Foto      : write(' Foto      ');
     end;
  end{PrintTy};
 
  (* -------------------------------------------------- *)

begin
 Get the directory information 
UnitRead(Vol,DD,SizeOf(DD),4);
NbrOfFiles := DD[0].DNumFiles;

 write which disk ths info is from 
writeln(chr(ff),'DIRECTORY OF #',Vol,':');

k := 1;

 Take care of the first entry 
with DD[1] do
  begin
  if DFirstBlk > FirstBlk then
    begin
    write('<UNUSED>');
    GotoXY(StrtPos,k); write(FirstBlk);
    GotoXY(FinisPos,k);write(pred(DFirstBlk));
    k := k + 1;
    writeln
    end
  end;

 For each entry display on the screen 
for i := 1 to NbrOfFiles do
  with DD[i] do
    begin
    write(Dtid);
    GotoXY(StrtPos,k); write(DFirstBlk);
    GotoXY(FinisPos,k);write(DLastBlk);
    PrintDAcc(DAccess);
    PrintTy(DFKind);
    writeln; k := succ(k);
    if i < NbrofFiles then
      if (DLastBlk < DD[succ(i)].DFirstBlk) then
        begin
        write('<UNUSED>');
        GotoXY(StrtPos,k); write(DLastBlk);
        GotoXY(FinisPos,k);write(pred(DD[succ(i)].DFirstBlk));
        k := k + 1;
        writeln
        end;
    { if we have reached the bottom of the screen and still
      have more to do... wrap around }
    if (k mod 31) = 0 then
      begin
      Pause;
      writeln(chr(ff),' DIRECTORY CONTD');
      k := 1
      end;
    end;

 Take care of the last entry, if blank etc 
with DD[NbrOfFiles] do
  begin
  if DlastBlk < LastBlk then
    begin
    write('<UNUSED>');
    GotoXY(StrtPos,k); write(succ(DLastBlk));
    GotoXY(FinisPos,k);write(LastBlk);
    k := k + 1;
    writeln
    end
  end


end{PrintNames};
 
(* ---------------------------------------------------- *)

end{SysUnit}.

