[comp.os.vms] FID To Filename Program

oakley%36975%essdp2.span@Sdsc-Sds.Arpa (07/27/87)

In reply to Marc Williams@Edwards-2060, below is a program that
will convert an FID to a file-spec. 

--------------------------------------------------------------------------
	.TITLE	FID Convert a file-id to full file-spec
	.IDENT	/1.0/
;++
;
; Title:
;	FID - Convert a file id (file index number, file sequence number,
;	      file relative volume number) to a full file spec.
;
; Version:
;	1.0
;
; Facility:
;	File system program.
;
; Abstract:
;	This program invokes the $QIO system service to convert a 
;	file-id to a file spec. To use this program, define a symbol
;	to invoke this program, such as:
;
;		$ FID :== $device:[dir]FID
;
;	The command syntax looks like:
;
;		$ FID/ID=(idx,seq[,rvn])  [device]
;
;	where idx is the file-id index, seq is the file-id sequence number,
;	rvn is the optional relative volume number, and device is the 
;	disk/volume set you would like to search. If rvn is ommitted, it
;	default to zero (appropriate for disks not in a volume set). If
;	device is not specified, it defaults to SYS$DISK (the current disk).
;
; Environment:
;	Access to file is required.
;
; Author:
;	Mark Oakley	Battelle Memorial Institute	  8-Jul-1987
;
; Modified:
;	
;
;--

	.SBTTL	Symbols, macros, data
	.PSECT	FID_DATA RD,WRT,NOEXE,LONG,SHR,PIC

	$ATRDEF			; Symbols for $QIO call
	$FIBDEF			;    "     "    "   "
	$IODEF			;    "     "    "   "
	$TPADEF			;    "     "  LIB$TPARSE

;
; Macro to handle return codes.
;
	.MACRO	ON_ERR	THERE,?HERE
	BLBS	R0,HERE
	BRW	THERE
HERE:	.ENDM	ON_ERR

COMMAND_LINE_BUF:				; Contents of the command
	.BLKB	80				; line will go here.
COMMAND_LINE_BUF_SIZ = . - COMMAND_LINE_BUF

COMMAND_LINE_DESC:
	.LONG	 COMMAND_LINE_BUF_SIZ
	.ADDRESS COMMAND_LINE_BUF

COMMAND_LINE_LEN:
	.BLKL	1

PARSE_BLK:					; For LIB$TPARSE.
	.LONG	TPA$K_COUNT0
	.LONG	TPA$M_ABBREV			; Permit abbreviations
. = PARSE_BLK + TPA$K_LENGTH0			; on command line.

IDX_VAL:					; Index value of fid.
	.BLKL	1

SEQ_VAL:					; Sequence number of fid.
	.BLKL	1

RVN_VAL:					; Relative volume number
	.BLKL	1				; of fid.

DEVICE_DESC:					; Descriptor, will be filled
	.BLKQ	1				; in by parsing or default.

DEFAULT_DEVICE_DESC:				; Current disk will be
	.ASCID	/SYS$DISK/			; default.

DVI_ITEM_LIST:					; If we are on a volume set,
	.WORD	 ROOT_DEVICE_SIZ		; make sure we get the root
	.WORD	 DVI$_ROOTDEVNAM		; volume.
	.ADDRESS ROOT_DEVICE
	.ADDRESS ROOT_DEVICE_DESC
	.LONG	 0

ROOT_DEVICE:					; Physical name of root
	.BLKB	40				; volume.
ROOT_DEVICE_SIZ = . - ROOT_DEVICE

ROOT_DEVICE_DESC:
	.LONG	 ROOT_DEVICE_SIZ
	.ADDRESS ROOT_DEVICE

FILE_FIB:					; Fill in this file info blk
. = FILE_FIB + FIB$W_FID			; with file id.
IDX:	.BLKW	1
SEQ:	.BLKW	1
RVN:	.BLKW	1
. = FILE_FIB + FIB$K_LENGTH

FILE_FIB_DESC:					; $QIO needs this.
	.LONG	 FIB$K_LENGTH
	.ADDRESS FILE_FIB

IOSB:						; $QIO status.
	.BLKQ	1

CHANNEL:					; Channel to root volume.
	.BLKL	1
               
ATTRIB:						; $QIO attribute block
	.WORD	 FILE_SPEC_SIZ			; to retrieve full file
	.WORD	 ATR$C_FILE_SPEC		; spec.
	.ADDRESS FILE_SPEC
	.LONG	 0

FILE_SPEC:					; Buffer for file spec.
	.BLKB	512
FILE_SPEC_SIZ = . - FILE_SPEC

FILE_SPEC_LEN:
	.BLKL	1

FORMAT:						; Format used by $FAO.
	.ASCID	#!/ The file is !AD !/#

OUT_BUF:					; Print buffer.
	.BLKB	132
OUT_BUF_SIZ = . - OUT_BUF

OUT_BUF_DESC:
	.LONG	 OUT_BUF_SIZ
	.ADDRESS OUT_BUF

	.SBTTL	Parse tables
	.PSECT	FID_PARSE RD,NOWRT,EXE,LONG,SHR,PIC

;
;  The syntax for this command looks like:
;
;   $FID/ID=(idx,seq[,rvn])  [device]
;

	$INIT_STATE	FID_STATE,FID_KEY

	$STATE	START

	$TRAN	'/'
	$STATE

	$TRAN	'ID'
	$STATE

	$TRAN	'='
	$STATE

	$TRAN	'('
	$STATE

	$TRAN	TPA$_DECIMAL,,,,IDX_VAL
	$STATE

	$TRAN	<','>
	$STATE

	$TRAN	TPA$_DECIMAL,,,,SEQ_VAL
	$STATE

	$TRAN	')',DEVICE_CHECK
	$TRAN	<','>
	$STATE

	$TRAN	TPA$_DECIMAL,,,,RVN_VAL
	$STATE

	$TRAN	')'
	$STATE	DEVICE_CHECK

	$TRAN	TPA$_SYMBOL,TPA$_EXIT,,,DEVICE_DESC
	$TRAN	TPA$_EOS,TPA$_EXIT
	$STATE

	$END_STATE

	.SBTTL	Code
	.PSECT	FID_CODE RD,NOWRT,EXE,LONG,SHR,PIC
	.ENTRY	FID,^M<R2,R3,R4,R5,R6,R7,R8,R9>

	PUSHL	#0			; See what's on the command line.
	PUSHAL	COMMAND_LINE_LEN
	PUSHL	#0
	PUSHAL	COMMAND_LINE_DESC
	CALLS	#4,G^LIB$GET_FOREIGN
	ON_ERR	EXIT

	MOVZWL	COMMAND_LINE_LEN,-	; Set up for LIB$TPARSE.
		PARSE_BLK+TPA$L_STRINGCNT
	MOVAL	COMMAND_LINE_BUF,-
		PARSE_BLK+TPA$L_STRINGPTR
	PUSHAL	FID_KEY
	PUSHAL	FID_STATE
	PUSHAL	PARSE_BLK
	CALLS	#3,G^LIB$TPARSE		; Parse the command line.
	ON_ERR	EXIT

	TSTW	DEVICE_DESC		; Was a device specified?
	BNEQ	20$
	MOVQ	DEFAULT_DEVICE_DESC,-	; No, use the default.
		DEVICE_DESC
20$:

	$GETDVIW_S -			; Get root volume name. Note that
		DEVNAM=DEVICE_DESC,-	; just the physical device name is
		ITMLST=DVI_ITEM_LIST,-	; returned if it is not a volume
		IOSB=IOSB		; set.
	ON_ERR	EXIT
	MOVW	IOSB,R0
	ON_ERR	EXIT

	MOVW	IDX_VAL,IDX		; Set up the FIB.
	MOVW	SEQ_VAL,SEQ
	MOVW	RVN_VAL,RVN

	$ASSIGN_S -			; Get a channel to the device.
		DEVNAM=ROOT_DEVICE_DESC,-
		CHAN=CHANNEL
	ON_ERR	EXIT

	$QIOW_S	CHAN=CHANNEL,-			; Use the attribute list
		FUNC=#IO$_ACCESS!IO$M_ACCESS,-	; capability to obtain
		IOSB=IOSB,-			; the full file spec.
		P1=FILE_FIB_DESC,-
		P5=#ATTRIB
	ON_ERR	EXIT
	MOVL	IOSB,R0
	ON_ERR	EXIT

	MOVZWL	FILE_SPEC,FILE_SPEC_LEN		; Setup for formatting.

	$FAO_S	CTRSTR=FORMAT,-			; Format the information
		OUTLEN=OUT_BUF_DESC,-		; into something we can
		OUTBUF=OUT_BUF_DESC,-		; read.
		P1=FILE_SPEC_LEN,-
		P2=#FILE_SPEC+2
	ON_ERR	EXIT

	PUSHAL	OUT_BUF_DESC			; Write it out.
	CALLS	#1,G^LIB$PUT_OUTPUT
	ON_ERR	EXIT

EXIT:
	RET
	.END	FID