Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - stanford/ftp/ftpdir.mac
There are no other files named ftpdir.mac in the archive.
	SEARCH FTPDEF
	TTITLE(FTPDIR, -- Routines for printing out directory listings)
	SUBTTL David Eppstein / Stanford University  21-Feb-1984

	;; Copyright (C) 1984 Board of Trustees, Stanford University
	;; The information in this software is subject to change without
	;; notice and should not be construed as a commitment by Stanford
	;; University.  Stanford assumes no responsibility for the use or
	;; reliability of this software.

	EXTERN DIRJFN,FILPRP,SKPDIR,TEMP,OPSYS
; Here when protocol wants us to print a filespec
; destination JFN in DIRJFN, file props in FILPRP, flags in FX

LS DIRDIR,20			; This must be permanent for DIRDCH

DIRPNT::ABTSKIP			; See if we got a ^G
	IFSKP.
	  TXZE FX,L%HDR		; Then remember we got it.  If not already done
	   TYPE <[Directory command aborted]%/> ; Tell user what he did
	  RET			; Ignore this and all remaining files
	ENDIF.

	;; Not aborted, so start up.  First headers if they haven't been done.
	SAVEAC <A,B,C,D>	; Save used registers
	TRVAR <<DIRFIL,20>,DIRDPT,DIRCPT> ; Declare local storage
	TXON FX,L%HDR		; Set header typed flag.  If not already set
	 CALL DIRHDR		; Then go make headers

	;; Parse the filename into directory and name-body, and if the
	;; directory was different from the previously-printed file
	;; then add the new directory name to the listing.
	CALL DIRNAM		; Parse filename into P.NAMB and P.DIRE
	MOVE A,[POINT 7,TEMP]	; Buffer output into temporary storage
	HRROI B,DIRDIR		; Point to directory
	TXZN FX,L%NDIR		; Any mismatches found in dir name?
	IFSKP.
	  TXZN F,F%NCRF		; Won't need CRLF. If didn't now
	   WRITE <%/>		; Then perversely write one
	  WRITE <   %2S%/>	; Add directory name
	ENDIF.
	TXZE F,F%NCRF		; If still want a CRLF
	 WRITE <%/>		; then write one

	;; Add the actual filename, counting characters so later columns
	;; can be aligned with each other.
	MOVE B,[POINT 7,DIRFIL]	; Get filename itself
	SETZ D,			; Nothing found yet
	DO.
	  ILDB C,B		; Get next filename char
	  JUMPE C,ENDLP.	; If null, done
	  CAIL C," "		; If not printable control char
	   CAIN C,177		; or equally unprintable del
	    LOOP.		; then ignore it
	  IDPB C,A		; Drop into string
	  AOJA D,TOP.		; Count off, and go back for another char
	ENDDO.

	;; Now we have made filename - if wanted more cols, print them too.
	CAIE FX,L%HDR		; Anything else to print?
	 JRST DIRPAT		; Yes, print attributes

; End of listing for this file
DIRPDN:	WRITE <%/>		; End buffered text with a CRLF
	MOVE A,DIRJFN		; Now to our output file
	HRROI B,TEMP		; With buffer we just filled
	SETZ C,			; Up to null
	SOUT%			; Send it off
	RET			; Done with that file
; Break up Server-Filename for directory listing
; we put the device and directory etc into DIRDIR
; and the filename itself into DIRFIL.
; L%NDIR will be set if the new directory was different from the old.

DIRNAM:	TXZ FX,L%NDIR		; No differences yet
	MOVE B,[POINT 7,FILPRP+P.SFIL] ; Point to source
	MOVE C,[POINT 7,DIRDIR]	; Point to directory destination
	MOVEM C,DIRCPT		; Save pointer in memory
	MOVE C,OPSYS		; Look at remote operating system
	CAIN C,OS.DEC		; TOPS-10 or SAIL?
	 JRST DIRDEC		; Yes, try to be smart

	;; Not TOPS-10 so the directory comes before the file.
	;; Copy it out into a separate string.
	CALL SKPDIR		; For other operating systems, skip over dir
	MOVEM B,DIRDPT		; Save pointer for later comparison
	MOVE B,[POINT 7,FILPRP+P.SFIL] ; Start at the beginning again
	DO.
	  CAMN B,DIRDPT		; Done with directory yet?
	   TDZA C,C		; Yes, get null
	    ILDB C,B		; No, get next char
	  CALL DIRDCH		; Add to directory string
	  JUMPN C,TOP.		; and go back to the top
	ENDDO.

	;; Got directory part, now use rest of string as file part.
	MOVE C,[POINT 7,DIRFIL]	; Now point to file
	TXZ F,F%TEMP		; No version seen yet
	DO.
	  ILDB D,B		; Get next char of filename
	  IDPB D,C		; Drop it into directory filename
	  CAIN D,";"		; Semicolon?
	   TXO F,F%TEMP		; Yes, remember we saw it
	  JUMPN D,TOP.		; Back for yet another
	ENDDO.

	;; Now we are mostly done with the filename.  But we might have
	;; forgotten the generation for TENEX files, so if we have we
	;; try to add it back in here.
	TXZE F,F%TEMP		; Seen a semi?
	 RET			; Yes, don't add generation twice
	MOVE D,OPSYS		; Get operating system again
	CAIN D,OS.10X		; Tenex?
	 SKIPG B,FILPRP+P.VERS	; Yes, do we have a version yet?
	  RET			; Some better operating system or no version
	MOVEI D,";"		; Get a semicolon again
	DPB D,C			; Drop in over null
	WRITE C,<%2D>		; Add generation
	RET			; Done with non-DEC filenames


; Here to add char in C to directory string
DIRDCH:	ILDB D,DIRCPT		; Get old char there
	CAIE C,(D)		; If not the same as new char
	 TXO FX,L%NDIR		; Remember the difference
	DPB C,DIRCPT		; Drop new char in
	RET
; Break up TOPS-10 style filename for directory
; DEV:FNAME.EXT[PRJ,PRG] is split into DEV:[PRJ,PRG] and FNAME.EXT

; Here from DIRDEC when we find a colon early in the filename.
; Put that part in the directory name and start over with rest of filename.
DIRCLN:	MOVE B,DIRDPT		; Start over
	DO.
	  ILDB C,A		; Get next char
	  CALL DIRDCH		; Drop in directory
	  CAIE C,":"		; If not a colon
	   LOOP.		; Back for another
	ENDDO.

; Main entry point.
; Loop, looking for a device terminator or directory starter.
; If a device terminator, we've come too far and have to start from the top.
; If a directory starter, we leave the completed filename and
; go on to finish filling out the directory name.
DIRDEC:	MOVEM B,DIRDPT		; Save pointer for possible retry
	MOVE D,[POINT 7,DIRFIL]	; Point to filename for DIRDEC	
	DO.
	  ILDB C,B		; Get next char
	  CAIN C,":"		; Colon?
	   JRST DIRCLN		; Yes, treat specially
	  IDPB C,D		; Drop it in
	  CAIN C,"["		; If an open bracket
	   EXIT.		; then go do directory part
	  JUMPN C,TOP.		; If null then done
	  CALLRET DIRDCH	; Add character to end of directory name
	ENDDO.

	;; Here after reading "[" in TOPS-10 filename
	SETZ C,			; Get a null
	DPB C,D			; Drop in at end of filename over bracket
	MOVEI C,"["		; Get open bracket again
	DO.
	  CALL DIRDCH		; Add to directory name
	  JUMPE C,R		; If null, done
	  ILDB C,B		; Else get next char
	  LOOP.			; Back for another
	ENDDO.
; More attributes printed in directory listing
; D contains number of chars in filename (for alignment).

DIRPAT:	SUBI D,^D24		; Reserve 24 chars for name
	IFG. D			; If we're already past it
	  WRITE <%/                        > ; Make new line and space over
	ELSE.
	  IFL. D		; If we need to pad out at all
	    MOVEI B," "		; Get a space
	    DO.
	      IDPB B,A		; Add it to buffer
	      AOJL D,TOP.	; Until we pad line out enough
	    ENDDO.
	  ENDIF.
	ENDIF.

	;; Alignment done, now print attributes.  First file type.
	TXNE FX,L%TYPE		; List file type?
	 CALL DIRLTY		; Yes, go do it

	;; Now size (bytes or pages depending on protocol and server)
	IFXN. FX,L%SIZE		; List file size?
	  MOVE B,FILPRP+P.SIZE	; Get file size
	  MOVX C,NO%LFL!NO%OOV!FLD(6,NO%COL)!FLD(^D10,NO%RDX)
	  NOUT%
	   NOP			; Ok if number overflows
	ENDIF.

	;; Now protection
	IFXN. FX,L%PROT		; List protection?
	  SKIPL B,FILPRP+P.PROT	; Get protection
	  IFSKP.
	    WRITE <    ?? >	; Unknown, don't type as number
	  ELSE.
	    MOVX C,NO%LFL!NO%OOV!FLD(7,NO%COL)!FLD(^D8,NO%RDX)
	    NOUT%
	     NOP
	  ENDIF.
	ENDIF.

	;; Now the various dates and author strings.
	MOVE B,FILPRP+P.CDAT
	TXNE FX,L%CDAT		; List creation date?
	 CALL PRDATE		; Yes, do so
	MOVE B,FILPRP+P.WDAT
	TXNE FX,L%WDAT		; List write date?
	 CALL PRDATE		; Yes, do so
	MOVE B,FILPRP+P.RDAT
	TXNE FX,L%RDAT		; List read date?
	 CALL PRDATE		; Yes, do so
	HRROI B,FILPRP+P.OAUT
	SKIPN FILPRP+P.OAUT
	 HRROI B,[ASCIZ/??      /]
	TXNE FX,L%OAUT		; List creator?
	 WRITE < %2S>
	HRROI B,FILPRP+P.AUTH
	SKIPN FILPRP+P.AUTH
	 HRROI B,[ASCIZ/??/]
	TXNE FX,L%AUTH		; List author?
	 WRITE < %2S>
	JRST DIRPDN		; Done with this file's listing
; More directory listing

; Here to list type and byte size of file
DIRLTY:	HRRZ C,FILPRP+P.TYPE	; Get file type
	HRRZ B,FILPRP+P.BYTE	; Byte size
	XCT [ WRITE < ???  >	; Something we don't recognize
	      WRITE <      >	; Unspecified
	      WRITE < Text >	; Text
	      WRITE < B(%2D)>	; Binary
	      WRITE < Paged>	; Paged (huh?)
	      WRITE < Dir  >	; Directory
	      WRITE < EBCD >	; EBCDIC
	      WRITE < Image>	; Image (?)
	    ]+1(C)
	CAIN C,TT.BIN		; Binary?
	 CAIL B,^D10		; Byte size less than 10?
	  RET			; No, done
	WRITE < >		; Yes, another space
	RET


; Print date in correct format for DIRECTORY command
;	A/ Destination designator (byte pointer to TEMP buffer)
;	B/ Tops20 format date and time
;	FX/ List format flags
; Returns +1 always
; Clobbers B, C

PRDATE:	IFE. B			; If time is unspecified
	  WRITE <    ---   >	; Write dashes instead
	  TXNE FX,L%TIME	; and if we wanted time too
	   WRITE <      >	; leave more blank space
	  RET
	ENDIF.
	WRITE < >		; Pad from previous column
	MOVX C,OT%NTM		; Normally omit time
	TXNE FX,L%TIME		; Want to include time?
	 TXC C,OT%NTM!OT%NSC	; Yes, but don't include seconds
	ODTIM%			; Do it
	RET
; Here to make header for directory listing

DIRHDR:	SETZM DIRDIR		; No directory found yet
	CAIN FX,L%HDR		; If we have no real flags set
	 RET			; Then we're done with the header
	HRROI A,TEMP		; Buffer string
	WRITE <                        >
	TXNE FX,L%TYPE		; Printing type?
	 WRITE < Type >
	TXNE FX,L%SIZE		; Printing size?
	 WRITE <  Size>
	TXNE FX,L%PROT		; Printing protection?
	 WRITE <   Prot>
	SETZ B,			; For dates, assume no times
	TXNE FX,L%TIME		; List times?
	 HRROI B,[ASCIZ /      /]	; Yes, extra space
	TXNE FX,L%CDAT		; Printing creation date?
	 WRITE <  Creation%2S>
	TXNE FX,L%WDAT		; Printing write date?
	 WRITE <  Write   %2S>
	TXNE FX,L%RDAT		; Printing read date?
	 WRITE <  Read    %2S>
	TXNE FX,L%OAUT		; Print creator?
	 WRITE < Creator >
	TXNE FX,L%AUTH		; Print author?
	 WRITE < Writer>
	TXO F,F%NCRF		; Need a CRLF
	JRST DIRPDN		; Done with that

	END