C-------------------------------------------------------------------
C Get_FileNames: Get all the file information into the Files_Display.
C   Current_Dir_FileName - The real name of the "THIS" directory
C			   (Complete name of .DIR file at next level up).
C   Could_Not_Load - Set to .TRUE. if I couldn't open 'Current_Dir_FileName'
C If Menu = More, (or Next_Menu = More) then the attributes are also obtained.
C-------------------------------------------------------------------
C*****************************************************************************
C
C  Revisions (Version 6.x)            July, 1986
C	Dale E. Coy
C	Los Alamos National Laboratory
C	(505) 667-3270
C
C	October 1986 - Add ability to handle case where a .DIR file is
C	not really a directory (IS_DIR Function).
C
C*****************************************************************************
C
C	Lastline = the file reference of the last valid entry.
C	FirstUsed = the file reference of the first filename
C		(4 if the first file is a .DIR, 6 if there is no .DIR
C		and the first file is a regular file, and 7 if there
C		are no files).
C	Note:  	If FirstUsed = 4, then SOMEWHERE below there are two lines:
C		(Blanks)
C		Files:        (This will be LastLine if no regular files)
C
C		If FirstUsed = 6, then you don't have to worry about 
C		anything else before LastLine
C
C		If FirstUsed = 7, then you don't have to do anything -
C		but good code can usually go ahead and execute.
C
C	The first 3 lines are always "garbage"
C
C	The Variables:
C		NumDirs, NumFiles
C		First_File (Default = 0)
C		Last_File  (Default = -1)
C      		First_Dir  (Default = 0)
C		Last_Dir   (Default = -1)
C	are set appropriately.
C
C        Total_Blks = 0, or is set as appropriate if attributes are loaded.
C
C-------------------------------------------------------------------
C	GetFileNames sets Current_Line (and TopLine, if necessary) to valid
C	values - by a rather brute force technique.  However, it
C	will preserve valid values if possible.
C-------------------------------------------------------------------
C  GET_FileNames attempts to read all of the files in the Current directory
C	which match the "wildcard" spec, (or which are .DIRs).
C  Could_Not_Load (Logical) is set appropriately.
C-------------------------------------------------------------------
C  IMPORTANT NOTE:  EACH CHANGE TO GET_FILENAMES SHOULD BE CONSIDERED FOR
C	INCORPORATION IN GET_ATTRIBUTES - FOR IDENTICAL OPERATION.
C------------------------------------------------------------------------------

       Subroutine Get_FileNames ( Could_Not_Load, Next_Menu )
       Implicit Integer*4 (A - Z)
       Logical Could_Not_Load, XTra_Check	
       Character*1 C
       Character*5 Numbers	
       Character*8 Nblks	
       Character*23 Date	
       Character*20 XCard	! Same length as WildCard	
       Integer*4 I, Next_Menu
       Integer*4 New_Display_Length
       Integer*2 Name_Size, XCard_Length	

       External  Str$match_wild, Str$_nomatch 
       Integer*4 Str$match_wild, Str$_nomatch, Nomatch_value, STAT

       Include 'Common.Dat'
       Character*(Attributes_Display_Width) file_info

	EXTERNAL IS_DIR
	Integer*2 Is_Dir_Channel   ! For use by UserOpen 
        Common /Dir_Channel/ Is_Dir_Channel
	
C      	WILDCARD IS A 20 CHAR STRING FROM THE /WILD/ COMMON BLOCK
C		MAKE SURE WILDCARD IS UPPER CASE!
C-------------------------------------------------------------------C

        Could_Not_Load = .FALSE.
        ReLoad         = .FALSE.	

C	 	  Assign a channel to "Channel";
C
	Status = Sys$Assign (%Descr(Current_Device),
	1		%Ref(Is_Dir_Channel),,)
C			NOTE THAT THE TRAILING COMMAS ARE REQUIRED

	

C		Open with all parameters of a "real" .DIR, so that
C		an error will probably indicate an invalid .dir file
        Open(Unit=1, File=Current_Dir_FileName, 
	1	Access = 'SEQUENTIAL', Carriagecontrol = 'NONE',
	2	Recl = 512, RecordType = 'VARIABLE',
	3	NoSpanBlocks, Status='OLD', READONLY, Shared, 
C 	3	NoSpanBlocks, Status='OLD', READONLY, 
	4	IOSTAT = IOX, UserOpen = Is_Dir, ERR=40)  
C
C --NOTE-- Opening SHARED seems to crash on CLOSE with V4.4
C BUT does not crash using VMS 4.5 and FORTRAN 4.6
C

C 		Deassign the channel (note use of %Val);
       	Status = Sys$Dassgn (%Val(Is_Dir_Channel))
	Is_Dir_Channel = -9999

        Goto 50

40	Status = Sys$Dassgn (%Val(Is_Dir_Channel))
	Is_Dir_Channel = -9999
	Call Rooted_Dir (Could_Not_Load, IOX)

	If (Could_Not_Load) then
	        GoTo 1100  ! Early exit 
	Else
		GoTo 50    ! Got it anyway
	End If


50     Continue

        NumFiles = 0
        NumDirs  = 0

	K = Lib$MatchC(';',WildCard) 
	If (K .LE. 0) then
		XCard = WildCard
		XCard_Length = WildCard_Length
		XTra_Check = .FALSE.
	Else
		XCard_Length = MAX(K-1,1)
		XCard = WildCard(:XCard_Length)
		XTra_Check = .TRUE.
	End If

	If (.NOT.Line23MSG_On)
     1          Call Mess_Line(' Reading Directory '//
	2			Current_Dir_FileName(1:62))

C	    This is the format, if there are no files at all.
C       Ld(1) = This_Directory_Line
C       Ld(2) = Blanks
C       Ld(3) = Directories_Line
C       Ld(4) = Blanks
C       Ld(5) = Files_Line
C       Ld(6) = Blanks
C       Ld(7) = Blanks                  
 	
        Gx = Lib$Matchc('[000000.000000', Current_Dir)
        If (Gx .NE. 0) then
	 	Current_Dir = '[000000]'
        End If   

	K = Lib$Matchc(']',Current_Dir)


C		SMG STUFF BEGINS HERE                    
	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)


C		SET DIRECTORY DISPLAY

	Call SMG$Erase_Chars (Directory_Display,69,1,12)

	Call SMG$Put_Chars (Directory_Display,%Descr(Current_Dir(1:K)),       
	1	1,12)

	Call SMG$Put_Chars (Directory_Display,
	1	%Descr(WILDCARD(1:wildcard_length)),1,
	2	%Ref(K+13))
	
	Dir_Display_Pos = (68 - K - WildCard_Length)

	If (Next_Menu .EQ. More_Mode) then
		Dir_Display_Pos = Dir_Display_Pos - 15
	Else If (Blocks_On) then
		   Call SMG$Unpaste_Virtual_Display
	1		(Blocks_Display,Pasteboard_ID)
		   Blocks_On = .FALSE.
	End If
	

	Call SMG$Move_Virtual_Display (Directory_Display,
	1	Pasteboard_ID,23,%Ref(Dir_Display_Pos))


C		SET DISPLAY LENGTH TO SOMETHING REASONABLE.

	If ((Current_Display_Length.GT.(6*Initial_Display_Length)).OR.
	1   (Current_Display_Length.LT.(  Initial_Display_Length)))
	2	Current_Display_Length = Initial_Display_Length

             
	If ((K+18) .GT. Initial_Files_Width) then
	    	Call SMG$Change_Virtual_Display
	1		(Files_Display,Current_Display_Length,K+18)
		Current_Files_Width = K+18
	Else
	    	Call SMG$Change_Virtual_Display
	1		(Files_Display,Current_Display_Length,
	2		 Initial_Files_Width)
		Current_Files_Width = Initial_Files_Width
	End If

	    	Call SMG$Change_Virtual_Display
	1		(Attributes_Display,Current_Display_Length,
	2		 Attributes_Display_Width)



 	Call SMG$Erase_Display(Files_Display)
	Call SMG$Erase_Display(Attributes_Display)

	If (Next_Menu .NE. Menu) Call SetChoices (Next_Menu)

	Call SMG$Put_Line (Files_Display,This_Directory_Line,2)
	Call SMG$Put_Line (Files_Display,Directories_Line,2)
	Call SMG$Put_Line (Files_Display,Files_Line,1)

	Call SMG$Put_Chars (Files_Display,Current_Dir(:K),1,18)       

	Call SMG$Put_Chars (Attributes_Display,
	1	Current_Dir(File_Attr_Pos-17:),1,1)

	If (K .LT. 43) then
		Call Lib$Date_Time (Date)
		Call SMG$Put_Chars (Attributes_Display,
	1		Date(:17),1,Attributes_Display_Width - 18)
	End If


C		THIS WOULD BE NICE, BUT THERE IS A BUG IN THE
C		V4.3 SMG$ ROUTINES THAT CAUSES IT TO BLOW UP
C		IF THE TOP LINE IS AT THE TOP OF THE SCREEN
C		(TopLine = 2).  THIS PUTS THE LABEL ON "Line 0",
C		AND WE GET AN ACCESS VIOLATION.  I THINK THAT A
C		FIX TO UPARROW AND DOWNARROW PATCHES THE PROBLEM -
C		BUT WATCH FOR IT.
C		
	C = Current_Dir(File_Attr_Pos-18:)
	If (VT300) then
            Call SMG$Label_Border (Attributes_Display,C,SMG$K_Left,2,
	1			BR_Mask)
	Else
            Call SMG$Label_Border (Attributes_Display,C,SMG$K_Left,2,
	1			SMG$M_Reverse)
	End If
		
        FirstUsed = 0   ! Index of 1st element used (0, 4, or 6)
		       !  (If 0, will be "brute forced" to 7 at end.
	IncluCount = 0
        NextDir    = 4     
        FileLine   = 5
        LastLine   = 5
        Total_Blks = 0
	First_File = 0
	Last_File  = -1
	First_Dir  = 0
	Last_Dir   = -1
	Nomatch_value = %loc( str$_nomatch)

	If (Menu .EQ. More_Mode) then
		Have_More = .TRUE.
        Else
		Have_More = .FALSE.
	End If
	
C
C	UNTIL MATCH BETWEEN WILDCARD AND FILE NAME
C

100    Read(1,200,End=900,Err=40)RecSize,Size,BigRec(1:RecSize-4)
200    Format(Q, 3X, A1, A) ! Read Variable sized rec from dir file

 	STAT = STR$MATCH_WILD
	1		(BIGREC(1:size),XCARD(1:Xcard_length))

	If ((Xtra_Check) .OR. (STAT .EQ. nomatch_value)) then
		Itsa_Dir = .FALSE.	! Provisionally
		GoTo 220
	Else  IF (STAT .NE. nomatch_value) then
		GoTo 250
	Else
		GoTo 100
	End If



C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C Programmer's Choice:  Always display all .DIR files
C	Comment out this block, and remove 'C' above, to display
C	only matched directories.
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
220	IF (Size .LT. 4)  then 	            ! It couldn't be a .DIR
		IF (STAT .EQ. nomatch_value) then
			GOTO 100
		Else
			GoTo 250
		End If
	End If

	IF (BIGREC(size-3:size) .NE. '.DIR') then ! Not a .DIR;

		IF (STAT .EQ. nomatch_value) then
			GoTo 100    ! No match and No .DIR
C						so read another record.
		Else
			GoTo 250    ! Regular File matching XWild
		End If

	Else  ! .DIR; file
		Itsa_Dir = .TRUE.
		GoTo 250
	End If

C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
C	END UNTIL WILDCARD MATCH
C

250    NHold = BigRec(1 : Size)
       Semi = Size + 1
       NHold(Semi : Semi) = ';' ! Put in semicolon 
       T = Size + 1             ! Point to 1st version number
       T = (T/2)*2 + 1          ! Ensure it is an odd number
300    Continue                 ! Encode version number into string
       Temp = IChar(BigRec(T:T)) + 256 * IChar(BigRec(T+1:T+1))
       
	If (Temp.le.9) then
	  	        Write (NHold(size+2:size+2),410) Temp
			Name_Size = Size+2
	Else If (Temp.le.99) then
	  	        Write (NHold(size+2:size+3),420) Temp
			Name_Size = Size+3
 	     Else If (Temp.le.999) then
	  	        Write (NHold(size+2:size+4),430) Temp
			Name_Size = Size+4
	          Else If (Temp.le.9999) then
	  	        Write (NHold(size+2:size+5),440) Temp
			Name_Size = Size+5
	               Else
			Write (NHold(size+2:size+6),450) Temp
		   	Name_Size = Size+6
	End If
		
410	Format(I1)
420	Format(I2)
430	Format(I3)
440	Format(I4)     
450	Format(I5)      

	If ((Xtra_Check) .AND. (.NOT.Itsa_Dir)) then ! Must check full wildcard again.
	 	STAT = STR$MATCH_WILD
	1		(NHold(1:Name_size),
	2		 WILDCARD(1:Wildcard_length))

		IF (STAT .EQ. nomatch_value) GOTO 100
	End If

	If ((Name_Size+Name_Pos + 1) .GT. Current_Files_Width) then
		Current_Files_Width = Name_Size + Name_Pos + 1

	    	Call SMG$Change_Virtual_Display
	1		(Files_Display,Current_Display_Length,
	2		 %Ref(Current_Files_Width))

		Call SMG$Erase_Display
	1		(Files_Display,LastLine+1,
	2		 1,Current_Display_Length,
	3		 %Ref(Current_Files_Width))

	End If



C-----------------------------------------------------------------C
C Got the name in 'NHold' - now put it in the Files display       C
C-----------------------------------------------------------------C



C       LdHold = NHold             ! Save Nhold for 
    				  ! passing to make_file_prot_string
       LdHold(Name_Pos:)=NHold
       LdHold(1:Name_Pos-1) = '  '! Make the 1st  chars blank

       LastLine = LastLine + 1    ! Bump lastline
C       If (LastLine .GT. 1000) Goto 900 ! Exit--array is full

        If (LastLine .GT. Current_Display_Length) then	
		New_Display_Length
	1	   = Current_Display_Length + Display_Length_Increment

	    	Call SMG$Change_Virtual_Display
	1		(Files_Display,%Ref(New_Display_Length),
	2		 %Ref(Current_Files_Width))
		Call SMG$Erase_Display
	1		(Files_Display,Current_Display_Length+1,
	2		 1,New_Display_Length,%Ref(Current_Files_Width))

	    	Call SMG$Change_Virtual_Display
	1		(Attributes_Display,%Ref(New_Display_Length),
	2		 Attributes_Display_Width)
		Call SMG$Erase_Display
	1		(Attributes_Display,Current_Display_Length+1,
	2		 1,New_Display_Length,Attributes_Display_Width)


		Current_Display_Length = New_Display_Length
	End If

                                                                        
C-----------------------------------------------------------------
C for displaying all the info
C-----------------------------------------------------------------
       If (Menu .EQ. More_Mode) then
    	 Call Make_file_prot_string ( File_Info )
	 Total_Blks = Total_Blks + File_Siz
	 
       End If !Menu =  (MORE mode) but NOT (INFO mode)

C	    The following is about the best we can do to guarantee
C		that we don't get "false" directories, without
C 		actually opening the files...........
       I = Lib$Matchc('.DIR;',LdHold)

       If (I .EQ. 0) then                  ! Was it a dir?
C		FILE FILE FILE FILE
	    If (Menu .EQ. More_Mode) then    	

		Call SMG$Set_Cursor_Abs 
	1		(Attributes_Display,LastLine,1)
		Call SMG$Put_Line
	1		(Attributes_Display,File_Info,0)

C		Call SMG$Put_Chars
C	1		(Attributes_Display,File_Info,LastLine,
C	2		 1,1)

	    End If        

	 Call SMG$Set_Cursor_Abs (Files_Display,LastLine,1)
	 Call SMG$Put_Line       (Files_Display,LdHold,0)

         If (FirstUsed .EQ. 0) FirstUsed = Lastline
         NumFiles = NumFiles + 1
	 Last_File = LastLine
       Else

C		DIRECTORY DIRECTORY DIRECTORY

		Call SMG$Insert_Line
	1		(Files_Display,NextDir,LdHold,SMG$M_Down)

	    If (Menu .EQ. More_Mode) then	

		Call SMG$Insert_Line
	1		(Attributes_Display,NextDir,File_Info,
	2		 SMG$M_Down)
	    End If

C		Brute Force is Faster
           FirstUsed = 4
	   First_Dir = 4

	 Last_Dir = NextDir
         NextDir = NextDir + 1
         NumDirs = NumDirs + 1
         FileLine = FileLine + 1
	 If (NumFiles .GT. 0) then
		Last_File  = Last_File + 1
	 End If
       End If
                
       T = T + 8                           ! Version #'s are 8 apart
       If (T .LT. RecSize - 4) then        !Done all versions?
		NHold(Size+2:Size+6) = '     '    ! Clear from last version!
		GoTo 300
       Else	
	        Goto 100                   ! YES-get next record
       End If	

C-------------------------------------------------------------------C
C Display(s) have all the names of files and directories.           C
C-------------------------------------------------------------------C
900    Continue          
       Close(1)                 ! Close the directory file


                                          
	Write(Numbers,401) NumDirs
401	Format (I5)

	Call SMG$Put_Chars (Files_Display,Numbers,3,26)
C	Call SMG$Put_Chars (Attributes_Display,Numbers,3,1)

	Write(Numbers,401) NumFiles
	Call SMG$Put_Chars (Files_Display,Numbers,FileLine,26)
C	Call SMG$Put_Chars (Attributes_Display,Numbers,FileLine,1)

	Write(Nblks,402) Total_Blks
402	Format (I8)
	Call SMG$Put_Chars (Blocks_Display,Nblks,1,1)
	If (Have_More) then
		Call SMG$Paste_Virtual_Display 
	1		(Blocks_Display,Pasteboard_ID,23,65)
		Blocks_On = .TRUE.
	End If                 
                 

C	Trim the display back to minimum.

	Current_Display_Length = LastLine

    	Call SMG$Change_Virtual_Display
	1		(Files_Display,Current_Display_Length,
	2		 %Ref(Current_Files_Width))

    	Call SMG$Change_Virtual_Display
	1		(Attributes_Display,Current_Display_Length,
	2		 Attributes_Display_Width)


C	Brighten the Top Line  of Files_Display Here!!!!!!!!!!

	If (VT300) then
	    Call SMG$Change_Rendition (Files_Display,
	1	1,1,1,%Ref(Current_Files_Width),BR_Mask)
	    Call SMG$Change_Rendition (Attributes_Display,
	1	1,1,1,Attributes_Display_Width,BR_Mask)
	Else
	    Call SMG$Change_Rendition (Files_Display,
	1	1,1,1,%Ref(Current_Files_Width),SMG$M_Reverse)
	    Call SMG$Change_Rendition (Attributes_Display,
	1	1,1,1,Attributes_Display_Width,SMG$M_Reverse)
	End If
	
C		Directories Line
	Call SMG$Change_Rendition (Files_Display,
	1	3,Name_Pos,1, %Ref(Current_Files_Width-Name_Pos+1),
	2	SMG$M_UnderLine)

	Call SMG$Change_Rendition (Attributes_Display,
	1	3,1,1,5,SMG$M_UnderLine)

C		Files Line
	Call SMG$Change_Rendition (Files_Display,
	1	FileLine,Name_Pos,1,%Ref(Current_Files_Width-Name_Pos+1),
	2	SMG$M_UnderLine)

	Call SMG$Change_Rendition (Attributes_Display,
	1	FileLine,1,1,5,SMG$M_UnderLine)



	Call SMG$End_Pasteboard_Update (Pasteboard_ID)
C--------------------

	Call Fix23

        If (FirstUsed .EQ. 0) FirstUsed = 7 !dir empty-point at spaces
	If (NumFiles .GT. 0) First_File = FileLine + 1


	If (.NOT.(((Current_Line .GE. First_Dir).AND.
	1	   (Current_Line .LE. Last_Dir ))      .OR.

	3         ((Current_Line .GE. First_File).AND.
	4	   (Current_Line .LE. Last_File )))    ) then
 
	       Topline = 1	
	       Current_Line = FirstUsed	
	Else
C		   Make sure we can "see" the Current_Line
		TopLine = MAX (TopLine, Current_Line - 21)
		If (TopLine .EQ. 2) TopLine = 3
		TopLine = MIN (TopLine, Current_Line)
	End If


1100   Continue

       Return
       End
                    
C-------------------------------------------------------------------------------
C Get_Attributes: Get the file attribute information into the Attributes Display
C   Current_Dir_FileName - The real name of the "THIS" directory                
C			     (Filename of .DIR in next directory upward)
C-------------------------------------------------------------------------------
C  Note that it is extremely important that this subroutine and
C  Get_FileNames act identically - otherwise behavior is unpredictable.
C  The assumption is made that Get_FileNames has set everything correctly
C-------------------------------------------------------------------------------
C  GET_ATTRIBUTES attempts to read all of the files in the Current directory.
C-------------------------------------------------------------------------------

       Subroutine Get_Attributes
       Implicit Integer*4 (A - Z)
       Character*1 C
       Character*8 Nblks	
       Character*23 Date	
       Integer*4 I 
       Include 'Common.Dat'
       Character*(Attributes_Display_Width) file_info

C	WILDCARD IS A 20 CHAR STRING FROM THE /WILD/ COMMON BLOCK
C		MAKE SURE WILDCARD IS UPPER CASE!
C-------------------------------------------------------------------C

       Call Mess_Line(' Reading Files in '//Current_Dir(1:78))

	
C		SMG STUFF BEGINS HERE

	Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)


C		SET DIRECTORY DISPLAY
	Dir_Display_Pos = Dir_Display_Pos - 15

	Call SMG$Move_Virtual_Display (Directory_Display,
	1	Pasteboard_ID,23,%Ref(Dir_Display_Pos))


C	     ASSUME DISPLAY LENGTH TO BE SAME AS FILES DISPLAY

C	    	Call SMG$Change_Virtual_Display
C	1		(Attributes_Display,Current_Display_Length,
C	2		 Attributes_Display_Width)

C		AND SHOULD ALREADY BE CLEAR.
C	Call SMG$Erase_Display(Attributes_Display)

        
        Gx = Lib$Matchc('[000000.000000', Current_Dir)
        If (Gx .NE. 0) then
	 	Current_Dir = '[000000]'
        End If

	K = Lib$Matchc(']',Current_Dir)

	Call SMG$Put_Chars (Attributes_Display,
	1	Current_Dir(File_Attr_Pos-17:),1,1)

	If (K .LT. 43) then
		Call Lib$Date_Time (Date)
		Call SMG$Put_Chars (Attributes_Display,
	1		Date(:17),1,Attributes_Display_Width - 18)
	End If

C		THIS WOULD BE NICE, BUT THERE IS A BUG IN THE
C		V4.3 SMG$ ROUTINES THAT CAUSES IT TO BLOW UP
C		IF THE TOP LINE IS AT THE TOP OF THE SCREEN
C		(TopLine = 2).  THIS PUTS THE LABEL ON "Line 0",
C		AND WE GET AN ACCESS VIOLATION.  I THINK THAT A
C		FIX TO UPARROW AND DOWNARROW PATCHES THE PROBLEM -
C		BUT WATCH FOR IT.
C		
	C = Current_Dir(File_Attr_Pos-18:)
	If (VT300) then
            Call SMG$Label_Border (Attributes_Display,C,SMG$K_Left,2,
	1			BR_Mask)
	Else
            Call SMG$Label_Border (Attributes_Display,C,SMG$K_Left,2,
	1			SMG$M_Reverse)
	End If
	

	Have_More = .TRUE.
        Total_Blks = 0

	
C
C		READ DIRECTORY FILES
C
      If (NumDirs .GT. 0) then
	Call SMG$Set_Cursor_Abs (Attributes_Display,%Ref(First_Dir),1)

	DO 100 I = First_Dir, Last_Dir

	   Call SMG$Set_Cursor_Abs (Files_Display,%Ref(I),Name_Pos)
	   Call SMG$Read_From_Display (Files_Display,NHold)

    	   Call Make_file_prot_string ( file_info )
	   Total_Blks = Total_Blks + File_Siz

	   Call SMG$Put_Line (Attributes_Display,File_Info,1)

100	Continue

      End If


C
C		READ REGULAR FILES
C
      If (NumFiles .GT. 0) then
	Call SMG$Set_Cursor_Abs (Attributes_Display,%Ref(First_File),1)

	DO 200 I = First_File, Last_File

 	   Call SMG$Set_Cursor_Abs (Files_Display,%Ref(I),Name_Pos)
	   Call SMG$Read_From_Display (Files_Display,NHold)

    	   Call Make_file_prot_string ( file_info )
	   Total_Blks = Total_Blks + File_Siz

	   Call SMG$Put_Line (Attributes_Display,File_Info,1)

200	Continue

      End If


C-------------------------------------------------------------------C
C Attributes Display has all the information.                       C
C-------------------------------------------------------------------C


	Write(Nblks,402) Total_Blks
402	Format (I8)
	Call SMG$Put_Chars (Blocks_Display,Nblks,1,1)
	If (Have_More) then
		Call SMG$Paste_Virtual_Display 
	1		(Blocks_Display,Pasteboard_ID,23,65)
		Blocks_On = .TRUE.
	End If                 

C	Brighten the Top Line  of Attributes_Display Here!
	If (VT300) then
	    Call SMG$Change_Rendition (Attributes_Display,
	1	1,1,1,Attributes_Display_Width,BR_Mask)
	Else
	    Call SMG$Change_Rendition (Attributes_Display,
	1	1,1,1,Attributes_Display_Width,SMG$M_Reverse)
	End If
	
C		Directories Line
	Call SMG$Change_Rendition (Attributes_Display,
	1	3,1,1,5,SMG$M_UnderLine)

C		Files Line
	Call SMG$Change_Rendition (Attributes_Display,
	1	FileLine,1,1,5,SMG$M_UnderLine)


	Call SMG$End_Pasteboard_Update (Pasteboard_ID)
C--------------------

	Call Fix23


1100   Continue
       Return
       End
                    
C-------------------------------------------------------------------
C Rooted_Dir:
C   Attempts to recover from "could not open" condition, if we are
C   at [000000]
C-------------------------------------------------------------------
C------------------------------------------------------------------------------

        Subroutine Rooted_Dir ( Could_Not_Load, IOX )
        Implicit Integer*4 (A - Z)
	Integer*2 K, I, KK, ItsK
        Logical Could_Not_Load	
        Character*80 Temp_Device	

	EXTERNAL IS_DIR
	Integer*2 Is_Dir_Channel   ! For use by UserOpen 
        Common /Dir_Channel/ Is_Dir_Channel

        Include 'Common.Dat'
	Include	'($LNMDEF)'
                                                
	Structure /TrnLnm_Item_List/
	  Integer*2 BufLen
	  Integer*2 Code		/LNM$_String/
	  Integer*4 Dst_Address
	  Integer*4 Length_Address
	  Integer*4 End_List		/0/
	End Structure

	Record /TrnLnm_Item_List/ T_ItmLst

C-------------------------------------------------------------------C
	CALL SMG$END_PASTEBOARD_UPDATE (PASTEBOARD_ID)

       	If (Current_Dir_FileName(1:18) .NE. '[000000]000000.DIR') 
	1	GoTo 800

        Could_Not_Load = .FALSE.
                           
	Call Str$Trim (%Descr(Current_Device)
	1		,%Descr(Current_Device),%Ref(K))
	If (K .LE. 1) GoTo 800
	KK = K   ! Save for Error Message, if needed
                                      
C	Call Lib$Sys_TrnLog(Current_Device(:K-1),,%Descr(Temp_Device))
	T_ItmLst.BufLen			=	LEN(Temp_Device)
	T_ItmLst.Dst_Address		=	%LOC(Temp_Device)
	T_ItmLst.Length_Address		=	%LOC(ItsK)
	
	Temp_Device = ' '
	Call SYS$TrnLnm(LNM$M_Case_Blind, 'LNM$FILE_DEV', 
	1	Current_Device(:K-1),, T_ItmLst)

        J = Lib$MatchC('::',%Descr(Temp_Device))
	If (J.LE.0) then
	        I = Lib$MatchC(':',%Descr(Temp_Device))
	Else
	        I = Lib$MatchC(':',%Descr(Temp_Device(J+2:)))+J+1
	End If

        If (I.GT.0) then
		Call Lib$Set_Logical('SYS$DISK',Temp_Device(:I))
        Else
       		GoTo 800
        End If

C		Here, we have a device which we think is "above" us.
C		We should also have a directory of the form [SYS0.]
C		or of the form [LIBRARY]

	J = I+1
	If (Temp_Device(J:J) .NE. '[') GoTo 800

	K = Lib$MatchC ('.]', %Descr(Temp_Device))
	If (K .GT. 0) then
		TempName = Temp_Device(J:K-1)//']'
	        Call Sys$SetdDir(TempName,%Val(0),%Val(0)) ! Set New Default Dir
C							   !   to "TempName"
	        Current_Dir = TempName	
		GoTo 111
	Else
		K = Lib$MatchC (']', %Descr(Temp_Device))
		If (K .LE. 1) GoTo 800
		Current_Dir = Temp_Device (J:K)
		GoTo 111
        End If


C		Note that TempName and DName2 are in Common, (DName2 is
C		set by POPSTACK to the previous directory name), 
C		and that the original values of Current_Dir and
C		Current_Dir_Filename are being saved by POPSTACK -
C		- so if we fail, we're still OK.  On the other hand,
C		if we succeed, POPSTACK will have the right info.


111     Call RealDir (Current_Dir, Current_Dir_FileName)
C			 [aaa.bbb] --> [aaa]bbb.DIR
        Call SMG$End_Pasteboard_Update (Pasteboard_ID)	
        Call Mess_Line
	1	(' Reading Directory '//Current_Dir_FileName(1:62))
        Call SMG$Begin_Pasteboard_Update (Pasteboard_ID)	

C	 	  Assign a channel to "Channel";
C
	Status = Sys$Assign (%Descr(Temp_Device(:I)),
	1		%Ref(Is_Dir_Channel),,)
C			NOTE THAT THE TRAILING COMMAS ARE REQUIRED



100     Open(Unit=1, File=Current_Dir_FileName, 
	1	Access = 'SEQUENTIAL', Carriagecontrol = 'NONE',
	2	Recl = 512, RecordType = 'VARIABLE',
	3	NoSpanBlocks, Status='OLD', READONLY, Shared, 
C 	3	NoSpanBlocks, Status='OLD', READONLY, 
	4	IOSTAT = IOX, UserOpen = Is_Dir, ERR=40)  
C
C --NOTE-- Opening SHARED seems to crash on CLOSE with V4.4
C BUT does not crash using VMS 4.5 and FORTRAN 4.6
C
C		   If we succeed, ....	

       		Current_Device = Temp_Device(:I)

C 		Deassign the channel (note use of %Val);
	       	Status = Sys$Dassgn (%Val(Is_Dir_Channel))
		Is_Dir_Channel = -9999
        Goto 900

40	CONTINUE
C 		Deassign the channel (note use of %Val);
       	Status = Sys$Dassgn (%Val(Is_Dir_Channel))
	Is_Dir_Channel = -9999

800    	Call SMG$End_Pasteboard_Update (Pasteboard_ID)

	If (IOX .EQ. 43) then   ! Not a Directory-Type File
	     Call Mess_Wait (' This is NOT REALLY a Directory file: '//
	1		 Current_Device(:KK)//Current_Dir_FileName)
	Else
		Call Mess_Wait (' Can''t open directory file: '//
	1		 Current_Device(:KK)//Current_Dir_FileName)
	End If

        Could_Not_Load = .TRUE. ! Tell caller I had trouble


900	Return
	End
