home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MFMP110A.ZIP / MFMP.PAS < prev    next >
Pascal/Delphi Source File  |  1992-05-25  |  113KB  |  3,246 lines

  1. (*#module(turbo_comp=>off)*)
  2. Program Maximus_File_Manager(Input,Output);
  3.  
  4. IMPORT
  5.   OS2DEF(ULONG),
  6.   DOS(FILEFINDBUF,HDIR,HDIR_CREATE,EXIT_PROCESS),
  7.   PASDOS(paramcount,paramstr,getdate,gettime),
  8.   TURBOCRT(white,blink,yellow,magenta,cyan,green,red,black,lightred,assigncrt),
  9.   TURBODOS(dirstr,namestr,extstr,pathstr,diskfree,fsplit),
  10.   MaxAreas *,
  11. {  Memory *, }
  12.   MfmCopy *,
  13.   Screen *,
  14.   Strings *,
  15.   TURBOSYS(_STR_INT,upcase)
  16.   ;
  17.  
  18. Const
  19. {  Pgmid = 'MFM 1.10 16nov91 MWBJR Enterprise 1:273/701.0 (215)641-0270';}
  20.   Pgmid = 'MFM 1.10.OS2.1 MWBJR Ent. 1:273/701, OS/2 - C. Renshaw 1:270/114';
  21.   Base153A = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@!#$%&''()-^_`{}~';
  22.   Base153B = 'ÇÜÄÅÉÆÖ¢£¥₧ƒÑªº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩';
  23.   Base153C = '╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■';
  24.   MaxSkip = 20;
  25.  
  26. Type
  27.   TypeOfRecordType = (Comment,FileRecord,Orphan,Offline);
  28.   ListPtr = ^ListRecord;
  29.   ListRecord = Record
  30.     NextEntry, PrevEntry : ListPtr;
  31.     TypeOfRecord : TypeOfRecordType;
  32.     FileName : String[12];
  33.     FileSize, FileDate : Integer;
  34.     Description : String[144];
  35.     Tagged : Boolean;
  36.   End;
  37.   AreaPtr = ^AreaRecord;
  38.   AreaRecord = Record
  39.     NextEntry, PrevEntry : AreaPtr;
  40.     AreaPath : String[40];
  41.   End;
  42.   S8 = String[8];
  43.  
  44. Var
  45.   tfname : string[12];
  46.   OK :boolean;
  47.   tempstr : maxstring;
  48.   ztempstr : array[1..255] of char;
  49.   hndlhdir : HDIR;
  50.   attr, reslng, count, retn : word;
  51.   rsrvd : ULONG;
  52.   Gcx : Char;
  53.   Gbx : Byte;
  54.   Counter, Row, AreaCounter, OffSet, Columns, ColumnPos : Byte;
  55.   Result : Word;
  56.   FileList, NewFileList : Text;
  57.   DirInfo : FILEFINDBUF;
  58.   Date : DateTime;
  59.   Month, Day : String[2];
  60.   Year : String[4];
  61.   AreaMask : String[20];
  62.   FileAreaPath : String[80];
  63.   WorkString : MAXSTRING;
  64.   NumberOfEntries, NumberOfAreaEntries, NumberOfFiles : Word;
  65.   D : DirStr;
  66.   N : NameStr;
  67.   E : ExtStr;
  68.   Altered, FilesBbs : Boolean;
  69.   FirstEntry, LastEntry, NewEntry, OldEntry, TopEntry, NextPrintEntry,
  70.   CurrentEntry, StackEntry, KillEntry, BeginSort, EndSort : ListPtr;
  71.   FirstAreaEntry, LastAreaEntry, NewAreaEntry,
  72.   OldAreaEntry, CurrentAreaEntry, ChooseAreaEntry : AreaPtr;
  73.   StringToFind : String[12];
  74.   FreeSpace, SizeOfFiles : Integer;
  75.   FreeSpaceString : String[6];
  76.   OkToAddToList, Changed : Boolean;
  77.   Base153 : String[153];
  78.   SkipList : Array[1..MaxSkip] Of String[12];
  79. {========================================================================}
  80.  
  81.  
  82. {========================================================================}
  83. Function GetDateString(PackedTime : Integer) : S8;
  84.   Var
  85.     Month, Day : String[2];
  86.     Year : String[4];
  87.     OK : boolean;
  88.   Begin
  89.     UnpackTime(PackedTime,Date);
  90.     If Date.Year < 20 Then Date.Year := Date.Year + 1980;
  91.     IntToStr(Date.Month,Month,10,OK);
  92.     IntToStr(Date.Day,Day,10,OK);
  93.     IntToStr(Date.Year,Year,10,OK);
  94.     If Length(Month) = 1 Then Month := '0' + Month;
  95.     If Length(Day) = 1 Then Day := '0' + Day;
  96.     Year := Copy(Year,3,2);
  97.     GetDateString := Month + '/' + Day + '/' + Year;
  98.   End;
  99. {========================================================================}
  100. Function GetTimeString(PackedTime : Integer) : S8;
  101.   Var
  102.     Hour, Min, Sec : String[2];
  103.   Begin
  104.     UnpackTime(PackedTime,Date);
  105.     _STR_INT(Date.Hour, 0,Hour);
  106.     _STR_INT(Date.Min, 0,Min);
  107.     _STR_INT(Date.Sec, 0,Sec);
  108.     If Length(Hour) = 1 Then Hour := '0' + Hour;
  109.     If Length(Min) = 1 Then Min := '0' + Min;
  110.     If Length(Sec) = 1 Then Sec := '0' + Sec;
  111.     GetTimeString := Hour + ':' + Min + ':' + Sec;
  112.   End;
  113. {========================================================================}
  114. Function GetPackedTime(DateString, TimeString : S8) : Integer;
  115.   Var
  116.     Code : boolean;
  117.     PackedTime : Integer;
  118.   Begin
  119.     tempstr := Copy(DateString,1,2);
  120.     Date.Month := StrToInt(tempstr,10,Code);
  121.     tempstr := Copy(DateString,4,2);
  122.     Date.Day := StrToInt(tempstr,10,Code);
  123.     tempstr := Copy(DateString,7,2);
  124.     Date.Year := StrToInt(tempstr,10,Code);
  125.     If Date.Year < 20 Then Date.Year := Date.Year + 1980;
  126.     tempstr := Copy(TimeString,1,2);
  127.     Date.Hour := StrToInt(tempstr,10,Code);
  128.     tempstr := Copy(TimeString,4,2);
  129.     Date.Min := StrToInt(tempstr,10,Code);
  130.     tempstr := Copy(TimeString,7,2);
  131.     Date.Sec := StrToInt(tempstr,10,Code);
  132.     PackTime(Date,PackedTime);
  133.     GetPackedTime := PackedTime;
  134.   End;
  135. {========================================================================}
  136. Procedure BlankCurrentLocation;
  137.   Begin
  138.     AnsiGotoXY(Row,1);
  139.     If CurrentEntry^.Tagged Then
  140.     Begin
  141.       NewTextColor(White); Write('∙');
  142.     End
  143.     Else
  144.     Begin
  145.       NewTextColor(White); Write(' ');
  146.     End;
  147.     AnsiGotoXY(24,80);
  148.   End;
  149. {========================================================================}
  150. Procedure DisplayCurrentLocation;
  151.   Begin
  152.     AnsiGotoXY(Row,1);
  153.     If CurrentEntry^.Tagged Then
  154.     Begin
  155.       NewTextColor(White+Blink); Write('»'); NewTextColor(White);
  156.     End
  157.     Else
  158.     Begin
  159.       NewTextColor(White+Blink); Write('>'); NewTextColor(White);
  160.     End;
  161.     AnsiGotoXY(24,80);
  162.   End;
  163. {========================================================================}
  164. Procedure DisplayRecord(Row : Byte);
  165.   Begin
  166.     AnsiGotoXY(Row,1); AnsiClearToEOL;
  167.     NewTextColor(White);
  168.     If NextPrintEntry^.Tagged Then Write('∙');
  169.     AnsiGotoXY(Row,2);
  170.     Case NextPrintEntry^.TypeOfRecord Of
  171.       Comment :
  172.       Begin
  173.         NewTextColor(White);
  174.         Write(NextPrintEntry^.Description);
  175.       End;
  176.       FileRecord :
  177.       Begin
  178.         NewTextColor(Yellow);
  179.         Write(Copy(nextprintentry^.filename+'            ',1,12));
  180.         NewTextColor(Magenta);
  181.         Write(NextPrintEntry^.FileSize:8);
  182.         NewTextColor(Green);
  183.         Write(' ' + GetDateString(NextPrintEntry^.FileDate)  + '  ');
  184.         NewTextColor(Cyan);
  185.         Write(Copy(NextPrintEntry^.Description,1,48));
  186.       End;
  187.       Orphan :
  188.       Begin
  189.         NewTextColor(Yellow);
  190.         Write(Copy(NextPrintEntry^.FileName+'            ',1,12));
  191.         NewTextColor(Magenta);
  192.         Write(NextPrintEntry^.FileSize:8);
  193.         NewTextColor(Green);
  194.         Write(' ' + GetDateString(NextPrintEntry^.FileDate)  + '  ');
  195.         NewTextColor(Red);
  196.         Write('Orphan');
  197.       End;
  198.       Offline :
  199.       Begin
  200.         NewTextColor(Yellow);
  201.         Write(Copy(NextPrintEntry^.FileName+'            ',1,12));
  202.         NewTextColor(Red);
  203.         Write(' offline           ');
  204.         NewTextColor(Cyan);
  205.         Write(Copy(NextPrintEntry^.Description,1,48));
  206.       End;
  207.       Else    End;
  208.   End;
  209. {========================================================================}
  210. Procedure DisplayScreen;
  211.   Var
  212.     Dsb : Byte;
  213.   Begin
  214.     NextPrintEntry := TopEntry;
  215.     Dsb := 1;
  216.     While (Dsb < 23) And (NextPrintEntry^.NextEntry <> NIL) Do
  217.     Begin
  218.       DisplayRecord(Dsb);
  219.       NextPrintEntry := NextPrintEntry^.NextEntry; Dsb:=Dsb+1;
  220.     End;
  221.     DisplayRecord(Dsb);
  222.     DisplayCurrentLocation;
  223.     If Dsb < 23 Then
  224.     Begin
  225.       Repeat
  226.         Dsb:=Dsb+1;
  227.         AnsiGotoXY(Dsb,1); AnsiClearToEOL;
  228.       Until Dsb = 23;
  229.     End;
  230.     AnsiGotoXY(24,80);
  231.   End;
  232. {========================================================================}
  233. Procedure LineUp;
  234.   Begin
  235.     If CurrentEntry^.PrevEntry <> NIL Then
  236.     Begin
  237.       If Row > 1 Then
  238.       Begin
  239.         BlankCurrentLocation;
  240.         Row:=Row-1; CurrentEntry := CurrentEntry^.PrevEntry;
  241.         DisplayCurrentLocation;
  242.       End
  243.       Else
  244.       Begin
  245.         CurrentEntry := CurrentEntry^.PrevEntry;
  246.         TopEntry := CurrentEntry;
  247.         DisplayScreen;
  248.       End;
  249.     End;
  250.   End;
  251. {========================================================================}
  252. Procedure LineDown;
  253.   Begin
  254.     If CurrentEntry^.NextEntry <> NIL Then
  255.     Begin
  256.       If Row <= 22 Then
  257.       Begin
  258.         BlankCurrentLocation;
  259.         Row:=Row+1; CurrentEntry := CurrentEntry^.NextEntry;
  260.         DisplayCurrentLocation;
  261.       End
  262.       Else
  263.       Begin
  264.         CurrentEntry := CurrentEntry^.NextEntry;
  265.         TopEntry := TopEntry^.NextEntry;
  266.         DisplayScreen;
  267.       End;
  268.     End;
  269.   End;
  270. {========================================================================}
  271. Procedure PageUp;
  272.   Begin
  273.     If NumberOfEntries <= 23 Then
  274.     Begin
  275.       CurrentEntry := FirstEntry; Row := 1;
  276.       DisplayScreen;
  277.     End
  278.     Else
  279.     Begin
  280.       Counter := 1;
  281.       While (Counter < 23) And (TopEntry^.PrevEntry <> NIL) Do
  282.       Begin
  283.         Counter:=Counter+1; TopEntry := TopEntry^.PrevEntry;
  284.       End;
  285.       While (Counter > 1) And (CurrentEntry^.PrevEntry <> NIL) Do
  286.       Begin
  287.         Counter:=Counter-1; CurrentEntry := CurrentEntry^.PrevEntry;
  288.       End;
  289.       Row := Row - (Counter - 1);
  290.       DisplayScreen;
  291.     End;
  292.   End;
  293. {========================================================================}
  294. Procedure PageDown;
  295.   Begin
  296.     If NumberOfEntries <= 23 Then
  297.     Begin
  298.       CurrentEntry := LastEntry; Row := NumberOfEntries;
  299.       DisplayScreen;
  300.     End
  301.     Else
  302.     Begin
  303.       Counter := 1;
  304.       While (Counter < 23) And (TopEntry^.NextEntry <> NIL) Do
  305.       Begin
  306.         Counter:=Counter+1; TopEntry := TopEntry^.NextEntry;
  307.       End;
  308.       While (Counter > 1) And (CurrentEntry^.NextEntry <> NIL) Do
  309.       Begin
  310.         Counter:=Counter-1; CurrentEntry := CurrentEntry^.NextEntry;
  311.       End;
  312.       Row := Row - (Counter - 1);
  313.       DisplayScreen;
  314.     End;
  315.   End;
  316. {========================================================================}
  317. Procedure TopOfList;
  318.   Begin
  319.     CurrentEntry := FirstEntry; TopEntry := FirstEntry; Row := 1;
  320.     DisplayScreen;
  321.   End;
  322. {========================================================================}
  323. Procedure BottomOfList;
  324.   Begin
  325.     If NumberOfEntries <= 23 Then
  326.     Begin
  327.       CurrentEntry := LastEntry;
  328.       Row := NumberOfEntries;
  329.       DisplayScreen;
  330.     End
  331.     Else
  332.     Begin
  333.       CurrentEntry := LastEntry; TopEntry := LastEntry;
  334.       Row := 23;
  335.       Repeat
  336.         TopEntry := TopEntry^.PrevEntry;
  337.         Row:=Row-1;
  338.       Until Row = 1;
  339.       Row := 23;
  340.       DisplayScreen;
  341.     End;
  342.   End;
  343. {========================================================================}
  344.  
  345.  
  346. {========================================================================}
  347. Function OkToAdd(InString : MAXSTRING) : Boolean;
  348.   Var
  349.     Otab : Byte;
  350.   Begin
  351.     If (MaxAvail > Size(ListRecord)) Then
  352.     Begin
  353.       OkToAdd := True;
  354.       For Otab := 1 To 10 Do If Pos(SkipList[Otab],UpperString(InString)) = 1 Then OkToAdd := False;
  355.     End
  356.     Else
  357.     Begin
  358.       OkToAdd := False;
  359.     End;
  360.   End;
  361. {========================================================================}
  362. Function CommentEntry : Boolean;
  363.   Begin
  364.     CommentEntry := False;
  365.     If Length(WorkString) = 0 Then CommentEntry := True;
  366.     If Copy(WorkString,1,1) = ' ' Then CommentEntry := True;
  367.     If Copy(WorkString,1,1) = '-' Then CommentEntry := True;
  368.     If Pos(WorkString[1],Base153) = 0 Then CommentEntry := True;
  369.   End;
  370. {========================================================================}
  371. Procedure FindOrphans;
  372.   Var
  373.     FileFound : Boolean;
  374.     SearchEntry : ListPtr;
  375.   Begin
  376.     FileFound := False; SearchEntry := FirstEntry;
  377.     If FilesBbs Then
  378.     Begin
  379.       While (Not FileFound) And (SearchEntry^.NextEntry <> NIL) Do
  380.       Begin
  381.         tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  382.         If tfname = SearchEntry^.FileName Then FileFound := True;
  383.         SearchEntry := SearchEntry^.NextEntry;
  384.       End;
  385.     End;
  386.     If FilesBbs Then
  387.     Begin
  388.       tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  389.       If (Not FileFound) And (tfname <> SearchEntry^.FileName) Then
  390.       Begin
  391.         tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  392.         If OkToAdd(tfname) Then
  393.         Begin
  394.           New(NewEntry);
  395.           If NumberOfEntries = 0 Then
  396.           Begin
  397.             FirstEntry := NewEntry;
  398.             NewEntry^.PrevEntry := NIL;
  399.             OldEntry := FirstEntry;
  400.           End
  401.           Else
  402.           Begin
  403.             NewEntry^.PrevEntry := OldEntry;
  404.             OldEntry^.NextEntry := NewEntry;
  405.             OldEntry := NewEntry;
  406.           End;
  407.           NewEntry^.TypeOfRecord := Orphan;
  408.           tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  409.           NewEntry^.FileName := tfname;
  410.           NewEntry^.FileSize := DirInfo.fileSize;
  411.           If tfname <> 'FILES.BBS' Then
  412.           Begin
  413.             SizeOfFiles := SizeOfFiles + DirInfo.fileSize;
  414.             NumberOfFiles:=NumberOfFiles+1;
  415.           End;
  416.           NewEntry^.FileDate := DirInfo.fdatelastwrite;
  417.           NewEntry^.FileDate := NewEntry^.FileDate << 16;
  418.           NewEntry^.FileDate := NewEntry^.FileDate + DirInfo.ftimelastwrite;
  419.           NewEntry^.Description := '';
  420.           NewEntry^.Tagged := False;
  421.           NumberOfEntries:=NumberOfEntries+1;
  422.         End;
  423.       End;
  424.     End
  425.     Else
  426.     Begin
  427.       If Not FileFound Then
  428.       Begin
  429.         If MaxAvail > Size(ListRecord) Then
  430.         Begin
  431.           New(NewEntry);
  432.           NewEntry^.Tagged := False;
  433.           If NumberOfEntries = 0 Then
  434.           Begin
  435.             FirstEntry := NewEntry;
  436.             NewEntry^.PrevEntry := NIL;
  437.             OldEntry := FirstEntry;
  438.           End
  439.           Else
  440.           Begin
  441.             NewEntry^.PrevEntry := OldEntry;
  442.             OldEntry^.NextEntry := NewEntry;
  443.             OldEntry := NewEntry;
  444.           End;
  445.           NewEntry^.TypeOfRecord := Orphan;
  446.           tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  447.           NewEntry^.FileName := tfname;
  448.           NewEntry^.FileSize := DirInfo.fileSize;
  449.           If tfname <> 'FILES.BBS' Then
  450.           Begin
  451.             SizeOfFiles := SizeOfFiles + DirInfo.fileSize;
  452.             NumberOfFiles:=NumberOfFiles+1;
  453.           End;
  454.           NewEntry^.FileDate := DirInfo.fdatelastwrite;
  455.           NewEntry^.FileDate := NewEntry^.FileDate << 16;
  456.           NewEntry^.FileDate := NewEntry^.FileDate + DirInfo.ftimelastwrite;
  457.           NewEntry^.Description := '';
  458.           NumberOfEntries:=NumberOfEntries+1;
  459.         End;
  460.       End;
  461.     End;
  462.   End;
  463. {========================================================================}
  464. Procedure BuildList;
  465.   Begin
  466.     NumberOfEntries := 0;
  467.     FilesBbs := True;
  468.     Altered := False;
  469.     SizeOfFiles := 0;
  470.     NumberOfFiles := 0;
  471.     Assign(FileList,FileAreaPath+'FILES.BBS');
  472.     FileMode := 0H;
  473.     {$I-}
  474.     IOcheck := FALSE;
  475.     Reset(FileList);
  476.     {$I+}
  477.     IOcheck :=TRUE;
  478.     If IOresult = 0 Then
  479.     Begin
  480.       AnsiGotoXY(25,1);
  481.       NewTextColor(White);
  482.       NewTextBackground(Black);
  483.       AnsiClearToEOL; Write('Loading FILES.BBS ...');
  484.       While Not Eof(FileList) Do
  485.       Begin
  486.         ReadLn(FileList,WorkString);
  487.         If OkToAdd(WorkString) Then
  488.         Begin
  489.           NumberOfEntries:=NumberOfEntries+1;
  490.           If CommentEntry Then
  491.           Begin
  492.             New(NewEntry);
  493.             NewEntry^.TypeOfRecord := Comment;
  494.             NewEntry^.FileName := '';
  495.             NewEntry^.FileSize := 0;
  496.             NewEntry^.FileDate := 0;
  497.             NewEntry^.Description := WorkString;
  498.             NewEntry^.Tagged := False;
  499.             If NumberOfEntries = 1 Then
  500.             Begin
  501.               FirstEntry := NewEntry;
  502.               NewEntry^.PrevEntry := NIL;
  503.               OldEntry := FirstEntry;
  504.             End
  505.             Else
  506.             Begin
  507.               NewEntry^.PrevEntry := OldEntry;
  508.               OldEntry^.NextEntry := NewEntry;
  509.               OldEntry := NewEntry;
  510.             End;
  511.           End
  512.           Else
  513.           Begin
  514.             New(NewEntry);
  515.             NewEntry^.Tagged := False;
  516.             If NumberOfEntries = 1 Then
  517.             Begin
  518.               FirstEntry := NewEntry;
  519.               NewEntry^.PrevEntry := NIL;
  520.               OldEntry := FirstEntry;
  521.             End
  522.             Else
  523.             Begin
  524.               NewEntry^.PrevEntry := OldEntry;
  525.               OldEntry^.NextEntry := NewEntry;
  526.               OldEntry := NewEntry;
  527.             End;
  528.             If Pos(' ',WorkString) = 0 Then
  529.             Begin
  530.               NewEntry^.FileName := UpperString(WorkString);
  531.             End
  532.             Else
  533.             Begin
  534.               NewEntry^.FileName := UpperString(Copy(
  535.                 Copy(WorkString,1,Pos(' ',WorkString)-1)
  536.                 ,1,12));
  537.             End;
  538.             attr := 0H;
  539.             hndlhdir := HDIR_CREATE;
  540.             count := 1;
  541.             reslng := size(FILEFINDBUF);
  542.             StrToZ(FileAreaPath+NewEntry^.FileName,ztempstr);
  543.             retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  544.               reslng,count,rsrvd);
  545.             If retn = 0 Then
  546.             Begin
  547.               NewEntry^.TypeOfRecord := FileRecord;
  548.               NewEntry^.FileSize := DirInfo.fileSize;
  549.               SizeOfFiles := SizeOfFiles + DirInfo.fileSize;
  550.               NumberOfFiles:=NumberOfFiles+1;
  551.               NewEntry^.FileDate := DirInfo.fdatelastwrite;
  552.               NewEntry^.FileDate := NewEntry^.FileDate << 16;
  553.               NewEntry^.FileDate := NewEntry^.FileDate + DirInfo.ftimelastwrite;
  554.               If Pos(' ',WorkString) = 0 Then
  555.               Begin
  556.                 NewEntry^.Description := '';
  557.               End
  558.               Else
  559.               Begin
  560.                 NewEntry^.Description := LtrimRtrim(Copy(WorkString,Pos(' ',WorkString)+1,144));
  561.               End;
  562.             End
  563.             Else
  564.             Begin
  565.               NewEntry^.TypeOfRecord := Offline;
  566.               NewEntry^.FileSize := 0;
  567.               NewEntry^.FileDate := 0;
  568.               If Pos(' ',WorkString) = 0 Then
  569.               Begin
  570.                 NewEntry^.Description := '';
  571.               End
  572.               Else
  573.               Begin
  574.                 NewEntry^.Description := LtrimRtrim(Copy(WorkString,Pos(' ',WorkString)+1,144));
  575.               End;
  576.             End;
  577.           End;
  578.         End;
  579.       End;
  580.       Close(FileList);
  581.       NewEntry^.NextEntry := NIL;
  582.       If NumberOfEntries = 0 Then FilesBbs := False;
  583.     End
  584.     Else
  585.     Begin
  586.       FilesBbs := False;
  587.     End;
  588.     attr := 0H;
  589.     hndlhdir := HDIR_CREATE;
  590.     count := 1;
  591.     reslng := size(FILEFINDBUF);
  592.     StrToZ(FileAreaPath+'*.*',ztempstr);
  593.     retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  594.       reslng,count,rsrvd);
  595.     If retn = 0 Then FindOrphans;
  596.     While retn = 0 Do
  597.     Begin
  598.       NewEntry^.NextEntry := NIL;
  599.       retn := dos.FindNext(hndlhdir,DirInfo,reslng,count);
  600.       If retn = 0 Then FindOrphans;
  601.     End;
  602.     LastEntry := NewEntry;
  603.     LastEntry^.NextEntry := NIL;
  604.     StackEntry := NIL; KillEntry := NIL;
  605.     AnsiGotoXY(25,1); AnsiClearToEOL;
  606.   End;
  607. {========================================================================}
  608. Function Bytes(NumberOfBytes : Integer) : S8;
  609.   Var
  610.     TempString : S8;
  611.   Begin
  612.     If NumberOfBytes < 1024 Then
  613.     Begin
  614.       TempString := MyStr(NumberOfBytes,4)+'K';
  615.     End
  616.     Else
  617.     Begin
  618.       IntToStr(NumberOfBytes DIV 1024,TempString,10,OK);
  619. {      _STR_REAL_FIX(NumberOfBytes/1024,3,1,TempString); }
  620.       TempString := TempString+'M';
  621.     End;
  622.     Bytes := TempString;
  623.   End;
  624. {========================================================================}
  625. Procedure SetupScreen;
  626.   Begin
  627.     NewTextColor(White); NewTextBackground(Black);
  628.     AnsiClearScreen; AnsiGotoXY(24,1);
  629.     NewTextColor(Black); NewTextBackground(Cyan);
  630.     Write(Pgmid+' ^Q=quit ?=help');
  631.     NewTextColor(White); NewTextBackground(Black);
  632.   End;
  633. {========================================================================}
  634. Procedure ReDrawScreen;
  635.   Begin
  636.     SetupScreen; DisplayScreen;
  637.   End;
  638. {========================================================================}
  639.  
  640.  
  641. {========================================================================}
  642. Procedure Help;
  643.   Begin
  644.     AnsiClearScreen; NewTextColor(7);
  645.     AnsiGotoXY(1,1); Write(Pgmid); WriteLn;
  646.     WriteLn('╔═[Navagate through list]════════════════════════════════════════════════════╗');
  647.     Write('║');
  648.     NewTextColor(9);
  649.     Write('          7 : TopOfList       8 : LineUp             9 : PageUp             ');
  650.     NewTextColor(7);
  651.     WriteLn('║');
  652.     Write('║');
  653.     NewTextColor(9);
  654.     Write('          1 : BottomOfList    2 : LineDown           3 : PageDown           ');
  655.     NewTextColor(7);
  656.     WriteLn('║');
  657.     WriteLn('╠═[Add, Edit and Rename]═════════════════════════════════════════════════════╣');
  658.     Write('║');
  659.     NewTextColor(10);
  660.     Write(' A : Adopt/Abandon         E : Edit Description        I : Insert Blank     ');
  661.     NewTextColor(7);
  662.     WriteLn('║');
  663.     Write('║');
  664.     NewTextColor(10);
  665.     Write(' R : Rename File           D : Change File Date       ^A : Adopt ALL        ');
  666.     NewTextColor(7);
  667.     WriteLn('║');
  668.     WriteLn('╠═[Copy or Move between areas]═══════════════════════════════════════════════╣');
  669.     Write('║');
  670.     NewTextColor(11);
  671.     Write(' C : Copy to New Area      M : Move to New Area                             ');
  672.     NewTextColor(7);
  673.     WriteLn('║');
  674.     Write('║');
  675.     NewTextColor(11);
  676.     Write(' $ : Mass Copy             # : Mass Move          <SP> : Toggle Tag         ');
  677.     NewTextColor(7);
  678.     WriteLn('║');
  679.     WriteLn('╠═[Move or Remove entries in list]═══════════════════════════════════════════╣');
  680.     Write('║');
  681.     NewTextColor(12);
  682.     Write(' < : Push Record     > : Pop Record   K : Kill Entry      U : UnKill Entry  ');
  683.     NewTextColor(7);
  684.     WriteLn('║');
  685.     Write('║');
  686.     NewTextColor(12);
  687.     Write(' [ : Stack Prev      ] : Stack Next   { : Prev Kill       } : Next Kill     ');
  688.     NewTextColor(7);
  689.     WriteLn('║');
  690.     Write('║');
  691.     NewTextColor(12);
  692.     Write(' ; : Show Stack                       : : Show Kill                         ');
  693.     NewTextColor(7);
  694.     WriteLn('║');
  695.     WriteLn('╠═[Sort list]════════════════════════════════════════════════════════════════╣');
  696.     Write('║');
  697.     NewTextColor(13);
  698.     Write(' F : Mark First   L : Mark Last   S : Sort by Name   T : Sort by Time       ');
  699.     NewTextColor(7);
  700.     WriteLn('║');
  701.     WriteLn('╠═[Search for string]════════════════════════════════════════════════════════╣');
  702.     Write('║');
  703.     NewTextColor(14);
  704.     Write(' ^F : In File Name       ^D : In Description         ^B : In Both           ');
  705.     NewTextColor(7);
  706.     WriteLn('║');
  707.     WriteLn('╠═[View]═[All Unavailable!!]═════════════════════════════════════════════════╣');
  708.     Write('║');
  709.     NewTextColor(9);
  710.     Write(' ALT-V : View File   ALT-F : Force SHEZ View    ALT-L : Force LIST View     ');
  711.     NewTextColor(7);
  712.     WriteLn('║');
  713.     WriteLn('╠═[Misc]════════════════════════════════════════════[Not Available]══════════╣');
  714.     Write('║');
  715.     NewTextColor(10);
  716.     Write(' N : New Area   W : Write List   ! : ReDraw Screen    ALT-S : Shell to DOS  ');
  717.     NewTextColor(7);
  718.     WriteLn('║');
  719.     WriteLn('╚════════════════════════════════════════════════════════════════════════════╝');
  720.     AnsiGotoXY(25,27);
  721.     NewTextColor(Blink+Red);
  722.     Write('Press any key to continue!');
  723.     NewTextColor(White);
  724.     AnsiGotoXY(1,80);
  725.     Gbx := GetInput;
  726.     ReDrawScreen;
  727.   End;
  728. {========================================================================}
  729. Procedure AreaHelp;
  730.   Begin
  731.     AnsiClearScreen; NewTextColor(7);
  732.     AnsiGotoXY(1,1); Write(Pgmid);
  733.     AnsiGotoXY(3,15); Write('7 : Upper Left      8 : Move Up            9 : Upper Right');
  734.     AnsiGotoXY(4,15); Write('4 : Move Left                              6 : Move Right');
  735.     AnsiGotoXY(5,15); Write('1 : Lower Left      2 : Move Down          3 : Lower Right');
  736.     AnsiGotoXY(7,15); Write('TAB : Add temporary path');
  737.     AnsiGotoXY(25,27);
  738.     NewTextColor(Blink+Red);
  739.     Write('Press any key to continue!');
  740.     NewTextColor(White);
  741.     AnsiGotoXY(1,80);
  742.     Gbx := GetInput;
  743.     SetupScreen;
  744.   End;
  745. {========================================================================}
  746.  
  747.  
  748. {========================================================================}
  749. Function EditLine(LineToEdit : MAXSTRING; MaxLength, Row, Col : Byte) : MAXSTRING;
  750.   Var
  751.     Elc : Char;
  752.     Elb : Byte;
  753.     OverWrite : Boolean;
  754.     CharacterPosition, OffSet : Byte;
  755.   Begin
  756.     CharacterPosition := 1; OverWrite := True; AnsiGotoXY(Row,1+Col);
  757.     OffSet := 0;
  758.     Repeat
  759.       Repeat
  760.         Elb := GetInput;
  761.         If Elb = 0 Then
  762.         Begin
  763.           Elb := GetInput;
  764.           Case Elb Of
  765.             71 : Elc := chr(23);
  766.             75 : Elc := chr(19);
  767.             77 : Elc := chr(4);
  768.             79 : Elc := chr(18);
  769.             82 : Elc := chr(22);
  770.             83 : Elc := chr(7);
  771.           Else
  772.             Elc := chr(0);
  773.           End;
  774.         End
  775.         Else
  776.         Begin
  777.           Elc := (Elb::Char);
  778.         End;
  779.       Until Elc In [chr(1),chr(3),chr(4),chr(6),chr(7),chr(8),chr(12),chr(13),chr(17),chr(18),chr(19),chr(21),chr(22),chr(23),' '..'~'];
  780.       Case Elc Of
  781.         chr(1) : Begin(* Move left to previous word *)
  782.                If CharacterPosition > 2 Then
  783.                Begin
  784.                  CharacterPosition:=CharacterPosition-1;
  785.                  While (LineToEdit[CharacterPosition] = ' ') And (CharacterPosition > 1) Do CharacterPosition:=CharacterPosition-1;
  786.                End;
  787.                While (LineToEdit[CharacterPosition] <> ' ') And (CharacterPosition > 1) Do CharacterPosition:=CharacterPosition-1;
  788.                If LineToEdit[CharacterPosition] = ' ' Then CharacterPosition:=CharacterPosition+1;
  789.                While (CharacterPosition-OffSet) < 1 Do OffSet:=OffSet-1;
  790.                AnsiGotoXY(Row,1+Col);
  791.                AnsiClearToEOL;
  792.                Write(Copy(LineToEdit,OffSet+1,79));
  793.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  794.              End;
  795.         chr(3) : Begin(* UpperCase first character *)
  796.                LineToEdit := CapFirst(LineToEdit);
  797.                AnsiGotoXY(Row,1+Col);
  798.                AnsiClearToEOL;
  799.                Write(Copy(LineToEdit,OffSet+1,79));
  800.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  801.              End;
  802.         chr(4) : Begin(* Move right one character *)
  803.                If CharacterPosition <= Length(LineToEdit) Then
  804.                Begin
  805.                  CharacterPosition:=CharacterPosition+1;
  806.                  If (CharacterPosition-(OffSet+1)) > 79 Then
  807.                  Begin
  808.                    OffSet:=OffSet+1;
  809.                    AnsiGotoXY(Row,1+Col);
  810.                    Write(Copy(LineToEdit,OffSet+1,79));
  811.                  End;
  812.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  813.                End;
  814.              End;
  815.         chr(6) : Begin(* Move right to next word *)
  816.                While (LineToEdit[CharacterPosition] <> ' ') And (CharacterPosition <= Length(LineToEdit)) Do
  817.                Begin
  818.                  CharacterPosition:=CharacterPosition+1;
  819.                End;
  820.                While (LineToEdit[CharacterPosition] = ' ') And (CharacterPosition <= Length(LineToEdit)) Do
  821.                Begin
  822.                  CharacterPosition:=CharacterPosition+1;
  823.                End;
  824.                AnsiGotoXY(Row,CharacterPosition+Col);
  825.                While (CharacterPosition-OffSet) > 79 Do OffSet:=OffSet+1;
  826.                AnsiGotoXY(Row,1+Col);
  827.                AnsiClearToEOL;
  828.                Write(Copy(LineToEdit,OffSet+1,79));
  829.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  830.              End;
  831.         chr(7) : Begin(* Delete character under cursor *)
  832.                If CharacterPosition <= Length(LineToEdit) Then
  833.                Begin
  834.                  Delete(LineToEdit,CharacterPosition,1);
  835.                  AnsiGotoXY(Row,1+Col);
  836.                  AnsiClearToEOL;
  837.                  Write(Copy(LineToEdit,OffSet+1,79));
  838.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  839.                End;
  840.              End;
  841.         chr(8) : Begin(* Delete character to left of cursor *)
  842.                If CharacterPosition > 1 Then
  843.                Begin
  844.                  CharacterPosition:=CharacterPosition-1;
  845.                  Delete(LineToEdit,CharacterPosition,1);
  846.                  AnsiGotoXY(Row,1+Col);
  847.                  AnsiClearToEOL;
  848.                  Write(Copy(LineToEdit,OffSet+1,79));
  849.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  850.                End;
  851.              End;
  852.         chr(12) : Begin(* LowerCase entire line *)
  853.                LineToEdit := LowerString(LineToEdit);
  854.                AnsiGotoXY(Row,1+Col);
  855.                AnsiClearToEOL;
  856.                Write(Copy(LineToEdit,OffSet+1,79));
  857.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  858.              End;
  859.         chr(18) : Begin(* Move to end of line *)
  860.                CharacterPosition := Length(LineToEdit)+1;
  861.                While Copy(LineToEdit,CharacterPosition,1) = ' ' Do Delete(LineToEdit,CharacterPosition,1);
  862.                If CharacterPosition > 79 Then
  863.                Begin
  864.                  OffSet := CharacterPosition-79;
  865.                End
  866.                Else
  867.                Begin
  868.                  OffSet := 0;
  869.                End;
  870.                If OffSet > 0 Then
  871.                Begin
  872.                  AnsiGotoXY(Row,1);
  873.                  Write(Copy(LineToEdit,OffSet+1,79)+' ');
  874.                End;
  875.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  876.              End;
  877.         chr(19) : Begin(* Move left one character *)
  878.                If CharacterPosition > 1 Then
  879.                Begin
  880.                  CharacterPosition:=CharacterPosition-1;
  881.                  If (CharacterPosition-OffSet) < 1 Then
  882.                  Begin
  883.                    OffSet:=OffSet-1;
  884.                    AnsiGotoXY(Row,1);
  885.                    Write(Copy(LineToEdit,OffSet+1,79));
  886.                  End;
  887.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  888.                End;
  889.              End;
  890.         chr(21) : Begin(* UpperCase entire line *)
  891.                LineToEdit := UpperString(LineToEdit);
  892.                AnsiGotoXY(Row,1+Col);
  893.                AnsiClearToEOL;
  894.                Write(Copy(LineToEdit,OffSet,79));
  895.                AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  896.              End;
  897.         chr(22) : Begin(* Toggle insert and overwrite *)
  898.                If OverWrite Then
  899.                Begin
  900.                  OverWrite := False;
  901.                  AnsiGotoXY(24,1);
  902.                  NewTextColor(Black);
  903.                  NewTextBackground(Cyan);
  904.                  Write('Insert   ');
  905.                  AnsiGotoXY(Row,1+Col);
  906.                  NewTextColor(White);
  907.                  NewTextBackground(Black);
  908.                  If CurrentEntry^.TypeOfRecord = Comment Then NewTextColor(White) Else NewTextColor(Cyan);
  909.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  910.                End
  911.                Else
  912.                Begin
  913.                  OverWrite := True;
  914.                  AnsiGotoXY(24,1);
  915.                  NewTextColor(Black);
  916.                  NewTextBackground(Cyan);
  917.                  Write('OverWrite');
  918.                  AnsiGotoXY(Row,1+Col);
  919.                  NewTextColor(White);
  920.                  NewTextBackground(Black);
  921.                  If CurrentEntry^.TypeOfRecord = Comment Then NewTextColor(White) Else NewTextColor(Cyan);
  922.                  AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  923.                End;
  924.              End;
  925.         chr(23) : Begin(* Move to begining of line *)
  926.                CharacterPosition := 1;
  927.                If OffSet > 0 Then
  928.                Begin
  929.                  OffSet := 0;
  930.                  AnsiGotoXY(Row,1);
  931.                  Write(Copy(LineToEdit,1,79));
  932.                End;
  933.                AnsiGotoXY(Row,CharacterPosition+Col);
  934.              End;
  935.       Else
  936.         If Elc <> chr(13) Then
  937.         Begin
  938.           If Elc = chr(17) Then
  939.           Begin
  940.             AnsiGotoXY(24,1);
  941.             NewTextColor(Black);
  942.             NewTextBackground(Cyan);
  943.             Write('Quoting  ');
  944.             AnsiGotoXY(Row,1+Col);
  945.             NewTextColor(White);
  946.             NewTextBackground(Black);
  947.             If CurrentEntry^.TypeOfRecord = Comment Then NewTextColor(White) Else NewTextColor(Cyan);
  948.             Elb := GetInput;
  949.             Elc := (Elb::Char);
  950.             AnsiGotoXY(24,1);
  951.             NewTextColor(Black);
  952.             NewTextBackground(Cyan);
  953.             If OverWrite Then Write('OverWrite') Else Write('Insert   ');
  954.             AnsiGotoXY(Row,1+Col);
  955.             NewTextColor(White);
  956.             NewTextBackground(Black);
  957.             If CurrentEntry^.TypeOfRecord = Comment Then NewTextColor(White) Else NewTextColor(Cyan);
  958.           End;
  959.           If OverWrite Then
  960.           Begin
  961.             If CharacterPosition <= Length(LineToEdit) Then
  962.             Begin
  963.               LineToEdit[CharacterPosition] := Elc;
  964.               AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  965.               If (CharacterPosition-(OffSet+1)) < 79 Then Write(Elc);
  966.               CharacterPosition:=CharacterPosition+1;
  967.               If (CharacterPosition-(OffSet+1)) > 79 Then
  968.               Begin
  969.                 OffSet:=OffSet+1;
  970.                 AnsiGotoXY(Row,1);
  971.                 Write(Copy(LineToEdit,OffSet+1,79));
  972.               End;
  973.               AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  974.             End
  975.             Else
  976.             Begin
  977.               If Length(LineToEdit) < MaxLength Then
  978.               Begin
  979.                 LineToEdit := LineToEdit + Elc;
  980.                 AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  981.                 If (CharacterPosition-(OffSet+1)) < 79 Then Write(Elc);
  982.                 CharacterPosition:=CharacterPosition+1;
  983.                 If (CharacterPosition-(OffSet+1)) > 79 Then
  984.                 Begin
  985.                   OffSet:=OffSet+1;
  986.                   AnsiGotoXY(Row,1);
  987.                   Write(Copy(LineToEdit,OffSet+1,79));
  988.                 End;
  989.                 AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  990.               End;
  991.             End;
  992.           End
  993.           Else
  994.           Begin
  995.             If Length(LineToEdit) < MaxLength Then
  996.             Begin
  997.               LineToEdit := Copy(LineToEdit,1,CharacterPosition-1)+Elc+Copy(LineToEdit,CharacterPosition,Length(LineToEdit));
  998.               AnsiGotoXY(Row,1+Col); Write(Copy(LineToEdit,OffSet+1,79)); CharacterPosition:=CharacterPosition+1;
  999.               AnsiGotoXY(Row,(CharacterPosition+Col)-OffSet);
  1000.             End;
  1001.           End;
  1002.         End;
  1003.       End;
  1004.     Until Elc = chr(13);
  1005.     EditLine := LineToEdit;
  1006.   End;
  1007. {========================================================================}
  1008. Procedure EditDescriptionLine;
  1009.   Var
  1010.     MaxLength : Byte;
  1011.   Begin
  1012.     If CurrentEntry^.TypeOfRecord = Comment Then MaxLength := 79 Else MaxLength := 141;
  1013.     CurrentEntry^.Description := EditLine(CurrentEntry^.Description,MaxLength,25,0);
  1014.   End;
  1015. {========================================================================}
  1016. Procedure EditDescription;
  1017.   Var
  1018.     edc : Char;
  1019.   Begin
  1020.     If CurrentEntry^.TypeOfRecord <> Orphan Then
  1021.     Begin
  1022.       Altered := True;
  1023.       AnsiGotoXY(24,1); NewTextColor(Black); NewTextBackground(Cyan);
  1024.       Write('OverWrite  ^w/^a/^s Left  ^d/^f/^r Right  ^h/^g Del ^v Toggle Insert            ');
  1025.       AnsiGotoXY(25,1); NewTextBackground(Black);
  1026.       If CurrentEntry^.TypeOfRecord = Comment Then NewTextColor(White) Else NewTextColor(Cyan);
  1027.       AnsiClearToEOL; Write(Copy(CurrentEntry^.Description,1,79));
  1028.       EditDescriptionLine;
  1029.       AnsiGotoXY(25,1); AnsiClearToEOL;
  1030.       If CurrentEntry^.TypeOfRecord = Comment Then
  1031.       Begin
  1032.         NewTextColor(White);
  1033.         AnsiGotoXY(Row,2); AnsiClearToEOL;
  1034.         Write(CurrentEntry^.Description);
  1035.       End
  1036.       Else
  1037.       Begin
  1038.         NewTextColor(Cyan);
  1039.         AnsiGotoXY(Row,33); AnsiClearToEOL;
  1040.         Write(Copy(CurrentEntry^.Description,1,48));
  1041.       End;
  1042.       AnsiGotoXY(24,1);
  1043.       NewTextColor(Black);
  1044.       NewTextBackground(Cyan);
  1045.       Write(Pgmid+' ^Q=quit ?=help');
  1046.       NewTextColor(White);
  1047.       NewTextBackground(Black);
  1048.       AnsiGotoXY(24,80);
  1049.     End;
  1050.   End;
  1051. {========================================================================}
  1052.  
  1053.  
  1054. {========================================================================}
  1055. Procedure AdoptAbandon(Display : Byte);
  1056.   Begin
  1057.     Altered := True;
  1058.     Case CurrentEntry^.TypeOfRecord Of
  1059.       Orphan :
  1060.       Begin
  1061.         CurrentEntry^.TypeOfRecord := FileRecord;
  1062.         NextPrintEntry := CurrentEntry;
  1063.         If Display = 1 Then
  1064.         Begin
  1065.           DisplayRecord(Row); DisplayCurrentLocation;
  1066.         End;
  1067.       End;
  1068.       FileRecord :
  1069.       Begin
  1070.         CurrentEntry^.TypeOfRecord := Orphan;
  1071.         NextPrintEntry := CurrentEntry;
  1072.         DisplayRecord(Row); DisplayCurrentLocation;
  1073.       End;
  1074.       Comment :
  1075.       Begin
  1076.         CurrentEntry^.TypeOfRecord := Offline;
  1077.         CurrentEntry^.Description := LtrimRtrim(CurrentEntry^.Description);
  1078.         CurrentEntry^.FileName :=
  1079.           Copy(CurrentEntry^.Description,1,
  1080.           Pos(' ',CurrentEntry^.Description)-1);
  1081.         CurrentEntry^.Description := Copy(CurrentEntry^.Description,Pos(' ',CurrentEntry^.Description)+1,79);
  1082.         NextPrintEntry := CurrentEntry;
  1083.         DisplayRecord(Row); DisplayCurrentLocation;
  1084.       End;
  1085.       Offline :
  1086.       Begin
  1087.         CurrentEntry^.TypeOfRecord := Comment;
  1088.         CurrentEntry^.Description :=
  1089.           CurrentEntry^.FileName+' '+CurrentEntry^.Description;
  1090.         CurrentEntry^.FileName := '';
  1091.         NextPrintEntry := CurrentEntry;
  1092.         DisplayRecord(Row); DisplayCurrentLocation;
  1093.       End;
  1094.       Else    End;
  1095.   End;
  1096. {========================================================================}
  1097. Procedure AdoptAllOrphans;
  1098.   Begin
  1099.     OldEntry := CurrentEntry;
  1100.     CurrentEntry := FirstEntry;
  1101.     Repeat
  1102.       If (CurrentEntry^.FileName <> 'FILES.BBS') And
  1103.          (CurrentEntry^.FileName <> 'FILES.BAK') And
  1104.          (CurrentEntry^.TypeOfRecord = Orphan) Then AdoptAbandon(0);
  1105.       CurrentEntry := CurrentEntry^.NextEntry;
  1106.     Until CurrentEntry = NIL;
  1107.     CurrentEntry := OldEntry;
  1108.     DisplayScreen;
  1109.   End;
  1110. {========================================================================}
  1111. Procedure InsertBlank;
  1112.   Begin
  1113.     If MaxAvail > Size(ListRecord) Then
  1114.     Begin
  1115.       Altered := True;
  1116.       New(NewEntry);
  1117.       NewEntry^.PrevEntry := CurrentEntry^.PrevEntry;
  1118.       NewEntry^.NextEntry := CurrentEntry;
  1119.       CurrentEntry^.PrevEntry^.NextEntry := NewEntry;
  1120.       CurrentEntry^.PrevEntry := NewEntry;
  1121.       If CurrentEntry = TopEntry Then TopEntry := NewEntry;
  1122.       If CurrentEntry = FirstEntry Then FirstEntry := NewEntry;
  1123.       CurrentEntry := NewEntry;
  1124.       CurrentEntry^.TypeOfRecord := Comment;
  1125.       CurrentEntry^.Description := ' ';
  1126.       CurrentEntry^.Tagged := False;
  1127.       NumberOfEntries:=NumberOfEntries+1;
  1128.       DisplayScreen;
  1129.     End;
  1130.   End;
  1131. {========================================================================}
  1132.  
  1133.  
  1134. {========================================================================}
  1135. Procedure PushRecord(Var TempEntry : ListPtr);
  1136.   Begin
  1137.     If (CurrentEntry^.PrevEntry <> NIL) Or (CurrentEntry^.NextEntry <> NIL) Then
  1138.     Begin
  1139.       If CurrentEntry^.FileName <> 'FILES.BBS' Then
  1140.       Begin
  1141.         If CurrentEntry^.TypeOfRecord In [Orphan,FileRecord] Then NumberOfFiles:=NumberOfFiles-1;
  1142.         SizeOfFiles := SizeOfFiles-CurrentEntry^.FileSize;
  1143.       End;
  1144.       Altered := True;
  1145.       OldEntry := CurrentEntry;
  1146.       If CurrentEntry^.PrevEntry = NIL Then
  1147.       Begin
  1148.         CurrentEntry^.NextEntry^.PrevEntry := NIL;
  1149.         CurrentEntry := CurrentEntry^.NextEntry;
  1150.         TopEntry := CurrentEntry;
  1151.         FirstEntry := CurrentEntry;
  1152.       End
  1153.       Else
  1154.       Begin
  1155.         If CurrentEntry^.NextEntry = NIL Then
  1156.         Begin
  1157.           CurrentEntry^.PrevEntry^.NextEntry := NIL;
  1158.           CurrentEntry := CurrentEntry^.PrevEntry;
  1159.           LastEntry := CurrentEntry;
  1160.           If TopEntry^.PrevEntry <> NIL Then
  1161.           Begin
  1162.             TopEntry := TopEntry^.PrevEntry;
  1163.           End
  1164.           Else
  1165.           Begin
  1166.             Row:=Row-1;
  1167.           End;
  1168.         End
  1169.         Else
  1170.         Begin
  1171.           CurrentEntry^.PrevEntry^.NextEntry := CurrentEntry^.NextEntry;
  1172.           CurrentEntry^.NextEntry^.PrevEntry := CurrentEntry^.PrevEntry;
  1173.           CurrentEntry := CurrentEntry^.NextEntry;
  1174.           If TopEntry = OldEntry Then TopEntry := CurrentEntry;
  1175.         End;
  1176.       End;
  1177.       If TempEntry = NIL Then
  1178.       Begin
  1179.         TempEntry := OldEntry;
  1180.         TempEntry^.PrevEntry := TempEntry;
  1181.         TempEntry^.NextEntry := TempEntry;
  1182.       End
  1183.       Else
  1184.       Begin
  1185.         If TempEntry^.PrevEntry = TempEntry Then
  1186.         Begin
  1187.           OldEntry^.PrevEntry := TempEntry;
  1188.           OldEntry^.NextEntry := TempEntry;
  1189.           TempEntry^.PrevEntry := OldEntry;
  1190.           TempEntry^.NextEntry := OldEntry;
  1191.           TempEntry := OldEntry;
  1192.         End
  1193.         Else
  1194.         Begin
  1195.           OldEntry^.PrevEntry := TempEntry;
  1196.           OldEntry^.NextEntry := TempEntry^.NextEntry;
  1197.           TempEntry^.NextEntry^.PrevEntry := OldEntry;
  1198.           TempEntry^.NextEntry := OldEntry;
  1199.           TempEntry := OldEntry;
  1200.         End;
  1201.       End;
  1202.       NumberOfEntries:=NumberOfEntries-1;
  1203.       DisplayScreen;
  1204.     End;
  1205.   End;
  1206. {========================================================================}
  1207. Procedure PopRecord(Var TempEntry : ListPtr; BeforeOrAfter : Char);
  1208.   Begin
  1209.     If TempEntry <> NIL Then
  1210.     Begin
  1211.       If TempEntry^.FileName <> 'FILES.BBS' Then
  1212.       Begin
  1213.         If TempEntry^.TypeOfRecord In [Orphan,FileRecord] Then NumberOfFiles:=NumberOfFiles+1;
  1214.         SizeOfFiles := SizeOfFiles+TempEntry^.FileSize;
  1215.       End;
  1216.       OldEntry := TempEntry;
  1217.       If TempEntry^.PrevEntry = TempEntry Then
  1218.       Begin
  1219.         TempEntry := NIL;
  1220.       End
  1221.       Else
  1222.       Begin
  1223.         TempEntry^.PrevEntry^.NextEntry := TempEntry^.NextEntry;
  1224.         TempEntry^.NextEntry^.PrevEntry := TempEntry^.PrevEntry;
  1225.         TempEntry := TempEntry^.PrevEntry;
  1226.       End;
  1227.       If BeforeOrAfter = 'B' Then
  1228.       Begin
  1229.         If CurrentEntry^.PrevEntry = NIL Then
  1230.         Begin
  1231.           OldEntry^.PrevEntry := CurrentEntry^.PrevEntry;
  1232.           OldEntry^.NextEntry := CurrentEntry;
  1233.           CurrentEntry^.PrevEntry := OldEntry;
  1234.           CurrentEntry := OldEntry;
  1235.           TopEntry := CurrentEntry;
  1236.           FirstEntry := CurrentEntry;
  1237.         End
  1238.         Else
  1239.         Begin
  1240.           OldEntry^.PrevEntry := CurrentEntry^.PrevEntry;
  1241.           OldEntry^.NextEntry := CurrentEntry;
  1242.           CurrentEntry^.PrevEntry^.NextEntry := OldEntry;
  1243.           CurrentEntry^.PrevEntry := OldEntry;
  1244.           CurrentEntry := OldEntry;
  1245.         End;
  1246.       End
  1247.       Else
  1248.       Begin
  1249.         If CurrentEntry^.NextEntry = NIL Then
  1250.         Begin
  1251.           OldEntry^.NextEntry := CurrentEntry^.NextEntry;
  1252.           OldEntry^.PrevEntry := CurrentEntry;
  1253.           CurrentEntry^.NextEntry := OldEntry;
  1254.         End
  1255.         Else
  1256.         Begin
  1257.           OldEntry^.NextEntry := CurrentEntry^.NextEntry;
  1258.           OldEntry^.PrevEntry := CurrentEntry;
  1259.           CurrentEntry^.NextEntry^.PrevEntry := OldEntry;
  1260.           CurrentEntry^.NextEntry := OldEntry;
  1261.         End;
  1262.       End;
  1263.       NumberOfEntries:=NumberOfEntries+1;
  1264.       DisplayScreen;
  1265.     End;
  1266.   End;
  1267. {========================================================================}
  1268. Procedure ShowStack(Var TempEntry : ListPtr);
  1269.   Begin
  1270.     If TempEntry <> NIL Then
  1271.     Begin
  1272.       NextPrintEntry := TempEntry;
  1273.       DisplayRecord(25);
  1274.       AnsiGotoXY(24,80);
  1275.     End;
  1276.   End;
  1277. {========================================================================}
  1278. Procedure StackPrev(Var TempEntry : ListPtr);
  1279.   Begin
  1280.     If TempEntry <> NIL Then
  1281.     Begin
  1282.       TempEntry := TempEntry^.PrevEntry;
  1283.       ShowStack(TempEntry);
  1284.     End;
  1285.   End;
  1286. {========================================================================}
  1287. Procedure StackNext(Var TempEntry : ListPtr);
  1288.   Begin
  1289.     If TempEntry <> NIL Then
  1290.     Begin
  1291.       TempEntry := TempEntry^.NextEntry;
  1292.       ShowStack(TempEntry);
  1293.     End;
  1294.   End;
  1295. {========================================================================}
  1296.  
  1297.  
  1298. {========================================================================}
  1299. Function SizeOfFilesBbs(FileArea : MAXSTRING) : Integer;
  1300.   Var
  1301.     FilesBbs : File Of Byte;
  1302.     SizeOfFile : Integer;
  1303.   Begin
  1304.     Assign(FilesBbs,FileArea+'FILES.BBS');
  1305.     {$I-}
  1306.     IOcheck := FALSE;
  1307.     Reset(FilesBbs);
  1308.     {$I+}
  1309.     IOcheck := TRUE;
  1310.     If IOresult = 0 Then
  1311.     Begin
  1312.       SizeOfFilesBbs := FileSize(FilesBbs);
  1313.       Close(FilesBbs);
  1314.     End
  1315.     Else
  1316.     Begin
  1317.       SizeOfFilesBbs := 0;
  1318.     End;
  1319.   End;
  1320. {========================================================================}
  1321. Function InMainList(TempEntry : ListPtr) : Boolean;
  1322.   Begin
  1323.     NextPrintEntry := FirstEntry; InMainList := False;
  1324.     While NextPrintEntry^.NextEntry <> NIL Do
  1325.     Begin
  1326.       If NextPrintEntry^.FileName = TempEntry^.FileName Then InMainList := True;
  1327.       NextPrintEntry := NextPrintEntry^.NextEntry;
  1328.     End;
  1329.   End;
  1330. {========================================================================}
  1331. Procedure EraseKillList;
  1332.   Var
  1333.     FileToErase : FILE OF char;
  1334.   Begin
  1335.     While KillEntry <> NIL Do
  1336.     Begin
  1337.       attr := 0H;
  1338.       hndlhdir := HDIR_CREATE;
  1339.       count := 1;
  1340.       reslng := size(FILEFINDBUF);
  1341.       StrToZ(FileAreaPath+KillEntry^.FileName,ztempstr);
  1342.       retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1343.         reslng,count,rsrvd);
  1344.       If retn = 0 Then
  1345.       Begin
  1346.         If (Not InMainList(KillEntry)) Then
  1347.         Begin
  1348.           If UpperString(KillEntry^.FileName) <> 'FILES.BBS' Then
  1349.           Begin
  1350.             Assign(FileToErase,FileAreaPath+KillEntry^.FileName);
  1351.             Erase(FileToErase);
  1352.           End;
  1353.         End;
  1354.       End;
  1355.       OldEntry := KillEntry;
  1356.       If KillEntry^.PrevEntry = KillEntry Then
  1357.       Begin
  1358.         Dispose(KillEntry);
  1359.         KillEntry := NIL;
  1360.       End
  1361.       Else
  1362.       Begin
  1363.         KillEntry^.PrevEntry^.NextEntry := KillEntry^.NextEntry;
  1364.         KillEntry^.NextEntry^.PrevEntry := KillEntry^.PrevEntry;
  1365.         KillEntry := KillEntry^.NextEntry;
  1366.       End;
  1367.       If KillEntry <> NIL Then Dispose(OldEntry);
  1368.     End;
  1369.   End;
  1370. {========================================================================}
  1371. Procedure Mfm2Bbs2Bak(InString : PathStr);
  1372.   Var
  1373.     TmpFilVar : Text;
  1374.   Begin
  1375.     attr := 0H;
  1376.     hndlhdir := HDIR_CREATE;
  1377.     count := 1;
  1378.     reslng := size(FILEFINDBUF);
  1379.     StrToZ(InString+'FILES.BAK',ztempstr);
  1380.     retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1381.       reslng,count,rsrvd);
  1382.     If retn = 0 Then
  1383.     Begin
  1384.       Assign(TmpFilVar,InString+'FILES.BAK');
  1385.       Erase(TmpFilVar);
  1386.     End;
  1387.     attr := 0H;
  1388.     hndlhdir := HDIR_CREATE;
  1389.     count := 1;
  1390.     reslng := size(FILEFINDBUF);
  1391.     StrToZ(InString+'FILES.BBS',ztempstr);
  1392.     retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1393.       reslng,count,rsrvd);
  1394.     If retn = 0 Then
  1395.     Begin
  1396.       Assign(TmpFilVar,InString+'FILES.BBS');
  1397.       Rename(TmpFilVar,InString+'FILES.BAK');
  1398.     End;
  1399.     Assign(TmpFilVar,InString+'FILES.MFM');
  1400.     Rename(TmpFilVar,InString+'FILES.BBS');
  1401.   End;
  1402. {========================================================================}
  1403. Procedure SaveList;
  1404.   Var
  1405.     Slc : Char;
  1406.   Begin
  1407.     AnsiGotoXY(25,1); AnsiClearToEOL;
  1408.     Write('This will DELETE killed files and update FILES.BBS, Are you sure? ');
  1409.     Repeat
  1410.       Gbx := GetInput;
  1411.       Slc := UpCase(chr(Gbx));
  1412.     Until Slc In ['N','Y'];
  1413.     Write(Slc);
  1414.     If Slc = 'Y' Then
  1415.     Begin
  1416.       Assign(FileList,FileAreaPath+'FILES.MFM');
  1417.       {$I-}
  1418.       IOcheck := FALSE;
  1419.       ReWrite(FileList);
  1420.       {$I+}
  1421.       IOcheck := TRUE;
  1422.       If IOresult = 0 Then
  1423.       Begin
  1424.         NextPrintEntry := FirstEntry;
  1425.         While NextPrintEntry^.NextEntry <> NIL Do
  1426.         Begin
  1427.           If NextPrintEntry^.TypeOfRecord <> Orphan Then
  1428.           Begin
  1429.             If NextPrintEntry^.TypeOfRecord <> Comment Then
  1430.             Begin
  1431.               Write(FileList,NextPrintEntry^.FileName);
  1432.               Write(FileList,
  1433.                 Copy('         ',1,13-Length(NextPrintEntry^.FileName))+' ');
  1434.             End;
  1435.             WriteLn(FileList,NextPrintEntry^.Description);
  1436.           End;
  1437.           NextPrintEntry := NextPrintEntry^.NextEntry;
  1438.         End;
  1439.         If NextPrintEntry^.TypeOfRecord <> Orphan Then
  1440.         Begin
  1441.           Write(FileList,NextPrintEntry^.FileName);
  1442.           Write(FileList,' ');
  1443.           WriteLn(FileList,NextPrintEntry^.Description);
  1444.         End;
  1445.         Close(FileList);
  1446.         Mfm2Bbs2Bak(FileAreaPath);
  1447.         EraseKillList;
  1448.         AnsiGotoXY(25,1); AnsiClearToEOL;
  1449.       End;
  1450.       Altered := False;
  1451.     End
  1452.     Else Write('N');
  1453.     AnsiGotoXY(24,80);
  1454.   End;
  1455. {========================================================================}
  1456.  
  1457.  
  1458. {========================================================================}
  1459. Procedure Quit;
  1460.   Var Qc : Char;
  1461. LABEL 1;
  1462.   Begin
  1463.     AnsiGotoXY(25,1); AnsiClearToEOL;
  1464.     Write('Are you sure? ');
  1465.     Repeat
  1466.       Gbx := GetInput;
  1467.       Qc := UpCase(chr(Gbx));
  1468.     Until Qc In ['N','Y'];
  1469.     Write(Qc);
  1470.     If Qc = 'N' Then
  1471.     Begin
  1472.       AnsiGotoXY(25,1); AnsiClearToEOL;
  1473.       GOTO 1;
  1474.     End;
  1475.     If Altered Then
  1476.     Begin
  1477.       SaveList;
  1478.     End;
  1479.     NewTextColor(White); NewTextBackground(Black);
  1480.     AnsiClearScreen;
  1481.     dos.exit(EXIT_PROCESS,0);
  1482. {    ABORT(0); }
  1483.  1:
  1484.   End;
  1485. {========================================================================}
  1486. Procedure ChangeFileDate;
  1487.   Var
  1488.     Cdc : Char;
  1489.     Year, Month, Day, DayOfWeek, Hour, Minute, Second, Sec100 : Word;
  1490.     FileToDate : FILE OF char;
  1491.     DateTimeString : String[17];
  1492.   Begin
  1493.     If CurrentEntry^.TypeOfRecord = FileRecord Then
  1494.     Begin
  1495.       AnsiGotoXY(25,1); AnsiClearToEOL;
  1496.       Write('Change date to current, special or abort? (C/S/A) ');
  1497.       Repeat
  1498.         Gbx := GetInput;
  1499.         Cdc := Upcase(chr(Gbx));
  1500.       Until Cdc In ['C','S','A'];
  1501.       Write(Cdc);
  1502.       If Cdc In ['C','S'] Then
  1503.       Begin
  1504.         Case Cdc Of
  1505.           'C' : Begin
  1506.                   GetDate(Year, Month, Day, DayOfWeek);
  1507.                   GetTime(Hour, Minute, Second, Sec100);
  1508.                   Date.Year := Year; Date.Month := Month; Date.Day := Day;
  1509.                   Date.Hour := Hour; Date.Min := Minute; Date.Sec := Second;
  1510.                   PackTime(Date, CurrentEntry^.FileDate);
  1511.                 End;
  1512.           'S' : Begin
  1513.                   AnsiGotoXY(25,1); AnsiClearToEOL;
  1514.                   DateTimeString := GetDateString(CurrentEntry^.FileDate)+' '+GetTimeString(CurrentEntry^.FileDate);
  1515.                   Write(DateTimeString);
  1516.                   DateTimeString := EditLine(DateTimeString,17,25,0);
  1517.                   AnsiGotoXY(25,40); Write(DateTimeString);
  1518.                   CurrentEntry^.FileDate := GetPackedTime(Copy(DateTimeString,1,8),Copy(DateTimeString,10,8));
  1519.                 End;
  1520.           Else        End;
  1521.         Assign(FileToDate,FileAreaPath+CurrentEntry^.FileName);
  1522.         Reset(FileToDate);
  1523.         SetFTime(FileToDate,CurrentEntry^.FileDate);
  1524.         Close(FileToDate);
  1525.         NextPrintEntry := CurrentEntry;
  1526.         DisplayRecord(Row); DisplayCurrentLocation;
  1527.       End;
  1528.       AnsiGotoXY(24,80);
  1529.     End;
  1530.   End;
  1531. {========================================================================}
  1532.  
  1533.  
  1534. {========================================================================}
  1535. Procedure GetAreaTable;
  1536.   Var
  1537.     AreaRecordNumber : Word;
  1538.     MaxAreaRecord : AreaRecordType;
  1539.   Begin
  1540.     NumberOfAreaEntries := 0; AreaRecordNumber := 1;
  1541.     OpenMaximusArea;
  1542.     While GetMaximusArea(AreaRecordNumber,StructLen,MaxAreaRecord) = 0 Do
  1543.     Begin
  1544.       OkToAddToList := False;
  1545.       AreaRecordNumber:=AreaRecordNumber+1;
  1546.       WorkString := Array2String(ADR(MaxAreaRecord.FilePath),Size(MaxAreaRecord.FilePath));
  1547.       attr := 0H;
  1548.       hndlhdir := HDIR_CREATE;
  1549.       count := 1;
  1550.       reslng := size(FILEFINDBUF);
  1551.       StrToZ(WorkString+'*.*',ztempstr);
  1552.       retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1553.         reslng,count,rsrvd);
  1554.       If retn = 0 Then
  1555.       Begin
  1556.         OkToAddToList := True;
  1557.       End
  1558.       Else
  1559.       Begin
  1560.         If retn <> 3 Then
  1561.         Begin
  1562.           Assign(FileList,WorkString+'FILES.BBS');
  1563.           {$I-}
  1564.           IOcheck := FALSE;
  1565.           ReWrite(FileList);
  1566.           {$I+}
  1567.           IOcheck := TRUE;
  1568.           If IOresult = 0 Then
  1569.           Begin
  1570.             Close(FileList);
  1571.             OkToAddToList := True;
  1572.           End;
  1573.         End;
  1574.       End;
  1575.       If (Length(WorkString) = 0) or (retn = 3) Then OkToAddToList := False;
  1576.       If OkToAddToList Then
  1577.       Begin
  1578.         NumberOfAreaEntries:=NumberOfAreaEntries+1;
  1579.         If MaxAvail > Size(ListRecord) Then
  1580.         Begin
  1581.           New(NewAreaEntry);
  1582.           If NumberOfAreaEntries = 1 Then
  1583.           Begin
  1584.             FirstAreaEntry := NewAreaEntry;
  1585.             NewAreaEntry^.PrevEntry := NIL;
  1586.             OldAreaEntry := FirstAreaEntry;
  1587.           End
  1588.           Else
  1589.           Begin
  1590.             NewAreaEntry^.PrevEntry := OldAreaEntry;
  1591.             OldAreaEntry^.NextEntry := NewAreaEntry;
  1592.             OldAreaEntry := NewAreaEntry;
  1593.           End;
  1594.           NewAreaEntry^.AreaPath := WorkString;
  1595.         End;
  1596.       End;
  1597.     End;
  1598.     CloseMaximusArea;
  1599.     If NumberOfAreaEntries = 0 Then
  1600.     Begin
  1601.       WriteLn('No areas found!');
  1602.       dos.exit(EXIT_PROCESS,1);
  1603. {      ABORT(1); }
  1604.     End
  1605.     Else
  1606.     Begin
  1607.       NewAreaEntry^.NextEntry := NIL;
  1608.       AreaCounter := 1; ChooseAreaEntry := FirstAreaEntry;
  1609.     End;
  1610.   End;
  1611. {========================================================================}
  1612. Procedure DisplayArea(AreaNumber : Byte; TempAreaEntry : AreaPtr);
  1613.   Var
  1614.     Row, Col : Byte;
  1615.   Begin
  1616.     WorkString := TempAreaEntry^.AreaPath;
  1617.     Delete(WorkString,Length(WorkString),1);
  1618.     WorkString := RCopy(WorkString,1,RPos('\',WorkString)-1);
  1619.     If AreaNumber = 1 Then Row := 1 Else Row := (((AreaNumber-1) Div Columns)+1);
  1620.     If AreaNumber = 1 Then Col := 1 Else Col := (((AreaNumber-1) Mod Columns)*ColumnPos)+1;
  1621.     If Col = 1 Then
  1622.     Begin
  1623.       AnsiGotoXY(Row,1); AnsiClearToEOL;
  1624.     End;
  1625.     AnsiGotoXY(Row,Col);
  1626.     NewTextColor(LightRed);
  1627.     Write(' '+WorkString);
  1628.     NewTextColor(White);
  1629.   End;
  1630. {========================================================================}
  1631. Procedure BlankAreaPointer(AreaNumber : Byte);
  1632.   Var
  1633.     Row, Col : Byte;
  1634.   Begin
  1635.     If AreaNumber = 1 Then Row := 1 Else Row := (((AreaNumber-1) Div Columns)+1);
  1636.     If AreaNumber = 1 Then Col := 1 Else Col := (((AreaNumber-1) Mod Columns)*ColumnPos)+1;
  1637.     AnsiGotoXY(Row,Col);
  1638.     Write(' ');
  1639.     AnsiGotoXY(24,80);
  1640.   End;
  1641. {========================================================================}
  1642. Procedure ShowAreaPointer(AreaNumber : Byte);
  1643.   Var
  1644.     Row, Col : Byte;
  1645.   Begin
  1646.     AnsiGotoXY(25,1); AnsiClearToEOL;
  1647.     Write(ChooseAreaEntry^.AreaPath);
  1648.     If AreaNumber = 1 Then Row := 1 Else Row := (((AreaNumber-1) Div Columns)+1);
  1649.     If AreaNumber = 1 Then Col := 1 Else Col := (((AreaNumber-1) Mod Columns)*ColumnPos)+1;
  1650.     AnsiGotoXY(Row,Col);
  1651.     Write('>');
  1652.     AnsiGotoXY(24,80);
  1653.   End;
  1654. {========================================================================}
  1655. Procedure DisplayAreaList;
  1656.   Var
  1657.     AreaCounter : Byte;
  1658.   Begin
  1659.     OldAreaEntry := FirstAreaEntry; AreaCounter := 0;
  1660.     While OldAreaEntry^.NextEntry <> NIL Do
  1661.     Begin
  1662.       AreaCounter:=AreaCounter+1;
  1663.       DisplayArea(AreaCounter, OldAreaEntry);
  1664.       OldAreaEntry := OldAreaEntry^.NextEntry;
  1665.     End;
  1666.     AreaCounter:=AreaCounter+1;
  1667.     DisplayArea(AreaCounter, OldAreaEntry);
  1668.   End;
  1669. {========================================================================}
  1670. Procedure AddTempArea;
  1671.   Var
  1672.     NewAreaName : MAXSTRING;
  1673.   Begin
  1674.     AnsiGotoXY(25,1); AnsiClearToEOL;
  1675.     Write('Enter new temporary path: ');
  1676.     NewAreaName := UpperString(EditLine('',40,25,26));
  1677.     If Length(NewAreaName) > 0 Then
  1678.     Begin
  1679.       If Copy(NewAreaName,Length(NewAreaName),1) <> '\' Then NewAreaName := NewAreaName + '\';
  1680.       OkToAddToList := False;
  1681.       attr := 0H;
  1682.       hndlhdir := HDIR_CREATE;
  1683.       count := 1;
  1684.       reslng := size(FILEFINDBUF);
  1685.       StrToZ(NewAreaName+'*.*',ztempstr);
  1686.       retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1687.         reslng,count,rsrvd);
  1688.       If retn = 0 Then
  1689.       Begin
  1690.         OkToAddToList := True;
  1691.       End
  1692.       Else
  1693.       Begin
  1694.         Assign(FileList,NewAreaName+'FILES.BBS');
  1695.         {$I-}
  1696.         IOcheck := FALSE;
  1697.         ReWrite(FileList);
  1698.         {$I+}
  1699.         IOcheck := TRUE;
  1700.         If IOresult = 0 Then
  1701.         Begin
  1702.           Close(FileList);
  1703.           OkToAddToList := True;
  1704.         End;
  1705.       End;
  1706.       If OkToAddToList Then
  1707.       Begin
  1708.         If MaxAvail > Size(ListRecord) Then
  1709.         Begin
  1710.           New(NewAreaEntry);
  1711.           NewAreaEntry^.PrevEntry := OldAreaEntry;
  1712.           OldAreaEntry^.NextEntry := NewAreaEntry;
  1713.           OldAreaEntry := NewAreaEntry;
  1714.           NewAreaEntry^.AreaPath := NewAreaName;
  1715.           NewAreaEntry^.NextEntry := NIL;
  1716.           NumberOfAreaEntries:=NumberOfAreaEntries+1;
  1717.           DisplayAreaList;
  1718.           ShowAreaPointer(AreaCounter);
  1719.         End;
  1720.       End
  1721.       Else
  1722.       Begin
  1723.         AnsiGotoXY(25,1); AnsiClearToEOL;
  1724.         Write('Directory '+NewAreaName+' not found!');
  1725.       End;
  1726.     End;
  1727.   End;
  1728. {========================================================================}
  1729. Procedure MatchMask;
  1730.   Var
  1731.     AreaPointer : AreaPtr;
  1732.     AreaPointerPosition : Byte;
  1733.     Matched : Boolean;
  1734.   Begin
  1735.     Matched := False; AreaPointer := FirstAreaEntry; AreaPointerPosition := 1;
  1736.     WorkString := AreaPointer^.AreaPath;
  1737.     Delete(WorkString,Length(WorkString),1);
  1738.     WorkString := RCopy(WorkString,1,RPos('\',WorkString)-1);
  1739.     If Pos(AreaMask,UpperString(WorkString)) = 1 Then Matched := True;
  1740.     While (AreaPointer^.NextEntry <> NIL) And (Not Matched) Do
  1741.     Begin
  1742.       AreaPointer := AreaPointer^.NextEntry; AreaPointerPosition:=AreaPointerPosition+1;
  1743.       WorkString := AreaPointer^.AreaPath;
  1744.       Delete(WorkString,Length(WorkString),1);
  1745.       WorkString := RCopy(WorkString,1,RPos('\',WorkString)-1);
  1746.       If Pos(AreaMask,UpperString(WorkString)) = 1 Then Matched := True;
  1747.     End;
  1748.     If Matched Then
  1749.     Begin
  1750.       BlankAreaPointer(AreaCounter);
  1751.       ChooseAreaEntry := AreaPointer;
  1752.       AreaCounter := AreaPointerPosition;
  1753.       ShowAreaPointer(AreaCounter);
  1754.     End
  1755.     Else
  1756.     Begin
  1757.       Delete(AreaMask,Length(AreaMask),1);
  1758.     End;
  1759.   End;
  1760. {========================================================================}
  1761. Function ChooseArea : MAXSTRING;
  1762.   Var
  1763.     Cax : Char;
  1764.     Cab : Byte;
  1765.   Begin
  1766.     DisplayAreaList;
  1767.     ShowAreaPointer(AreaCounter);
  1768.     AreaMask := '';
  1769.     Repeat
  1770.       Gbx := GetInput;
  1771.       Cax := Upcase(chr(Gbx));
  1772.       If Gbx = 0 Then
  1773.       Begin
  1774.         Gbx := GetInput;
  1775.         Case Gbx Of
  1776.           71 : Cax := '7';
  1777.           72 : Cax := '8';
  1778.           73 : Cax := '9';
  1779.           75 : Cax := '4';
  1780.           77 : Cax := '6';
  1781.           79 : Cax := '1';
  1782.           80 : Cax := '2';
  1783.           81 : Cax := '3';
  1784.           Else        End;
  1785.       End;
  1786.       Case Cax Of
  1787.         '1' : Begin
  1788.                 BlankAreaPointer(AreaCounter);
  1789.                 AreaCounter := (NumberOfAreaEntries - (NumberOfAreaEntries Mod Columns)) + 1;
  1790.                 If AreaCounter > NumberOfAreaEntries Then AreaCounter := NumberOfAreaEntries - (Columns-1);
  1791.                 ChooseAreaEntry := FirstAreaEntry;
  1792.                 For Cab := 1 To AreaCounter-1 Do ChooseAreaEntry := ChooseAreaEntry^.NextEntry;
  1793.                 ShowAreaPointer(AreaCounter);
  1794.               End;
  1795.         '2' : Begin
  1796.                 If AreaCounter+Columns <= NumberOfAreaEntries Then
  1797.                 Begin
  1798.                   BlankAreaPointer(AreaCounter);
  1799.                   AreaCounter := AreaCounter + Columns;
  1800.                   For Cab := 1 To Columns Do ChooseAreaEntry := ChooseAreaEntry^.NextEntry;
  1801.                   ShowAreaPointer(AreaCounter);
  1802.                 End;
  1803.               End;
  1804.         '3' : Begin
  1805.                 BlankAreaPointer(AreaCounter);
  1806.                 AreaCounter := NumberOfAreaEntries - (NumberOfAreaEntries Mod Columns);
  1807.                 ChooseAreaEntry := FirstAreaEntry;
  1808.                 For Cab := 1 To AreaCounter-1 Do ChooseAreaEntry := ChooseAreaEntry^.NextEntry;
  1809.                 ShowAreaPointer(AreaCounter);
  1810.               End;
  1811.         '4' : Begin
  1812.                 If AreaCounter > 1 Then
  1813.                 Begin
  1814.                   ChooseAreaEntry := ChooseAreaEntry^.PrevEntry;
  1815.                   BlankAreaPointer(AreaCounter);
  1816.                   AreaCounter:=AreaCounter-1;
  1817.                   ShowAreaPointer(AreaCounter);
  1818.                 End;
  1819.               End;
  1820.         '6' : Begin
  1821.                 If AreaCounter < NumberOfAreaEntries Then
  1822.                 Begin
  1823.                   ChooseAreaEntry := ChooseAreaEntry^.NextEntry;
  1824.                   BlankAreaPointer(AreaCounter);
  1825.                   AreaCounter:=AreaCounter+1;
  1826.                   ShowAreaPointer(AreaCounter);
  1827.                 End;
  1828.               End;
  1829.         '7' : Begin
  1830.                 ChooseAreaEntry := FirstAreaEntry;
  1831.                 BlankAreaPointer(AreaCounter);
  1832.                 AreaCounter := 1;
  1833.                 ShowAreaPointer(AreaCounter);
  1834.               End;
  1835.         '8' : Begin
  1836.                 If AreaCounter-Columns > 0 Then
  1837.                 Begin
  1838.                   BlankAreaPointer(AreaCounter);
  1839.                   AreaCounter := AreaCounter - Columns;
  1840.                   For Cab := 1 To Columns Do ChooseAreaEntry := ChooseAreaEntry^.PrevEntry;
  1841.                   ShowAreaPointer(AreaCounter);
  1842.                 End;
  1843.               End;
  1844.         '9' : Begin
  1845.                 BlankAreaPointer(AreaCounter);
  1846.                 AreaCounter := Columns;
  1847.                 ChooseAreaEntry := FirstAreaEntry;
  1848.                 For Cab := 1 To Columns-1 Do ChooseAreaEntry := ChooseAreaEntry^.NextEntry;
  1849.                 ShowAreaPointer(AreaCounter);
  1850.               End;
  1851.         chr(9)  : AddTempArea;
  1852.         '?' : Begin
  1853.                 AreaHelp;
  1854.                 DisplayAreaList;
  1855.                 ShowAreaPointer(AreaCounter);
  1856.               End;
  1857.       Else
  1858.         If Cax = chr(8) Then
  1859.         Begin
  1860.           Delete(AreaMask,Length(AreaMask),1);
  1861.           MatchMask
  1862.         End;
  1863.         If Cax In [':','A'..'Z','a'..'z'] Then
  1864.         Begin
  1865.           AreaMask := AreaMask + Cax;
  1866.           MatchMask
  1867.         End;
  1868.         AnsiGotoXY(25,1); AnsiClearToEOL;
  1869.         Write(AreaMask);
  1870.       End;
  1871.     Until Cax In [chr(13),chr(17),chr(27)];
  1872.     If Cax In [chr(17),chr(27)] Then
  1873.     Begin
  1874.       If Cax = chr(17) Then
  1875.       Begin
  1876.         ChooseArea := 'QUITQUICK';
  1877.       End
  1878.       Else
  1879.       Begin
  1880.         ChooseArea := 'QUIT';
  1881.       End;
  1882.     End
  1883.     Else
  1884.     Begin
  1885.       ChooseArea := ChooseAreaEntry^.AreaPath;
  1886.     End;
  1887.   End;
  1888. {========================================================================}
  1889. Procedure ChooseNewArea;
  1890.   Var
  1891.     TempArea : MAXSTRING;
  1892.   Begin
  1893.     If Altered Then
  1894.     Begin
  1895.       SaveList;
  1896.       Altered := False;
  1897.     End;
  1898.     BeginSort := NIL; EndSort := NIL;
  1899.     NextPrintEntry := FirstEntry;
  1900.     If NumberOfEntries > 0 Then
  1901.     Begin
  1902.       While NextPrintEntry^.NextEntry <> NIL Do
  1903.       Begin
  1904.         NextPrintEntry := NextPrintEntry^.NextEntry;
  1905.         Dispose(NextPrintEntry^.PrevEntry);
  1906.       End;
  1907.       Dispose(NextPrintEntry);
  1908.     End;
  1909.     SetupScreen;
  1910.     Repeat
  1911.       TempArea := ChooseArea;
  1912.       If TempArea = 'QUITQUICK' Then
  1913.       Begin
  1914.         dos.exit(EXIT_PROCESS,1);
  1915. {        ABORT(1); }
  1916.       End;
  1917.       If TempArea <> 'QUIT' Then
  1918.       Begin
  1919.         FileAreaPath := TempArea;
  1920.       End;
  1921.       NumberOfEntries := 0; BuildList;
  1922.       If NumberOfEntries = 0 Then
  1923.       Begin
  1924.         AnsiGotoXY(25,1); AnsiClearToEOL;
  1925.         Write('This area contains no files!');
  1926.       End;
  1927.     Until (NumberOfEntries > 0) Or (TempArea = 'QUIT');
  1928.     If NumberOfEntries > 0 Then
  1929.     Begin
  1930.       If TempArea <> 'QUIT' Then
  1931.       Begin
  1932.         Row := 1;
  1933.         CurrentEntry := FirstEntry;
  1934.         TopEntry := FirstEntry;
  1935.       End;
  1936.       DisplayScreen;
  1937.     End;
  1938.   End;
  1939. {========================================================================}
  1940.  
  1941.  
  1942. {========================================================================}
  1943. Procedure CenterWrite(Row : Byte; CenteredString : MAXSTRING);
  1944.   Begin
  1945.     AnsiGotoXY(Row,1); AnsiClearToEOL;
  1946.     AnsiGotoXY(Row,40-(Length(CenteredString) Div 2));
  1947.     Write(CenteredString);
  1948.   End;
  1949. {========================================================================}
  1950. Function FileCopy(FromFileName, ToFileName : MAXSTRING; CopyOrMove : Char) : Boolean;
  1951.   Var
  1952.     FromFile, ToFile : FILE OF char;
  1953.     OverWrite : Boolean;
  1954.     Fcc : Char;
  1955.     TempEntry : ListPtr;
  1956.     ToFilesBbs : Text;
  1957.   Begin
  1958.     FileCopy := False; OverWrite := True;
  1959.     attr := 0H;
  1960.     hndlhdir := HDIR_CREATE;
  1961.     count := 1;
  1962.     reslng := size(FILEFINDBUF);
  1963.     StrToZ(FromFileName,ztempstr);
  1964.     retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1965.       reslng,count,rsrvd);
  1966.     If retn = 0 Then
  1967.     Begin
  1968.       attr := 0H;
  1969.       hndlhdir := HDIR_CREATE;
  1970.       count := 1;
  1971.       reslng := size(FILEFINDBUF);
  1972.       StrToZ(ToFileName,ztempstr);
  1973.       retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  1974.         reslng,count,rsrvd);
  1975.       If retn = 0 Then
  1976.       Begin
  1977.         OverWrite := False;
  1978.         AnsiClearScreen; AnsiGotoXY(21,1);
  1979.         NewTextColor(Black); NewTextBackground(Cyan);
  1980.         Write(Pgmid+' ^Q=quit ?=help');
  1981.         NewTextColor(White); NewTextBackground(Black);
  1982.         NextPrintEntry := CurrentEntry; DisplayRecord(22);
  1983.         NewTextColor(White);
  1984.         CenterWrite(23,'already exists as');
  1985.         New(TempEntry);
  1986.         TempEntry^.TypeOfRecord := FileRecord;
  1987.         tfname := array2string(ADR(dirinfo.name),dirinfo.cname);
  1988.         TempEntry^.FileName := tfname;
  1989.         TempEntry^.FileDate := DirInfo.fdatelastwrite;
  1990.         TempEntry^.FileDate := TempEntry^.FileDate << 16;
  1991.         TempEntry^.FileDate := TempEntry^.FileDate + DirInfo.ftimelastwrite;
  1992.         TempEntry^.FileSize := DirInfo.fileSize;
  1993.         Fsplit(ToFileName,D,N,E);
  1994.         Assign(ToFilesBbs,D+'FILES.BBS');
  1995.         {$I-}
  1996.         IOcheck := FALSE;
  1997.         Reset(ToFilesBbs);
  1998.         {$I+}
  1999.         IOcheck := TRUE;
  2000.         If IOresult = 0 Then
  2001.         Begin
  2002.           While (Not Eof(ToFilesBbs)) Do
  2003.           Begin
  2004.             ReadLn(ToFilesBbs,WorkString);
  2005.             If Pos(N+E,WorkString) > 0 Then
  2006.             Begin
  2007.               TempEntry^.Description := Copy(WorkString,Pos(' ',WorkString)+1,Length(WorkString)-Pos(' ',WorkString));
  2008.             End;
  2009.           End;
  2010.           Close(ToFilesBbs);
  2011.         End
  2012.         Else
  2013.         Begin
  2014.           TempEntry^.Description := '';
  2015.         End;
  2016.         TempEntry^.Tagged := False;
  2017.         NextPrintEntry := TempEntry; DisplayRecord(24);
  2018.         Dispose(TempEntry);
  2019.         NewTextColor(White);
  2020.         CenterWrite(25,'Overwrite? (Y/N) ');
  2021.         Repeat
  2022.           Gbx := GetInput;
  2023.           Fcc := Upcase(chr(Gbx));
  2024.         Until Fcc In ['N','Y'];
  2025.         Write(Fcc);
  2026.         If Fcc = 'Y' Then OverWrite := True;
  2027.       End;
  2028.       If OverWrite Then
  2029.       Begin
  2030.         If (CopyOrMove = 'M') And (Copy(FromFileName,1,1) = Copy(ToFileName,1,1)) Then
  2031.         Begin
  2032.           CenterWrite(22,'Moving');
  2033.           CenterWrite(23,FromFileName);
  2034.           CenterWrite(24,'to');
  2035.           CenterWrite(25,ToFileName);
  2036.           attr := 0H;
  2037.           hndlhdir := HDIR_CREATE;
  2038.           count := 1;
  2039.           reslng := size(FILEFINDBUF);
  2040.           StrToZ(ToFileName,ztempstr);
  2041.           retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2042.             reslng,count,rsrvd);
  2043.           If retn = 0 Then
  2044.           Begin
  2045.             Assign(ToFile,ToFileName);
  2046.             Erase(ToFile);
  2047.           End;
  2048.           Assign(FromFile,FromFileName);
  2049.           Rename(FromFile,ToFileName);
  2050.         End
  2051.         Else
  2052.         Begin
  2053.           If CopyOrMove = 'C' Then CenterWrite(22,'Copying ') Else CenterWrite(22,'Moving ');
  2054.           CenterWrite(23,FromFileName);
  2055.           CenterWrite(24,'to');
  2056.           CenterWrite(25,ToFileName);
  2057.           DoFileCopy(FromFileName,ToFileName);
  2058.           Assign(FromFile,FromFileName);
  2059.           If CopyOrMove = 'M' Then Erase(FromFile);
  2060.         End;
  2061.         FileCopy := True;
  2062.       End;
  2063.     End;
  2064.   End;
  2065. {========================================================================}
  2066. Procedure ShowSizeSpace(Drive : Char; Row : Byte);
  2067.   Begin
  2068.     Drive := Upcase(Drive);
  2069.     AnsiGotoXY(Row,1);
  2070.     NewTextColor(Black);
  2071.     NewTextBackground(Cyan);
  2072.     AnsiClearToEOL;
  2073.     Write(CurrentEntry^.FileName+' is ',CurrentEntry^.FileSize Div 1024,'K bytes in size!   There are ');
  2074.     Write(DiskFree(Ord(Drive)-64) Div 1024);
  2075.     Write('K bytes free on drive '+Drive+'.');
  2076.     NewTextColor(White); NewTextBackground(Black);
  2077.   End;
  2078. {========================================================================}
  2079. Procedure CopyFile;
  2080.   Var
  2081.     ToAreaPath : String[80];
  2082.     Cfc : Char;
  2083.   Begin
  2084.     If CurrentEntry^.TypeOfRecord = FileRecord Then
  2085.     Begin
  2086.       SetupScreen;
  2087.       AnsiGotoXY(25,1); AnsiClearToEOL;
  2088.       Write(FileAreaPath+CurrentEntry^.FileName);
  2089.       ToAreaPath := ChooseArea;
  2090.       If ToAreaPath <> 'QUIT' Then
  2091.       Begin
  2092.         ShowSizeSpace(ToAreaPath[1],24);
  2093.         If CurrentEntry^.FileSize < (DiskFree(Ord(Upcase(ToAreaPath[1]))-64)-(SizeOfFilesBbs(ToAreaPath)+2048)) Then
  2094.         Begin
  2095.           ShowSizeSpace(ToAreaPath[1],21);
  2096.           CenterWrite(22,FileAreaPath+CurrentEntry^.FileName);
  2097.           CenterWrite(23,'to');
  2098.           CenterWrite(24,ToAreaPath+CurrentEntry^.FileName);
  2099.           CenterWrite(25,'Proceed with COPY? (Y/N) ');
  2100.           Repeat
  2101.             Gbx := GetInput;
  2102.             Cfc := Upcase(chr(Gbx));
  2103.           Until Cfc In ['N','Y'];
  2104.           Write(Cfc);
  2105.           If Cfc = 'Y' Then
  2106.           Begin
  2107.             If FileCopy(FileAreaPath+CurrentEntry^.FileName,ToAreaPath+CurrentEntry^.FileName,'C') Then
  2108.             Begin
  2109.               attr := 0H;
  2110.               hndlhdir := HDIR_CREATE;
  2111.               count := 1;
  2112.               reslng := size(FILEFINDBUF);
  2113.               StrToZ(ToAreaPath+'FILES.BBS',ztempstr);
  2114.               retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2115.                 reslng,count,rsrvd);
  2116.               If retn = 0 Then
  2117.               Begin
  2118.                 Changed := False;
  2119.                 Assign(FileList,ToAreaPath+'FILES.BBS');
  2120.                 Reset(FileList);
  2121.                 Assign(NewFileList,ToAreaPath+'FILES.MFM');
  2122.                 ReWrite(NewFileList);
  2123.                 While (Not Eof(FileList)) Do
  2124.                 Begin
  2125.                   ReadLn(FileList,WorkString);
  2126.                   If Pos(CurrentEntry^.FileName,WorkString) = 0 Then
  2127.                   Begin
  2128.                     WriteLn(NewFileList,WorkString);
  2129.                   End
  2130.                   Else
  2131.                   Begin
  2132.                     WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2133.                     Changed := True;
  2134.                   End;
  2135.                 End;
  2136.                 If (Not Changed) Then WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2137.                 Close(FileList); Close(NewFileList);
  2138.                 Mfm2Bbs2Bak(ToAreaPath);
  2139.               End
  2140.               Else
  2141.               Begin
  2142.                 Assign(FileList,ToAreaPath+'FILES.MFM');
  2143.                 ReWrite(FileList);
  2144.                 WriteLn(FileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2145.                 Close(FileList);
  2146.                 Mfm2Bbs2Bak(ToAreaPath);
  2147.               End;
  2148.             End;
  2149.           End;
  2150.           ReDrawScreen;
  2151.         End
  2152.         Else
  2153.         Begin
  2154.           ReDrawScreen;
  2155.           AnsiGotoXY(25,1); AnsiClearToEOL;
  2156.           Write('There is not enough space on drive '+ToAreaPath[1]+' to complete the copy!');
  2157.         End;
  2158.       End
  2159.       Else ReDrawScreen;
  2160.     End;
  2161.   End;
  2162. {========================================================================}
  2163. Procedure MoveFile;
  2164.   Var
  2165.     ToAreaPath : String[80];
  2166.     Mfc : Char;
  2167.     FileToErase : FILE OF char;
  2168.   Begin
  2169.     If CurrentEntry^.TypeOfRecord = FileRecord Then
  2170.     Begin
  2171.       SetupScreen;
  2172.       AnsiGotoXY(25,1); AnsiClearToEOL;
  2173.       Write(FileAreaPath+CurrentEntry^.FileName);
  2174.       ToAreaPath := ChooseArea;
  2175.       If ToAreaPath <> 'QUIT' Then
  2176.       Begin
  2177.         ShowSizeSpace(ToAreaPath[1],24);
  2178.         If (CurrentEntry^.FileSize < (DiskFree(Ord(Upcase(ToAreaPath[1]))-64))-(SizeOfFilesBbs(ToAreaPath)+2048))
  2179.           Or (FileAreaPath[1] = ToAreaPath[1]) Then
  2180.         Begin
  2181.           ShowSizeSpace(ToAreaPath[1],21);
  2182.           CenterWrite(22,FileAreaPath+CurrentEntry^.FileName);
  2183.           CenterWrite(23,'to');
  2184.           CenterWrite(24,ToAreaPath+CurrentEntry^.FileName);
  2185.           CenterWrite(25,'Proceed with MOVE? (Y/N) ');
  2186.           Repeat
  2187.             Gbx := GetInput;
  2188.             Mfc := Upcase(chr(Gbx));
  2189.           Until Mfc In ['N','Y'];
  2190.           Write(Mfc);
  2191.           If Mfc = 'Y' Then
  2192.           Begin
  2193.             If FileCopy(FileAreaPath+CurrentEntry^.FileName,ToAreaPath+CurrentEntry^.FileName,'M') Then
  2194.             Begin
  2195.               attr := 0H;
  2196.               hndlhdir := HDIR_CREATE;
  2197.               count := 1;
  2198.               reslng := size(FILEFINDBUF);
  2199.               StrToZ(ToAreaPath+'FILES.BBS',ztempstr);
  2200.               retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2201.                 reslng,count,rsrvd);
  2202.               If retn = 0 Then
  2203.               Begin
  2204.                 Changed := False;
  2205.                 Assign(FileList,ToAreaPath+'FILES.BBS');
  2206.                 Reset(FileList);
  2207.                 Assign(NewFileList,ToAreaPath+'FILES.MFM');
  2208.                 ReWrite(NewFileList);
  2209.                 While (Not Eof(FileList)) Do
  2210.                 Begin
  2211.                   ReadLn(FileList,WorkString);
  2212.                   If Pos(CurrentEntry^.FileName,WorkString) = 0 Then
  2213.                   Begin
  2214.                     WriteLn(NewFileList,WorkString);
  2215.                   End
  2216.                   Else
  2217.                   Begin
  2218.                     WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2219.                     Changed := True;
  2220.                   End;
  2221.                 End;
  2222.                 If (Not Changed) Then WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2223.                 Close(FileList); Close(NewFileList);
  2224.                 Mfm2Bbs2Bak(ToAreaPath);
  2225.               End
  2226.               Else
  2227.               Begin
  2228.                 Assign(FileList,ToAreaPath+'FILES.MFM');
  2229.                 ReWrite(FileList);
  2230.                 WriteLn(FileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2231.                 Close(FileList);
  2232.                 Mfm2Bbs2Bak(ToAreaPath);
  2233.               End;
  2234.               PushRecord(KillEntry);
  2235.               OldEntry := KillEntry;
  2236.               If KillEntry^.PrevEntry = KillEntry Then
  2237.               Begin
  2238.                 Dispose(KillEntry);
  2239.                 KillEntry := NIL;
  2240.               End
  2241.               Else
  2242.               Begin
  2243.                 KillEntry^.PrevEntry^.NextEntry := KillEntry^.NextEntry;
  2244.                 KillEntry^.NextEntry^.PrevEntry := KillEntry^.PrevEntry;
  2245.                 KillEntry := KillEntry^.NextEntry;
  2246.               End;
  2247.               If KillEntry <> NIL Then Dispose(OldEntry);
  2248.             End;
  2249.           End;
  2250.           ReDrawScreen;
  2251.         End
  2252.         Else
  2253.         Begin
  2254.           ReDrawScreen;
  2255.           AnsiGotoXY(25,1); AnsiClearToEOL;
  2256.           Write('There is not enough space on drive '+ToAreaPath[1]+' to complete the move!');
  2257.         End;
  2258.       End
  2259.       Else ReDrawScreen;
  2260.     End;
  2261.   End;
  2262. {========================================================================}
  2263. Procedure MassMove;
  2264.   Var
  2265.     ToAreaPath : String[80];
  2266.     TempEntry : ListPtr;
  2267.     Mmc : Char;
  2268.     MoveOk : Boolean;
  2269.   Begin
  2270.     SetupScreen;
  2271.     CenterWrite(25,'Select area to MASS MOVE to...');
  2272.     ToAreaPath := ChooseArea;
  2273.     If ToAreaPath <> 'QUIT' Then
  2274.     Begin
  2275.       CenterWrite(25,'Proceed with MASS MOVE? (Y/N) ');
  2276.       Repeat
  2277.         Gbx := GetInput;
  2278.         Mmc := Upcase(chr(Gbx));
  2279.       Until Mmc In ['N','Y'];
  2280.       Write(Mmc);
  2281.       If Mmc = 'Y' Then
  2282.       Begin
  2283.         TempEntry := CurrentEntry;
  2284.         CurrentEntry := FirstEntry;
  2285.         While CurrentEntry^.NextEntry <> NIL Do
  2286.         Begin
  2287.           MoveOk := False;
  2288.           If CurrentEntry^.Tagged Then
  2289.           Begin
  2290.             ShowSizeSpace(ToAreaPath[1],24);
  2291.             If (CurrentEntry^.FileSize < (DiskFree(Ord(Upcase(ToAreaPath[1]))-64))-(SizeOfFilesBbs(ToAreaPath)+2048))
  2292.               Or (FileAreaPath[1] = ToAreaPath[1]) Then
  2293.             Begin
  2294.               ShowSizeSpace(ToAreaPath[1],21);
  2295.               If FileCopy(FileAreaPath+CurrentEntry^.FileName,ToAreaPath+CurrentEntry^.FileName,'M') Then
  2296.               Begin
  2297.                 attr := 0H;
  2298.                 hndlhdir := HDIR_CREATE;
  2299.                 count := 1;
  2300.                 reslng := size(FILEFINDBUF);
  2301.                 StrToZ(ToAreaPath+'FILES.BBS',ztempstr);
  2302.                 retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2303.                   reslng,count,rsrvd);
  2304.                 If retn = 0 Then
  2305.                 Begin
  2306.                   Changed := False;
  2307.                   Assign(FileList,ToAreaPath+'FILES.BBS');
  2308.                   Reset(FileList);
  2309.                   Assign(NewFileList,ToAreaPath+'FILES.MFM');
  2310.                   ReWrite(NewFileList);
  2311.                   While (Not Eof(FileList)) Do
  2312.                   Begin
  2313.                     ReadLn(FileList,WorkString);
  2314.                     If Pos(CurrentEntry^.FileName,WorkString) = 0 Then
  2315.                     Begin
  2316.                       WriteLn(NewFileList,WorkString);
  2317.                     End
  2318.                     Else
  2319.                     Begin
  2320.                       WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2321.                       Changed := True;
  2322.                     End;
  2323.                   End;
  2324.                   If (Not Changed) Then WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2325.                   Close(FileList); Close(NewFileList);
  2326.                   Mfm2Bbs2Bak(ToAreaPath);
  2327.                 End
  2328.                 Else
  2329.                 Begin
  2330.                   Assign(FileList,ToAreaPath+'FILES.MFM');
  2331.                   ReWrite(FileList);
  2332.                   WriteLn(FileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2333.                   Close(FileList);
  2334.                   Mfm2Bbs2Bak(ToAreaPath);
  2335.                 End;
  2336.                 MoveOk := True;
  2337.                 PushRecord(KillEntry);
  2338.                 OldEntry := KillEntry;
  2339.                 If KillEntry^.PrevEntry = KillEntry Then
  2340.                 Begin
  2341.                   Dispose(KillEntry);
  2342.                   KillEntry := NIL;
  2343.                 End
  2344.                 Else
  2345.                 Begin
  2346.                   KillEntry^.PrevEntry^.NextEntry := KillEntry^.NextEntry;
  2347.                   KillEntry^.NextEntry^.PrevEntry := KillEntry^.PrevEntry;
  2348.                   KillEntry := KillEntry^.NextEntry;
  2349.                 End;
  2350.                 If KillEntry <> NIL Then Dispose(OldEntry);
  2351.               End;
  2352.             End
  2353.             Else
  2354.             Begin
  2355.               ReDrawScreen;
  2356.               AnsiGotoXY(25,1); AnsiClearToEOL;
  2357.               Write('There is not enough space on drive '+ToAreaPath[1]+' to complete the move!');
  2358.             End;
  2359.           End;
  2360.           If (Not MoveOk) Then CurrentEntry := CurrentEntry^.NextEntry;
  2361.         End;
  2362.       End;
  2363.     End;
  2364.     CurrentEntry := TopEntry; Row := 1;
  2365.     SetupScreen; DisplayScreen;
  2366.   End;
  2367. {========================================================================}
  2368. Procedure MassCopy;
  2369.   Var
  2370.     ToAreaPath : String[80];
  2371.     TempEntry : ListPtr;
  2372.     Mcc : Char;
  2373.     CopyOk : Boolean;
  2374.   Begin
  2375.     SetupScreen;
  2376.     CenterWrite(25,'Select area to MASS COPY to...');
  2377.     ToAreaPath := ChooseArea;
  2378.     If ToAreaPath <> 'QUIT' Then
  2379.     Begin
  2380.       CenterWrite(25,'Proceed with MASS COPY? (Y/N) ');
  2381.       Repeat
  2382.         Gbx := GetInput;
  2383.         Mcc := Upcase(chr(Gbx));
  2384.       Until Mcc In ['N','Y'];
  2385.       Write(Mcc);
  2386.       If Mcc = 'Y' Then
  2387.       Begin
  2388.         TempEntry := CurrentEntry;
  2389.         CurrentEntry := FirstEntry;
  2390.         While CurrentEntry^.NextEntry <> NIL Do
  2391.         Begin
  2392.           CopyOk := False;
  2393.           If CurrentEntry^.Tagged Then
  2394.           Begin
  2395.             ShowSizeSpace(ToAreaPath[1],24);
  2396.             If (CurrentEntry^.FileSize < (DiskFree(Ord(Upcase(ToAreaPath[1]))-64))-(SizeOfFilesBbs(ToAreaPath)+2048))
  2397.               Or (FileAreaPath[1] = ToAreaPath[1]) Then
  2398.             Begin
  2399.               ShowSizeSpace(ToAreaPath[1],21);
  2400.               If FileCopy(FileAreaPath+CurrentEntry^.FileName,ToAreaPath+CurrentEntry^.FileName,'C') Then
  2401.               Begin
  2402.                 attr := 0H;
  2403.                 hndlhdir := HDIR_CREATE;
  2404.                 count := 1;
  2405.                 reslng := size(FILEFINDBUF);
  2406.                 StrToZ(ToAreaPath+'FILES.BBS',ztempstr);
  2407.                 retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2408.                   reslng,count,rsrvd);
  2409.                 If retn = 0 Then
  2410.                 Begin
  2411.                   Changed := False;
  2412.                   Assign(FileList,ToAreaPath+'FILES.BBS');
  2413.                   Reset(FileList);
  2414.                   Assign(NewFileList,ToAreaPath+'FILES.MFM');
  2415.                   ReWrite(NewFileList);
  2416.                   While (Not Eof(FileList)) Do
  2417.                   Begin
  2418.                     ReadLn(FileList,WorkString);
  2419.                     If Pos(CurrentEntry^.FileName,WorkString) = 0 Then
  2420.                     Begin
  2421.                       WriteLn(NewFileList,WorkString);
  2422.                     End
  2423.                     Else
  2424.                     Begin
  2425.                       WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2426.                       Changed := True;
  2427.                     End;
  2428.                   End;
  2429.                   If (Not Changed) Then WriteLn(NewFileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2430.                   Close(FileList); Close(NewFileList);
  2431.                   Mfm2Bbs2Bak(ToAreaPath);
  2432.                 End
  2433.                 Else
  2434.                 Begin
  2435.                   Assign(FileList,ToAreaPath+'FILES.MFM');
  2436.                   ReWrite(FileList);
  2437.                   WriteLn(FileList,CurrentEntry^.FileName+' '+CurrentEntry^.Description);
  2438.                   Close(FileList);
  2439.                   Mfm2Bbs2Bak(ToAreaPath);
  2440.                 End;
  2441.                 CopyOk := True;
  2442.               End;
  2443.             End
  2444.             Else
  2445.             Begin
  2446.               ReDrawScreen;
  2447.               AnsiGotoXY(25,1); AnsiClearToEOL;
  2448.               Write('There is not enough space on drive '+ToAreaPath[1]+' to complete the copy!');
  2449.             End;
  2450.           End;
  2451.           CurrentEntry^.Tagged := False;
  2452.           If (Not CopyOk) Then CurrentEntry := CurrentEntry^.NextEntry;
  2453.         End;
  2454.       End;
  2455.     End;
  2456.     CurrentEntry := TopEntry; Row := 1;
  2457.     SetupScreen; DisplayScreen;
  2458.   End;
  2459. {========================================================================}
  2460.  
  2461.  
  2462. {========================================================================}
  2463. Procedure SortList;
  2464.   Var
  2465.     TempSort : ListPtr;
  2466.     SortNext, SortPrev, Exchange : Boolean;
  2467.   Begin
  2468.     If (BeginSort <> NIL) And (EndSort <> NIL) And (BeginSort <> EndSort) Then
  2469.     Begin
  2470.       SortNext := False; SortPrev := False; Altered := True;
  2471.       If MaxAvail > Size(ListRecord) Then
  2472.       Begin
  2473.         New(TempSort);
  2474.         NextPrintEntry := BeginSort;
  2475.         While (NextPrintEntry <> EndSort) And (NextPrintEntry <> NIL) Do
  2476.         Begin
  2477.           NextPrintEntry := NextPrintEntry^.NextEntry;
  2478.           If NextPrintEntry = EndSort Then SortNext := True;
  2479.         End;
  2480.         NextPrintEntry := BeginSort;
  2481.         While (NextPrintEntry <> EndSort) And (NextPrintEntry <> NIL) Do
  2482.         Begin
  2483.           NextPrintEntry := NextPrintEntry^.PrevEntry;
  2484.           If NextPrintEntry = EndSort Then SortPrev := True;
  2485.         End;
  2486.         If SortNext Then
  2487.         Begin
  2488.           Repeat
  2489.             Exchange := False;
  2490.             NextPrintEntry := BeginSort;
  2491.             While NextPrintEntry <> EndSort Do
  2492.             Begin
  2493.               If NextPrintEntry^.FileName > NextPrintEntry^.NextEntry^.FileName Then
  2494.               Begin
  2495.                 TempSort^.TypeOfRecord := NextPrintEntry^.TypeOfRecord;
  2496.                 TempSort^.FileName := NextPrintEntry^.FileName;
  2497.                 TempSort^.FileSize := NextPrintEntry^.FileSize;
  2498.                 TempSort^.FileDate := NextPrintEntry^.FileDate;
  2499.                 TempSort^.Description := NextPrintEntry^.Description;
  2500.                 NextPrintEntry^.TypeOfRecord := NextPrintEntry^.NextEntry^.TypeOfRecord;
  2501.                 NextPrintEntry^.FileName := NextPrintEntry^.NextEntry^.FileName;
  2502.                 NextPrintEntry^.FileSize := NextPrintEntry^.NextEntry^.FileSize;
  2503.                 NextPrintEntry^.FileDate := NextPrintEntry^.NextEntry^.FileDate;
  2504.                 NextPrintEntry^.Description := NextPrintEntry^.NextEntry^.Description;
  2505.                 NextPrintEntry^.NextEntry^.TypeOfRecord := TempSort^.TypeOfRecord;
  2506.                 NextPrintEntry^.NextEntry^.FileName := TempSort^.FileName;
  2507.                 NextPrintEntry^.NextEntry^.FileSize := TempSort^.FileSize;
  2508.                 NextPrintEntry^.NextEntry^.FileDate := TempSort^.FileDate;
  2509.                 NextPrintEntry^.NextEntry^.Description := TempSort^.Description;
  2510.                 Exchange := True;
  2511.               End;
  2512.               NextPrintEntry := NextPrintEntry^.NextEntry;
  2513.             End;
  2514.           Until (Not Exchange);
  2515.           DisplayScreen;
  2516.         End;
  2517.         If SortPrev Then
  2518.         Begin
  2519.           Repeat
  2520.             Exchange := False;
  2521.             NextPrintEntry := BeginSort;
  2522.             While NextPrintEntry <> EndSort Do
  2523.             Begin
  2524.               If NextPrintEntry^.FileName > NextPrintEntry^.PrevEntry^.FileName Then
  2525.               Begin
  2526.                 TempSort^.TypeOfRecord := NextPrintEntry^.TypeOfRecord;
  2527.                 TempSort^.FileName := NextPrintEntry^.FileName;
  2528.                 TempSort^.FileSize := NextPrintEntry^.FileSize;
  2529.                 TempSort^.FileDate := NextPrintEntry^.FileDate;
  2530.                 TempSort^.Description := NextPrintEntry^.Description;
  2531.                 NextPrintEntry^.TypeOfRecord := NextPrintEntry^.PrevEntry^.TypeOfRecord;
  2532.                 NextPrintEntry^.FileName := NextPrintEntry^.PrevEntry^.FileName;
  2533.                 NextPrintEntry^.FileSize := NextPrintEntry^.PrevEntry^.FileSize;
  2534.                 NextPrintEntry^.FileDate := NextPrintEntry^.PrevEntry^.FileDate;
  2535.                 NextPrintEntry^.Description := NextPrintEntry^.PrevEntry^.Description;
  2536.                 NextPrintEntry^.PrevEntry^.TypeOfRecord := TempSort^.TypeOfRecord;
  2537.                 NextPrintEntry^.PrevEntry^.FileName := TempSort^.FileName;
  2538.                 NextPrintEntry^.PrevEntry^.FileSize := TempSort^.FileSize;
  2539.                 NextPrintEntry^.PrevEntry^.FileDate := TempSort^.FileDate;
  2540.                 NextPrintEntry^.PrevEntry^.Description := TempSort^.Description;
  2541.                 Exchange := True;
  2542.               End;
  2543.               NextPrintEntry := NextPrintEntry^.PrevEntry;
  2544.             End;
  2545.           Until (Not Exchange);
  2546.           DisplayScreen;
  2547.         End;
  2548.         Dispose(TempSort);
  2549.       End;
  2550.     End;
  2551.   End;
  2552. {========================================================================}
  2553. Procedure SortListTime;
  2554.   Var
  2555.     TempSort : ListPtr;
  2556.     SortNext, SortPrev, Exchange : Boolean;
  2557.   Begin
  2558.     If (BeginSort <> NIL) And (EndSort <> NIL) And (BeginSort <> EndSort) Then
  2559.     Begin
  2560.       SortNext := False; SortPrev := False; Altered := True;
  2561.       If MaxAvail > Size(ListRecord) Then
  2562.       Begin
  2563.         New(TempSort);
  2564.         NextPrintEntry := BeginSort;
  2565.         While (NextPrintEntry <> EndSort) And (NextPrintEntry <> NIL) Do
  2566.         Begin
  2567.           NextPrintEntry := NextPrintEntry^.NextEntry;
  2568.           If NextPrintEntry = EndSort Then SortNext := True;
  2569.         End;
  2570.         NextPrintEntry := BeginSort;
  2571.         While (NextPrintEntry <> EndSort) And (NextPrintEntry <> NIL) Do
  2572.         Begin
  2573.           NextPrintEntry := NextPrintEntry^.PrevEntry;
  2574.           If NextPrintEntry = EndSort Then SortPrev := True;
  2575.         End;
  2576.         If SortNext Then
  2577.         Begin
  2578.           Repeat
  2579.             Exchange := False;
  2580.             NextPrintEntry := BeginSort;
  2581.             While NextPrintEntry <> EndSort Do
  2582.             Begin
  2583.               If NextPrintEntry^.FileDate > NextPrintEntry^.NextEntry^.FileDate Then
  2584.               Begin
  2585.                 TempSort^.TypeOfRecord := NextPrintEntry^.TypeOfRecord;
  2586.                 TempSort^.FileName := NextPrintEntry^.FileName;
  2587.                 TempSort^.FileSize := NextPrintEntry^.FileSize;
  2588.                 TempSort^.FileDate := NextPrintEntry^.FileDate;
  2589.                 TempSort^.Description := NextPrintEntry^.Description;
  2590.                 NextPrintEntry^.TypeOfRecord := NextPrintEntry^.NextEntry^.TypeOfRecord;
  2591.                 NextPrintEntry^.FileName := NextPrintEntry^.NextEntry^.FileName;
  2592.                 NextPrintEntry^.FileSize := NextPrintEntry^.NextEntry^.FileSize;
  2593.                 NextPrintEntry^.FileDate := NextPrintEntry^.NextEntry^.FileDate;
  2594.                 NextPrintEntry^.Description := NextPrintEntry^.NextEntry^.Description;
  2595.                 NextPrintEntry^.NextEntry^.TypeOfRecord := TempSort^.TypeOfRecord;
  2596.                 NextPrintEntry^.NextEntry^.FileName := TempSort^.FileName;
  2597.                 NextPrintEntry^.NextEntry^.FileSize := TempSort^.FileSize;
  2598.                 NextPrintEntry^.NextEntry^.FileDate := TempSort^.FileDate;
  2599.                 NextPrintEntry^.NextEntry^.Description := TempSort^.Description;
  2600.                 Exchange := True;
  2601.               End;
  2602.               NextPrintEntry := NextPrintEntry^.NextEntry;
  2603.             End;
  2604.           Until (Not Exchange);
  2605.           DisplayScreen;
  2606.         End;
  2607.         If SortPrev Then
  2608.         Begin
  2609.           Repeat
  2610.             Exchange := False;
  2611.             NextPrintEntry := BeginSort;
  2612.             While NextPrintEntry <> EndSort Do
  2613.             Begin
  2614.               If NextPrintEntry^.FileDate > NextPrintEntry^.PrevEntry^.FileDate Then
  2615.               Begin
  2616.                 TempSort^.TypeOfRecord := NextPrintEntry^.TypeOfRecord;
  2617.                 TempSort^.FileName := NextPrintEntry^.FileName;
  2618.                 TempSort^.FileSize := NextPrintEntry^.FileSize;
  2619.                 TempSort^.FileDate := NextPrintEntry^.FileDate;
  2620.                 TempSort^.Description := NextPrintEntry^.Description;
  2621.                 NextPrintEntry^.TypeOfRecord := NextPrintEntry^.PrevEntry^.TypeOfRecord;
  2622.                 NextPrintEntry^.FileName := NextPrintEntry^.PrevEntry^.FileName;
  2623.                 NextPrintEntry^.FileSize := NextPrintEntry^.PrevEntry^.FileSize;
  2624.                 NextPrintEntry^.FileDate := NextPrintEntry^.PrevEntry^.FileDate;
  2625.                 NextPrintEntry^.Description := NextPrintEntry^.PrevEntry^.Description;
  2626.                 NextPrintEntry^.PrevEntry^.TypeOfRecord := TempSort^.TypeOfRecord;
  2627.                 NextPrintEntry^.PrevEntry^.FileName := TempSort^.FileName;
  2628.                 NextPrintEntry^.PrevEntry^.FileSize := TempSort^.FileSize;
  2629.                 NextPrintEntry^.PrevEntry^.FileDate := TempSort^.FileDate;
  2630.                 NextPrintEntry^.PrevEntry^.Description := TempSort^.Description;
  2631.                 Exchange := True;
  2632.               End;
  2633.               NextPrintEntry := NextPrintEntry^.PrevEntry;
  2634.             End;
  2635.           Until (Not Exchange);
  2636.           DisplayScreen;
  2637.         End;
  2638.         Dispose(TempSort);
  2639.       End;
  2640.     End;
  2641.   End;
  2642. {========================================================================}
  2643.  
  2644.  
  2645. {========================================================================}
  2646. Function ValidFileName(FileName : MAXSTRING) : Boolean;
  2647.   Begin
  2648.     If (Pos('.',FileName) <= 9)
  2649.     And (RPos('.',FileName) <= 4)
  2650.     And (Length(FileName) > 0)
  2651.     And (Copy(FileName,1,1) <> '.') Then
  2652.     Begin
  2653.       ValidFileName := True;
  2654.     End
  2655.     Else
  2656.     Begin
  2657.       ValidFileName := False;
  2658.     End;
  2659.   End;
  2660. {========================================================================}
  2661. Procedure RenameFile;
  2662.   Var
  2663.     NewFileName : String[12];
  2664.     FileToRename : FILE OF char;
  2665.     Rfc : Char;
  2666.   Begin
  2667.     If CurrentEntry^.TypeOfRecord = FileRecord Then
  2668.     Begin
  2669.       AnsiGotoXY(25,1); AnsiClearToEOL;
  2670.       Write('Enter file name to rename '+CurrentEntry^.FileName+' to: ');
  2671.       OffSet := 31 + Length(CurrentEntry^.FileName);
  2672.       NewFileName := UpperString(EditLine('',12,25,OffSet));
  2673.       If ValidFileName(NewFileName) Then
  2674.       Begin
  2675.         attr := 0H;
  2676.         hndlhdir := HDIR_CREATE;
  2677.         count := 1;
  2678.         reslng := size(FILEFINDBUF);
  2679.         StrToZ(FileAreaPath+NewFileName,ztempstr);
  2680.         retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2681.           reslng,count,rsrvd);
  2682.         If retn <> 0 Then
  2683.         Begin
  2684.           AnsiGotoXY(25,1); AnsiClearToEOL;
  2685.           Write('Rename '+CurrentEntry^.FileName+' to '+NewFileName+' (Y/N)? ');
  2686.           Repeat
  2687.             Gbx := GetInput;
  2688.             Rfc := Upcase(chr(Gbx));
  2689.           Until Rfc In ['N','Y'];
  2690.           Write(Rfc);
  2691.           If Rfc = 'Y' Then
  2692.           Begin
  2693.             Altered := True;
  2694.             Assign(FileToRename,FileAreaPath+CurrentEntry^.FileName);
  2695.             Rename(FileToRename,FileAreaPath+NewFileName);
  2696.             CurrentEntry^.FileName := NewFileName;
  2697.             NextPrintEntry := CurrentEntry;
  2698.             DisplayRecord(Row); DisplayCurrentLocation;
  2699.           End;
  2700.         End;
  2701.       End;
  2702.       AnsiGotoXY(24,80);
  2703.     End;
  2704.   End;
  2705. {========================================================================}
  2706. Procedure FindString(TypeOfSearch : Char);
  2707.   Var
  2708.     Found : Boolean;
  2709.     Counter : Byte;
  2710.   Begin
  2711.     AnsiGotoXY(25,1); AnsiClearToEOL;
  2712.     Write('Enter string to search for: '+StringToFind);
  2713.     StringToFind := UpperString(EditLine(StringToFind,12,25,28));
  2714.     NextPrintEntry := CurrentEntry; Found := False;
  2715.     While (Not Found) And (NextPrintEntry^.NextEntry <> NIL) Do
  2716.     Begin
  2717.       NextPrintEntry := NextPrintEntry^.NextEntry;
  2718.       If Pos(StringToFind,UpperString(NextPrintEntry^.FileName)) > 0 Then Found := True;
  2719.       Case TypeOfSearch Of
  2720.         'B' : Begin
  2721.                 If Pos(StringToFind,UpperString(NextPrintEntry^.FileName)) > 0 Then Found := True;
  2722.                 If Pos(StringToFind,UpperString(NextPrintEntry^.Description)) > 0 Then Found := True;
  2723.               End;
  2724.         'D' : Begin
  2725.                 If Pos(StringToFind,UpperString(NextPrintEntry^.Description)) > 0 Then Found := True;
  2726.               End;
  2727.         'F' : Begin
  2728.                 If Pos(StringToFind,UpperString(NextPrintEntry^.FileName)) > 0 Then Found := True;
  2729.               End;
  2730.         Else      End;
  2731.     End;
  2732.     If Found Then
  2733.     Begin
  2734.       Counter := 10;
  2735.       CurrentEntry := NextPrintEntry;
  2736.       While (Counter > 1) And (NextPrintEntry^.PrevEntry <> NIL) Do
  2737.       Begin
  2738.         Counter:=Counter-1;
  2739.         NextPrintEntry := NextPrintEntry^.PrevEntry;
  2740.       End;
  2741.       TopEntry := NextPrintEntry;
  2742.       AnsiGotoXY(25,1); AnsiClearToEOL;
  2743.       Write(StringToFind+' found!');
  2744.       Row := 11 - Counter;
  2745.       DisplayScreen;
  2746.     End
  2747.     Else
  2748.     Begin
  2749.       AnsiGotoXY(25,1); AnsiClearToEOL;
  2750.       Write(StringToFind+' NOT found!');
  2751.       DisplayCurrentLocation;
  2752.     End;
  2753.   End;
  2754. {========================================================================}
  2755.  
  2756.  
  2757. {========================================================================}
  2758. Procedure ViewFile;
  2759.   Var
  2760.     Ext : String[3];
  2761.     ReturnCode : Int16;
  2762.     PathToUtility : PathStr;
  2763.   Begin
  2764.     If ReDirectTo = Console Then
  2765.     Begin
  2766.       If CurrentEntry^.TypeOfRecord In [FileRecord,Orphan] Then
  2767.       Begin
  2768.         If Pos('.',CurrentEntry^.FileName) > 0 Then
  2769.         Begin
  2770.           Ext := Copy(CurrentEntry^.FileName,Pos('.',CurrentEntry^.FileName)+1,
  2771.                Length(CurrentEntry^.FileName)-Pos('.',CurrentEntry^.FileName));
  2772.           AnsiClearScreen;
  2773. {          SetMemTop(HeapPtr); }
  2774. {          SwapVectors; }
  2775.           If Pos(Ext,'ARCARJLZHPAKZIPZOO') In [1,4,7,10,13,16] Then
  2776.           Begin
  2777.             Write('Loading SHEZ...');
  2778. {            PathToUtility := FSearch('SHEZ.EXE',GetEnv('PATH')); }
  2779. {            Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName); }
  2780.           End
  2781.           Else
  2782.           Begin
  2783.             Write('Loading LIST...');
  2784. {            PathToUtility := FSearch('LIST.COM',GetEnv('PATH')); }
  2785.             If PathToUtility = '' Then
  2786.             Begin
  2787. {              PathToUtility := FSearch('L.COM',GetEnv('PATH')); }
  2788.             End;
  2789. {            Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName); }
  2790.           End;
  2791. {          SwapVectors; }
  2792. {          SetMemTop(HeapEnd); }
  2793.           SetupScreen; DisplayScreen;
  2794.         End;
  2795.       End;
  2796.     End;
  2797.   End;
  2798. {========================================================================}
  2799. Procedure CallShez;
  2800.   Var
  2801.     ReturnCode : Int16;
  2802.     PathToUtility : PathStr;
  2803.   Begin
  2804.     If ReDirectTo = Console Then
  2805.     Begin
  2806.       If CurrentEntry^.TypeOfRecord In [FileRecord,Orphan] Then
  2807.       Begin
  2808.         If Length(CurrentEntry^.FileName) > 0 Then
  2809.         Begin
  2810.           AnsiClearScreen;
  2811. {          SetMemTop(HeapPtr); }
  2812.           Write('Loading SHEZ...');
  2813. {          SwapVectors; }
  2814. {          PathToUtility := FSearch('SHEZ.EXE',GetEnv('PATH')); }
  2815.           If Pos('.',CurrentEntry^.FileName) = 0 Then
  2816.           Begin
  2817. {            Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName+'.*'); }
  2818.           End
  2819.           Else
  2820.           Begin
  2821. {            Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName); }
  2822.           End;
  2823. {          SwapVectors; }
  2824. {          SetMemTop(HeapEnd); }
  2825.           SetupScreen; DisplayScreen;
  2826.         End;
  2827.       End;
  2828.     End;
  2829.   End;
  2830. {========================================================================}
  2831. Procedure CallList;
  2832.   Var
  2833.     ReturnCode : Int16;
  2834.     PathToUtility : PathStr;
  2835.   Begin
  2836.     If ReDirectTo = Console Then
  2837.     Begin
  2838.       If CurrentEntry^.TypeOfRecord In [FileRecord,Orphan] Then
  2839.       Begin
  2840.         If Length(CurrentEntry^.FileName) > 0 Then
  2841.         Begin
  2842.           AnsiClearScreen;
  2843. {          SetMemTop(HeapPtr); }
  2844.           Write('Loading LIST...');
  2845. {          SwapVectors; }
  2846. {          PathToUtility := FSearch('LIST.COM',GetEnv('PATH')); }
  2847.           If PathToUtility = '' Then
  2848.           Begin
  2849. {            PathToUtility := FSearch('L.COM',GetEnv('PATH')); }
  2850.           End;
  2851. {          Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName); }
  2852. {          SwapVectors; }
  2853. {          SetMemTop(HeapEnd); }
  2854.           SetupScreen; DisplayScreen;
  2855.         End;
  2856.       End;
  2857.     End;
  2858.   End;
  2859. {========================================================================}
  2860. Procedure CallVpic;
  2861.   Var
  2862.     ReturnCode : Int16;
  2863.     PathToUtility : PathStr;
  2864.   Begin
  2865.     If ReDirectTo = Console Then
  2866.     Begin
  2867.       If CurrentEntry^.TypeOfRecord In [FileRecord,Orphan] Then
  2868.       Begin
  2869.         If Length(CurrentEntry^.FileName) > 0 Then
  2870.         Begin
  2871.           AnsiClearScreen;
  2872. {          SetMemTop(HeapPtr); }
  2873.           Write('Loading VPIC...');
  2874. {          SwapVectors; }
  2875. {          PathToUtility := FSearch('VPIC.EXE',GetEnv('PATH')); }
  2876. {          Exec(FExpand(PathToUtility),FileAreaPath+CurrentEntry^.FileName); }
  2877. {          SwapVectors; }
  2878. {          SetMemTop(HeapEnd); }
  2879.           SetupScreen; DisplayScreen;
  2880.         End;
  2881.       End;
  2882.     End;
  2883.   End;
  2884. {========================================================================}
  2885. Procedure ShellToDos;
  2886.   Var
  2887.     ReturnCode : Int16;
  2888.   Begin
  2889.     AnsiClearScreen;
  2890. {    SetMemTop(HeapPtr); }
  2891.     WriteLn('Type EXIT to return...');
  2892. {    SwapVectors; }
  2893. {    Exec(GetEnv('COMSPEC'), ''); }
  2894. {    SwapVectors; }
  2895. {    SetMemTop(HeapEnd); }
  2896.     SetupScreen; DisplayScreen;
  2897.   End;
  2898. {========================================================================}
  2899.  
  2900.  
  2901. {========================================================================}
  2902. Procedure ParseCommandLine;
  2903.   Var
  2904.     x : Byte;
  2905.     FileAreaPathOk, AreaPathOk, OutputSelected : Boolean;
  2906.   Begin
  2907.     ReDirectTo := StandardIO; FileAreaPath := ''; Columns := 5; ColumnPos := 16;
  2908.     FileAreaPathOk := False; AreaPathOk := False; OutputSelected := False;
  2909. {    Assign(Input,''); }
  2910. {    Reset(Input); }
  2911. {    Assign(Output,''); }
  2912. {    ReWrite(Output); }
  2913.     WriteLn(Pgmid); {WriteLn;}
  2914.     WriteLn('Pre-Alpha version for testing ONLY, make backups please!');
  2915.     WriteLn;
  2916.     If ParamCount = 0 Then
  2917.     Begin
  2918.       ReDirectTo := Console;
  2919.       OutputSelected := True;
  2920. {      AssignCrt(Input); }
  2921. {      Reset(Input); }
  2922. {      AssignCrt(Output); }
  2923. {      ReWrite(Output); }
  2924.       Fsplit(ParamStr(0),D,N,E);
  2925.       AreaPath := D + 'AREA.DAT';
  2926.       GetAreaTable;
  2927.       If NumberOfAreaEntries < Columns Then Columns := NumberOfAreaEntries;
  2928.       SetupScreen;
  2929.       FileAreaPath := ChooseArea;
  2930.       If (FileAreaPath = 'QUIT') Or (FileAreaPath = 'QUITQUICK') Then
  2931.       Begin
  2932.         dos.exit(EXIT_PROCESS,250);
  2933. {        ABORT(250); }
  2934.       End;
  2935.     End
  2936.     Else
  2937.     Begin
  2938.       For x := 1 To ParamCount Do
  2939.       Begin
  2940.         If Copy(UpperString(ParamStr(x)),1,2) = '-A' Then
  2941.         Begin
  2942.           AreaPathOk := True;
  2943.           AreaPath := Copy(UpperString(ParamStr(x)),3,Length(ParamStr(x))-2);
  2944.           If Length(AreaPath) > 0 Then
  2945.           Begin
  2946.             attr := 0H;
  2947.             hndlhdir := HDIR_CREATE;
  2948.             count := 1;
  2949.             reslng := size(FILEFINDBUF);
  2950.             StrToZ(AreaPath,ztempstr);
  2951.             retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2952.               reslng,count,rsrvd);
  2953.             If retn <> 0 Then
  2954.             Begin
  2955.               If Copy(AreaPath,Length(AreaPath),1) <> '\' Then AreaPath := AreaPath + '\';
  2956.               attr := 0H;
  2957.               hndlhdir := HDIR_CREATE;
  2958.               count := 1;
  2959.               reslng := size(FILEFINDBUF);
  2960.               StrToZ(AreaPath+'AREA.DAT',ztempstr);
  2961.               retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  2962.                 reslng,count,rsrvd);
  2963.               If retn <> 0 Then
  2964.               Begin
  2965.                 WriteLn('AREA.DAT not found in '+AreaPath+' !');
  2966.                 dos.exit(EXIT_PROCESS,1);
  2967. {                ABORT(1); }
  2968.               End
  2969.               Else
  2970.               Begin
  2971.                 AreaPath := AreaPath + 'AREA.DAT';
  2972.               End;
  2973.             End;
  2974.           End;
  2975.         End;
  2976.         If Copy(UpperString(ParamStr(x)),1,2) = '-C' Then
  2977.         Begin
  2978.           OutputSelected := True;
  2979.           If Copy(ParamStr(x),3,1) = '0' Then
  2980.           Begin
  2981.             ReDirectTo := Console;
  2982. {            AssignCrt(Input);}
  2983. {            Reset(Input);}
  2984. {            AssignCrt(Output);}
  2985. {            ReWrite(Output);}
  2986.           End;
  2987.           If Copy(ParamStr(x),3,1) = '1' Then
  2988.           Begin
  2989.             ReDirectTo := ComPort1;
  2990.             Assign(Input,'Com1'); Reset(Input);
  2991.             Assign(Output,'Com1'); ReWrite(Output);
  2992.           End;
  2993.           If Copy(ParamStr(x),3,1) = '2' Then
  2994.           Begin
  2995.             ReDirectTo := ComPort2;
  2996.             Assign(Input,'Com2'); Reset(Input);
  2997.             Assign(Output,'Com2'); ReWrite(Output);
  2998.           End;
  2999.           If Copy(ParamStr(x),3,1) = '9' Then
  3000.           Begin
  3001.             ReDirectTo := StandardIO;
  3002. {            Assign(Input,''); Reset(Input);}
  3003. {            Assign(Output,''); ReWrite(Output);}
  3004.           End;
  3005.         End;
  3006.         If Copy(UpperString(ParamStr(x)),1,2) = '-P' Then
  3007.         Begin
  3008.           FileAreaPathOk := True;
  3009.           FileAreaPath := Copy(UpperString(ParamStr(x)),3,Length(ParamStr(x))-2);
  3010.           If Length(FileAreaPath) > 0 Then
  3011.           Begin
  3012.             If Copy(FileAreaPath,Length(FileAreaPath),1) <> '\' Then FileAreaPath := FileAreaPath + '\';
  3013.             attr := 0H;
  3014.             hndlhdir := HDIR_CREATE;
  3015.             count := 1;
  3016.             reslng := size(FILEFINDBUF);
  3017.             StrToZ(FileAreaPath+'*.*',ztempstr);
  3018.             retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  3019.               reslng,count,rsrvd);
  3020.             If retn <> 0 Then
  3021.             Begin
  3022.               WriteLn('Directory '+FileAreaPath+' not found!');
  3023.               dos.exit(EXIT_PROCESS,1);
  3024. {              ABORT(1); }
  3025.             End;
  3026.           End;
  3027.         End;
  3028.         If Copy(UpperString(ParamStr(x)),1,2) = '-K' Then
  3029.         Begin
  3030.           tempstr := Copy(ParamStr(x),3,1);
  3031.           Columns := StrToInt(tempstr,10,OK);
  3032. {          _VAL_INT(Copy(ParamStr(x),3,1),Columns,Result); }
  3033.           If Columns < 3 Then Columns := 3;
  3034.           If Columns > 8 Then Columns := 8;
  3035.         End;
  3036.       End;
  3037.       If Columns = 3 Then ColumnPos := 25;
  3038.       If Columns = 4 Then ColumnPos := 20;
  3039.       If Columns = 5 Then ColumnPos := 16;
  3040.       If Columns = 6 Then ColumnPos := 14;
  3041.       If Columns = 7 Then ColumnPos := 12;
  3042.       If Columns = 8 Then ColumnPos := 10;
  3043.       If (Not AreaPathOk) Then
  3044.       Begin
  3045.         Fsplit(ParamStr(0),D,N,E);
  3046.         AreaPath := D + 'AREA.DAT';
  3047.       End;
  3048.       GetAreaTable;
  3049.       If NumberOfAreaEntries < Columns Then Columns := NumberOfAreaEntries;
  3050.       If (Not OutputSelected) Then
  3051.       Begin
  3052.         ReDirectTo := Console;
  3053.         OutputSelected := True;
  3054. {        AssignCrt(Input); }
  3055. {        Reset(Input); }
  3056. {        AssignCrt(Output); }
  3057. {        ReWrite(Output); }
  3058.       End;
  3059.       SetupScreen;
  3060.       If (Not FileAreaPathOk) Then
  3061.       Begin
  3062.         FileAreaPath := ChooseArea;
  3063.         If (FileAreaPath = 'QUIT') Or (FileAreaPath = 'QUITQUICK') Then
  3064.         Begin
  3065.           dos.exit(EXIT_PROCESS,250);
  3066. {          ABORT(250); }
  3067.         End;
  3068.       End;
  3069.     End;
  3070.   End;
  3071. {========================================================================}
  3072. Procedure BuildSkipList;
  3073.   Var
  3074.     Bslb : Byte;
  3075.     InFile : Text;
  3076.   Begin
  3077.     For Bslb := 1 To MaxSkip Do SkipList[Bslb] := 'ACBDEFGHIJKL';
  3078.     Fsplit(ParamStr(0),D,N,E);
  3079.     attr := 0H;
  3080.     hndlhdir := HDIR_CREATE;
  3081.     count := 1;
  3082.     reslng := size(FILEFINDBUF);
  3083.     StrToZ(D+'MFM-SKIP.LST',ztempstr);
  3084.     retn := dos.FindFirst(ztempstr,hndlhdir,attr,DirInfo,
  3085.       reslng,count,rsrvd);
  3086.     If retn = 0 Then
  3087.     Begin
  3088.       Assign(InFile,D+'MFM-SKIP.LST');
  3089.       Reset(InFile);
  3090.       Bslb := 1;
  3091.       While (Not Eof(InFile)) And (Bslb < MaxSkip) Do
  3092.       Begin
  3093.         ReadLn(InFile,SkipList[Bslb]);
  3094.         Bslb:=Bslb+1;
  3095.       End;
  3096.       Close(InFile);
  3097.     End;
  3098.   End;
  3099. {========================================================================}
  3100. Begin
  3101.   Altered := False; BeginSort := NIL; EndSort := NIL;
  3102.   Base153 := Base153A + Base153B + Base153C;
  3103.   ParseCommandLine;
  3104.   BuildSkipList;
  3105.   NumberOfEntries := 0;
  3106.   BuildList;
  3107.   StringToFind := '';
  3108.   If NumberOfEntries = 0 Then
  3109.   Begin
  3110.     AnsiGotoXY(25,1);
  3111.     AnsiClearToEOL;
  3112.     Write('This area contains no files!');
  3113.     Repeat
  3114.       FileAreaPath := ChooseArea;
  3115.       NumberOfEntries := 0; BuildList;
  3116.       If NumberOfEntries = 0 Then
  3117.       Begin
  3118.         AnsiGotoXY(25,1);
  3119.         AnsiClearToEOL;
  3120.         Write('This area contains no files!');
  3121.       End;
  3122.     Until NumberOfEntries > 0;
  3123.   End;
  3124.   If NumberOfEntries > 0 Then
  3125.   Begin
  3126.     Row := 1;
  3127.     CurrentEntry := FirstEntry;
  3128.     TopEntry := FirstEntry;
  3129.     DisplayScreen;
  3130.     Repeat
  3131.       Gcx := Upcase(FileAreaPath[1]);
  3132.       AnsiGotoXY(24,1);
  3133.       NewTextColor(Black);
  3134.       NewTextBackground(Cyan);
  3135.       FreeSpace := DiskFree(Ord(Gcx)-64) Div 1024;
  3136.       AnsiClearToEOL;
  3137.       Write(' Number of files = '+MyStr(NumberOfFiles,3)
  3138.             +'   Size of files = '+Bytes(SizeOfFiles Div 1024)
  3139.             +'   Free space = '+Bytes(FreeSpace)
  3140.             +'   ? = Help');
  3141.       NewTextColor(White);
  3142.       NewTextBackground(Black);
  3143.       AnsiGotoXY(25,1);
  3144.       AnsiClearToEOL;
  3145.       Write(FileAreaPath);
  3146.       AnsiGotoXY(24,80);
  3147.       Gbx := GetInput;
  3148.       Gcx := Upcase(Chr(Gbx));
  3149.       If Gbx = 0 Then
  3150.       Begin
  3151.         Gbx := GetInput;
  3152.         Case Gbx Of
  3153.           31 : Begin         { ALT-S }
  3154.                  ShellToDos;
  3155.                  Gcx := chr(0);
  3156.                End;
  3157.           33 : Begin         { ALT-F }
  3158.                  CallShez;
  3159.                  Gcx := chr(0);
  3160.                End;
  3161.           38 : Begin         { ALT-L }
  3162.                  CallList;
  3163.                  Gcx := chr(0);
  3164.                End;
  3165.           44 : Begin         { ALT-Z }
  3166.                  CallVpic;
  3167.                  Gcx := chr(0);
  3168.                End;
  3169.           47 : Begin         { ALT-V }
  3170.                  ViewFile;
  3171.                  Gcx := chr(0);
  3172.                End;
  3173.           72 : Gcx := '8';
  3174.           80 : Gcx := '2';
  3175.           73 : Gcx := '9';
  3176.           81 : Gcx := '3';
  3177.           71 : Gcx := '7';
  3178.           79 : Gcx := '1';
  3179.           Else        End;
  3180.       End;
  3181.       Case Gcx Of
  3182.         chr(1)  : AdoptAllOrphans;
  3183.         chr(2)  : FindString('B');
  3184.         chr(4)  : FindString('D');
  3185.         chr(6)  : FindString('F');
  3186.         chr(17)  : Begin
  3187.                 If Altered Then SaveList;
  3188.                 dos.exit(EXIT_PROCESS,0);
  3189. {                ABORT(0); }
  3190.               End;
  3191.         chr(24)  : Begin
  3192.                 If CurrentEntry^.PrevEntry <> NIL Then
  3193.                   Begin
  3194.                     CurrentEntry^.Description := CurrentEntry^.PrevEntry^.Description;
  3195.                     NextPrintEntry := CurrentEntry;
  3196.                     DisplayRecord(Row);
  3197.                     DisplayCurrentLocation;
  3198.                   End;
  3199.               End;
  3200.         ' ' : Begin
  3201.                 CurrentEntry^.Tagged := (Not CurrentEntry^.Tagged);
  3202.                 LineDown;
  3203.                 If CurrentEntry^.NextEntry = NIL Then DisplayCurrentLocation;
  3204.               End;
  3205.         '8' : LineUp;
  3206.         '2' : LineDown;
  3207.         '9' : PageUp;
  3208.         '3' : PageDown;
  3209.         '7' : TopOfList;
  3210.         '1' : BottomOfList;
  3211.         '#' : MassMove;
  3212.         '$' : MassCopy;
  3213.         'A' : AdoptAbandon(1);
  3214.         'C' : CopyFile;
  3215.         'D' : ChangeFileDate;
  3216.         'E' : EditDescription;
  3217.         'F' : BeginSort := CurrentEntry;
  3218.         'I' : InsertBlank;
  3219.         'K' : PushRecord(KillEntry);
  3220.         'L' : EndSort := CurrentEntry;
  3221.         'M' : MoveFile;
  3222.         'N' : ChooseNewArea;
  3223.         'Q' : Quit;
  3224.         'R' : RenameFile;
  3225.         'S' : SortList;
  3226.         'T' : SortListTime;
  3227.         'U' : PopRecord(KillEntry,'B');
  3228.         'W' : SaveList;
  3229.         '<' : PushRecord(StackEntry);
  3230.         '>' : PopRecord(StackEntry,'A');
  3231.         ',' : PushRecord(StackEntry);
  3232.         '.' : PopRecord(StackEntry,'B');
  3233.         '[' : StackPrev(StackEntry);
  3234.         ']' : StackNext(StackEntry);
  3235.         ';' : ShowStack(StackEntry);
  3236.         '{' : StackPrev(KillEntry);
  3237.         '}' : StackNext(KillEntry);
  3238.         ':' : ShowStack(KillEntry);
  3239.         '!' : ReDrawScreen;
  3240.         '?' : Help;
  3241.         Else      End;
  3242.     Until Gcx = chr(255);
  3243.   End;
  3244. End.
  3245. {========================================================================}
  3246.