	.TITLE FIND - FIND FILES
	.IDENT	/1.00/
;
; THIS PROGRAM IS MEANT TO FUCTION AS A SRD UTILITY FOR ODS-2 FOR VAX
;
; WRITTEN BY: LOU PERAZZOLI  10-JUN-1978
;
;
; LOCAL MACROS
	.MACRO	TEXT	TXXT,?LAB1,?LAB2
	.LONG	LAB2-LAB1
	.LONG	LAB1
LAB1:	.ASCII	/TXXT/
LAB2:
	.ENDM
	.MACRO	STATUS	ERROR_NUM,INST,?A
	BLBS	R0,A
	MOVL	#ERROR_NUM,R1
	BSBW	ERROR
	INST
A:
	.ENDM
	.MACRO	ERROR	ERROR_NUM,INST
	MOVL	#ERROR_NUM,R1
	BSBW	ERROR
	INST
	.ENDM
	.MACRO	BITS	NAME,NO
NAME'_V=NO
NAME=1@NO
	.ENDM
	$RMSDEF
	$TPADEF
;	$FH2DEF
FH2$L_FILECHAR=^X34
FH2$V_DIRECTORY=^X0D
;	$HM2DEF
; THE ABOVE LINE ($HM2DEF) CAUSES A SYMBOL TABLE OVERFLOW - SO WE WILL DEFINE
; THE OFFSETS MANAULLY AND HOPE THEY DON'T CHANGE AND WHEN THE ASSEMBLER
; WORKS PROPERLY THE CAN BE REMOVED.
	HM2$W_STRUCLEV=^X0C
	HM2$W_IBMAPVBN=^X16
	HM2$W_IBMAPSIZE=^X20
	.LIST	ME
	BITS	DEV_PRES,23
	BITS	WILD_UIC,4
	BITS	WILD_GROUP,6
	BITS	WILD_MEM,5
	BITS	WILD_NAME,7
	BITS	WILD_EXT,8
	BITS	WILD_VER,9
	BITS	VER_PRES,10
	BITS	MEM_EXISTS,13
	BITS	HIGH_PRES,31
	BITS	NOT_PRES,30
	BITS	BEFORE_PRES,24
	BITS	AFTER_PRES,25
	BITS	SPEC_PRES,16
	BITS	OUTPUT_PRES,21
	.NLIST	ME
	.PSECT	RABANDFAB,LONG
IN_FAB:	$FAB	FAC=<GET,PUT>,FNA=IN_NAME,FNS=9,MRS=80,RAT=CR,RFM=VAR
IN_RAB:	$RAB	FAB=IN_FAB,RAC=SEQ,RSZ=80,UBF=IN_BUF,USZ=80,-
		ROP=<PMT,CVT>,PBF=PRO_BUF,PSZ=PRO_SIZE
IN_NAME:	.ASCII /SYS$INPUT/
PRO_BUF:	.ASCII <13><10>/TYPE IT> /
PRO_SIZE=.-PRO_BUF
IN_BUF:	.BLKB	100
;
;
	.PSECT	CODE,QUAD
START:	.WORD	0
	.ENABL	LSB
	$OPEN	FAB=FAB_SYSOUT	;OPEN SYS$OUTPUT
	$CONNECT	RAB=RAB_SYSOUT
	$OPEN FAB=IN_FAB
	STATUS	INPUT_ERR,RET
	$CONNECT	RAB=IN_RAB
	STATUS	INPUT_ERR,RET
	MOVAB	W^CLI_REQBLK,R8		;POINT TO COMMAND REQUEST DESCRIPTOR
	PUSHL	R8			;STORE ARGUMENT FOR CALL
	CALLS	#1,@CLI$A_UTILSERV(AP)	;CALL CLI TO GET A COMMAND LINE
	MOVZWL	CLI$W_RQSIZE(R8),R9	;NUMBER OF BYTES READ IN
	BEQL	NEXT			;IF ZERO - GO PROMPT AND READ
; DUE TO THE FACT THAT THE CLI MAY GIVE US "FIND" IN THE STRING SO WE MUST
; REMOVE IT AND HOPE THE USER DID NOT TYPE IN FIND
;
	MOVL	CLI$A_RQADDR(R8),R7	;START OF STRING TO R7
	CMPL	#4,R9			;WERE THERE AT LEAST 4 CHARACTERS
	BGTR	5$			; IF LESS THAN 4 OKAY
	CMPL	#^A/FIND/,(R7)		;ARE THE  FIRST 4 CHARACTERS FIND
	BNEQ	5$
	SUBL	#4,R9			;4 LESS CHARACTERS TO MOVE
	BEQL	NEXT			;IF ZERO - READ INPUT LINE
	ADDL	#4,R7			;MOVE STRING PAST FIRST 4 CHARACTERS
5$:
	INCB	W^ONE_SHOT		;SET FLAG SO WE DON'T PROMPT EVER
	MOVC3	R9,(R7),W^IN_BUF		;MOVE STRING TO INPUT BUFFER
	MOVW	R9,W^IN_RAB+RAB$W_RSZ	;STORE LEN IN RAB TO ACT LIKE READ
	BRB	1010$			;GO PARSE THE COMMAND LINE
NEXT:
	TSTB	W^ONE_SHOT		;IF NOT ZERO - WE GOT LINE FROM COMMAND
	BNEQ	1005$			;BR IF LINE FROM CLI
10$:	$GET	RAB=IN_RAB
	BLBS	R0,1010$
	CMPL	R0,#RMS$_EOF
	BNEQ	1011$
1005$:
	MOVL	#1,R0		;RETURN SUCCESS
	RET			;ALL DONE
1011$:	STATUS	INPUT_GET,<BRW	NEXT>
1010$:
	.DSABL	LSB
; INIT TPARSE DATA BASE
	MOVAB	W^DEVICE_NAME,R0	;START ADDRESS OF TPARSE TABLE AREA
	MOVAB	W^END_TAB,R1		;ADDRESS OF END TO TPARSE TABLE
	SUBL2	R0,R1			;NUMBER OF BYTES IN TABLE
	MOVC5	#0,(R0),#0,R1,(R0)	;CLEAR THE STORAGE
	MOVL	#1,W^FILE_TRIES		;INIT FILE_TRIES
	MOVAB	W^TPAR_DATA,R0		;ADDRESS NEEDED FOR TPARSE
	MOVZWL	W^IN_RAB+RAB$W_RSZ,TPA$L_STRINGCNT(R0)	;LENGHT OF STRING 
	MOVAB	W^IN_BUF,TPA$L_STRINGPTR(R0) ;POINT TO STRING
	PUSHAL	W^TABLE_KEY		;ARGUMENT FOR TPARSE
	PUSHAL	W^TABLE_STATE		;ARGUMENT FOR TPARSE
	PUSHL	R0			;ARGUMENT FOR TPARSE
	CALLS	#3,W^LIB$TPARSE		;INVOKE TPARSE
	STATUS	SYNTAX_ERR,<BRW	NEXT>
;OPEN THE INDEX FILE
	MOVB	W^DEVICE_NAME,W^INDEX_FAB+FAB$B_DNS	;MOVE IN THE SIZE TO FNS
	MOVL	W^DEVICE_NAME+4,W^INDEX_FAB+FAB$L_DNA	;MOVE IN THE NAME
	$OPEN	FAB=INDEX_FAB		;OPEN THE INDEX FILE
	STATUS	INDEX_OPN,<BRW	NEXT>
	MOVAB	W^BUFFER,R2		;ADDRESS OF BUFFER FOR QIO TO R2
	$QIOW_S	CHAN=INDEX_FAB+FAB$L_STV,FUNC=#IO$_READVBLK,-
		IOSB=IO_STAT,P1=(R2),P2=#512,P3=#2	;READ HOME BLOCK
	STATUS	INDEXF_READ,<BRW	NEXT>
	BLBC	HM2$W_STRUCLEV+1(R2),1500$	;IS DISK ODS-2 (LEVEL=2)
	ERROR	NOT_ODS2,<BRW	NEXT>
1500$:
	CLRL	R0
	ADDW3	HM2$W_IBMAPVBN(R2),HM2$W_IBMAPSIZE(R2),R0	;FIND BLOCK
						;NUMBER OF INDEX FILE HEADERS
	SUBL3	#1,R0,W^HEAD_OFFSET		;SUBTRACT ONE AND STORE
	BBC	#BEFORE_PRES_V,W^COMMAND,2010$	;WAS A BEFORE TIME ENTERED
	MOVAB	W^BEFORE_TIME,R3	;TIME
	TSTL	(R3)			;WAS TIME GIVEN
	BNEQ	2000$			;BR IF NOT
	MOVAB	W^DEFAULT_TIME,R3	;GIVE DEFAULT TIME
2000$:
	$BINTIM_S	TIMBUF=(R3),TIMADR=BTIME
	STATUS	TIME_ERR,<BRW	NEXT>
2010$:
	BBC	#AFTER_PRES_V,W^COMMAND,2050$	;AFTER TIME SPECIFIED
	MOVAB	W^AFTER_TIME,R3
	TSTL	(R3)		;WAS TIME GIVEN
	BNEQ	2040$		;BR IF IT WAS GIVEN
	MOVAB	W^DEFAULT_TIME,R3
2040$:
	$BINTIM_S	TIMBUF=(R3),TIMADR=ATIME
	STATUS	TIME_ERR,<BRW	NEXT>
2050$:
	BBS	#SPEC_PRES_V,W^COMMAND,2070$
	BISL	#<WILD_NAME!WILD_EXT>,W^COMMAND	;IF NO FILE SPECIFIED MAKE *.*
2070$:
; ARE WE CREATING A FILE OR WRITING TO SYS$OUTPUT
	BBS	#OUTPUT_PRES_V,W^COMMAND,15$  ;BRANCH IF WE ARE CREATING A FILE
	MOVAB	W^RAB_SYSOUT,W^RAB_OUT_HOLD	;SET R10 TO POINT TO SYSOUT
	BRB	18$
15$:
	MOVB	W^OUTPUT_NAME,W^FAB_OUT+FAB$B_FNS	;LEN OF OUTPUT NAME
	MOVL	W^OUTPUT_NAME+4,W^FAB_OUT+FAB$L_FNA	;ADDR OF NAME
	$CREATE	FAB=FAB_OUT
	STATUS	CREATE_ERR,<BRW	NEXT>
	MOVAL	W^FAB_OUT,W^RAB_OUT+RAB$L_FAB	;HAVE THE RAB POINT TO THIS FAB
	$CONNECT RAB=RAB_OUT	;OPEN ON SYSOUTPUT
	STATUS	OUTPUT_ERR,<BRW	NEXT>
	MOVAB	W^RAB_OUT,W^RAB_OUT_HOLD	;SAVE ADDRESS OF RAB FOR LATER
18$:
; BUILD THE DEFAULT NAME FOR OPENS (DISK:[0,0].DIR)
	MOVAB	W^DEFAULT_NAME,R3	;ADDRESS OF DEFAULT_NAME TO R3 FOR MOVC
	TSTL	W^DEVICE_NAME		;WAS A DEVICE NAME ENTERED (FROM PARSE)
	BEQL	150$			;BR IF NOT DEVICE PRESENT
	MOVC3	W^DEVICE_NAME,@W^DEVICE_NAME+4,(R3)	;MOVE IN DEVICE NAME
150$:
	MOVC3	#9,W^ZERO_DIR,(R3)	;MOVE IN [0,0].DIR
	ADDL3	#9,W^DEVICE_NAME,W^DEFAULT_NAME_SZ	;CALC SIZE OF NAME
	MOVB	W^DEFAULT_NAME_SZ,W^FAB_BLOCK+FAB$B_DNS	;UPDATE FAB
	CLRL	W^PUT_FLAG		;COUNTER OF NUMBER OF RECORDS WRITTEN
	CLRL	W^DIR_FLAG		;COUNTER OF NUMBER OF DIRECTORIES FOUND
; GET THE DIRECTORY
;
	TSTL	W^UIC_NAME		;WAS A DIRECTORY ENTRY SPECIFIED
	BNEQ	100$			;BR IF IT WAS SPECIFIED
; GET THE DEFAULT DIRECTORY STRING
50$:
	MOVC3	#7,W^NEW_NAME,W^NAME_SO_FAR1	;MOVE IN "[000000" JUST IN CASE
	MOVAL	PIO$GT_DDSTRING,R6	;GET DEFAULT NAME STRING
	MOVZBL	(R6)+,R7		;GET LEN OF COUNTED STRING
	LOCC	#^A/,/,R7,(R6)		;IS THERE A COMMA IN THE NAME
	BEQL	90$			;BR IF NO COMMA
	MOVAB	W^NAME_SO_FAR1+4,R3		;LOCATION OF , IF WE HAD ONE
55$:	CMPB	#^A/[/,-(R1)			;IS NEXT CHARACTER UP A [
	BEQL	60$				;BR IF SO
	MOVB	(R1),-(R3)			;MOVE IN THE DIGIT
	BRB	55$				;DO ANOTHER
60$:
	ADDL3	R7,R6,R1			;POINT R1 TO END OF STRING ("]")
	DECL	R1				;ADJUST SO R1 POINTS TO "]"
	MOVAB	NAME_SO_FAR1+7,R3		;POINT TO END OF STRING +1
65$:	CMPB	#^A/,/,-(R1)			;IS NEXT CHARACTER A ,
	BEQL	70$				;BR IF SO
	MOVB	(R1),-(R3)			;MOVE IN THE CHARACTER
	BRB	65$
70$:
	MOVL	#7,R7				;LEN OF STRING IS 7 ("[000000"
	BRB	95$
90$:
	DECL	R7			;KNOCK OFF LAST CHAR "]"
	MOVC3	R7,(R6),W^NAME_SO_FAR1
95$:
	PUSHAB	W^NAME_SO_FAR1		;BUILD AN ARGUMENT
	PUSHL	R7			;COUNT OF DESC
	PUSHL	SP			;LOCATION OF DESC
	PUSHAB	W^UIC_NAME		;UIC SPECIFIED (IF ANY)
	CALLS	#2,W^UIC_GET		;GET THE UIC RESOLVING WILD CARDS
	BRB	DONE_ALL
100$:
	MOVL	W^UIC_NAME+4,R6		;START OF NAME
	CMPB	#^A/./,1(R6)		;IS SECOND CHAR A .
	BNEQ	200$			;BR IF NOT
	DECL	W^UIC_NAME		;MOVE NAME OVER [
	INCL	W^UIC_NAME+4		;MOVE THE STRING OVER [
	BRB	50$			;PLAY WITH DEFAULT NAME STRING
200$:
	CLRL	W^NAME_SO_FAR
	PUSHAB	W^NAME_SO_FAR
	PUSHAB	W^UIC_NAME
	CALLS	#2,W^UIC_GET
DONE_ALL:
	$DASSGN_S	CHAN=INDEX_FAB+FAB$L_STV	;CLOSE THE INDEX FILE
						;BY DEASSIGNING THE CHANNEL
	TSTL	W^DIR_FLAG		;WERE ANY DIRECTORIES FOUND
	BNEQ	116$
	CLRL	R0
	ERROR	NO_DIR,<BRB 117$>		;ISSUE AN ERROR MESSAGE
116$:
	TSTL	W^PUT_FLAG		;WERE ANY RECORDS WRITTEN
	BNEQ	117$
	CLRL	R0			;CLEAR R0 FOR ERROR ROUTINE
	ERROR	NO_FILE			;ISSUE AN ERROR MESSAGE
117$:
	BBC	#OUTPUT_PRES_V,W^COMMAND,120$ ;SKIP CLOSE IF WRITING ON SYS$OUTPUT
	$DISCONNECT RAB=RAB_OUT
	STATUS	CLOSE_OUT,<BRW	NEXT>
	$CLOSE FAB=FAB_OUT
	STATUS	CLOSE_OUT,<BRW	NEXT>
120$:
125$:
	BRW	NEXT
.PSECT	DATA2,LONG
.ALIGN	LONG
CLI_REQBLK:
	$CLIREQDESC	RQTYPE=CLI$K_GETCMD	;REQUEST DESC FOR GETTING THE
						;COMMAND LINE FROM THE CLI
ONE_SHOT:	.BYTE	0			;FLAG TO INDICATE CLI COMMAND
NEW_NAME:	.ASCII/[000000/
.PAGE
.ALIGN	 LONG
VALIDATE_DIR::
; THIS ROUTINE READS A HEADER OF THE INDEX FILE (VBN SPECIFIED IN R2)
; AND CHECKS TO SEE IF IT WAS A DIRECTORY FILE
	$QIOW_S	CHAN=INDEX_FAB+FAB$L_STV,-
		FUNC=#IO$_READVBLK,IOSB=IO_STAT,-
		P1=BUFFER,P2=#512,P3=R2
	MOVAB	W^BUFFER,R0
	BBC	#FH2$V_DIRECTORY,FH2$L_FILECHAR(R0),NOTDIR
	MOVL	#1,R0
	RSB
NOTDIR:	CLRL	R0
	RSB
	.END	START
