	TITLE	JX - FIND MATCHING JFNS - PHIL BUDNE
 
; 10 04 1984	BUDD	ADD FL$W?? FLAGS
 
.DECSAVE
 
P==17				;PDL
 
.INSRT LIB:SYMBOLS
.INSRT LIB:MACROS
.INSRT LIB:PRARG
.INSRT LIB:MONRD
 
FL==0				;FLAGS
 FL$HDR==BIT(0)			; HEADER HAS BEEN TYPED
 FL$WDV==BIT(1)			; DEVICE=*
 FL$WDR==BIT(2)			; DIR=
 FL$WFL==BIT(3)			; FILE=*
 FL$WEX==BIT(4)			; EXT=*
 FL$WVR==BIT(5)			; VER=*
 
F==7				;FILE LOOP
J==10				;JOB LOOP
BP==11				;BYTE PTR
 
LPDL==100
PJRST=JUMPA 11,

	SUBTTL	IMPURE STORAGE
 
PDL:	-LPDL,,.
	BLOCK	LPDL
 
MLJFN:	BLOCK	1		;SIZE OF JFN BLOCK IN JSB
JSVAR:	BLOCK	1		;ADDRESS OF JSB IN MONITOR SPACE
 
TXTPTR:	BLOCK	1
TXTCNT:	BLOCK	1
FILJFN:	BLOCK	1		;PARSE ONLY FILE JFN
USRNUM:	BLOCK	1		;USER NUMBER OF CURRENT JOB
FILSTS:	BLOCK	1		;FILE STATUS FLAGS
 
WLDSTR:	BLOCK	50.		;WILD STRING BUFFER
WLDDEV:	BLOCK	1		;BP TO WILD DEV
WLDDIR:	BLOCK	1		;BP TO WILD DIR
WLDFIL:	BLOCK	1		;BP TO WILD FILE
WLDEXT:	BLOCK	1		;BP TO WILD EXT
WLDVER:	BLOCK	1		;BP TO WILD VER
 
TMPSTR:	BLOCK	50.		;TEMP STRING BUFFER
TMPDEV:	BLOCK	1		;BP TO TEMP DEV
TMPDIR:	BLOCK	1		;BP TO TEMP DIR
TMPFIL:	BLOCK	1		;BP TO TEMP FILE
TMPEXT:	BLOCK	1		;BP TO TEMP EXT
TMPVER:	BLOCK	1		;BP TO TEMP VER
 
USRBUF:	BLOCK	10.		;STRING FOR USERNAMES
 
SVPTR:	BLOCK	1		;SAVED PTR FOR WILD
SVMSK:	BLOCK	1		;SAVED MASK FOR WILD
 
CMDBLK:	0			;FLAGS + REPARSE
	.PRIIN,,.NULIO		;JFNS
	-1,,[0]			;PROMPT
	-1,,STRBUF
	-1,,STRBUF
	5*LSTRBF
	0
	-1,,ATMBUF
	5*LATMBF
	0,,CMDGTJ
 
STRBUF:	BLOCK	<LSTRBF==20>
ATMBUF:	BLOCK	<LATMBF==10>
 
THEJOB:	BLOCK	1
THEUSR:	BLOCK	1

EV:	JRST	START
	JRST	START
	(SETZ).FVERS
 
START:	RESET
	ENABLE
	MOVE	P,PDL
	SETZ	FL
	CALL	DOINI
	CALL	DORSCAN
	CALL	SEARCH
	HALTF
 
DOINI:	SETZM	THEUSR
	SETOM	THEJOB
	MOVEI	1,.RDTST	;MONRD TEST FUNCTION
	SETZ	2,
	MONRD
	 ERJMP	NOMONRD
	CAIE	2,.TSTNM
	 JRST	NOMONRD
 
	MOVEI	1,.RDSYM
	MOVE	2,[SIXBIT /JSVAR/]
	MONRD
	 ERJMP	NOMONRD
	JUMPN	1,NOMONRD
	MOVEM	2,JSVAR
 
	MOVEI	1,.RDSYM
	MOVE	2,[SIXBIT /MLJFN/]
	MONRD
	 ERJMP	NOMONRD
	JUMPN	1,NOMONRD
	MOVEM	2,MLJFN
	RET

KOFFDB:	Field(.CMFLD,CM%FNC) ? 0 ? 0 ? 0
INIFDB:	Field(.CMINI,CM%FNC) ? 0 ? 0 ? 0
CFMFDB:	Field(.CMCFM,CM%FNC) ? 0 ? 0 ? 0
FILFDB:	Field(.CMFIL,CM%FNC) ? 0 ? 0 ? 0
USRFDB:	Field(.CMUSR,CM%FNC) ? 0 ? 0 ? 0
JOBFDB:	Field(.CMNUM,CM%FNC) ? 10. ? 0 ? 0
SWIFDB:	Field(.CMSWI,CM%FNC)\CFMFDB ? SWITAB ? 0 ? 0
SWITAB:	2,,2
	[ASCIZ 'JOB:'],,.JOB
	[ASCIZ 'USER:'],,.USER
 
STAR:	ASCIZ	"*"
 
CMDGTJ:	GJ%OLD\GJ%OFG\GJ%IFG\GJ%FLG\.GJALL ; GEN (OLD,PRSONLY,WILD,RETFLGS,..*)
	0			; SRC
	-1,,[ASCIZ "DSK*"]	; DEV
	-1,,STAR		; DIR
	-1,,STAR		; NAM
	-1,,STAR		; EXT
	0			; PRO
	0			; ACT
	0			; JFN
	BLOCK	10
 
DORSCAN:
	MOVEI	1,.RSINI
	RSCAN
	 TRN
	MOVEI	1,CMDBLK
	MOVEI	2,INIFDB
	COMND
	MOVEI	2,KOFFDB	;EAT PROGRAM NAME
	COMND
	MOVEI	2,FILFDB
	COMND
	TLNE	1,(CM%NOP)
	 JRST	DIE
	MOVEM	2,FILJFN
	CALL	EXPLODE
	MOVE	1,FILJFN
	RLJFN
	 .LOSE
 
; LOOP HERE, PARSING SWITCHES, OR CONFIRM
SWILOP:	MOVEI	1,CMDBLK
	MOVEI	2,SWIFDB
	COMND			;GET SWITCH OR CONFIRM
	TLNE	1,(CM%NOP)
	 JRST	DIE
	TSZ	3,3
	JUMPN	3,CPOPJ		;WAS CONFIRM
	HRRZ	2,(2)		;GET ACTION
	JRST	(2)
 
.JOB:	MOVEI	2,JOBFDB
	COMND
	MOVEM	2,THEJOB
	JRST	SWILOP
 
.USER:	MOVEI	2,USRFDB
	COMND
	MOVEM	2,THEUSR
	JRST	SWILOP

EXPLODE:
	MOVSI	4,-5		;LOOP COUNT
	MOVE	1,[ASCIIP WLDSTR] ;BP TO STRING BUFFER
EXPLOP:	MOVE	2,FILJFN
	MOVEM	1,WLDDEV(4)	;STORE BP
	MOVE	3,EXPTAB(4)	;GET BITS
	JFNS			;EXTRACT WILD STRING
	SETZ	2,		;GET NULL..
	ILDB	2,1		;..TERMINATE
	AOBJN	4,EXPLOP	;...LOOP...
 
	MOVE	1,WLDDEV	;GET WILD DEVICE
	HRROI	2,[ASCIZ 'DSK*'] ;GET DEFAULT DEVICE
	STCMP			;COMPARE
	SKIPN	1		;WAS DEVICE = 'DSK*' ?
	 TLO	FL,(FL$WDV)	; YES, REMEMBER THAT AS "*"
	MOVSI	4,-4
BITLOP:	MOVE	1,WLDDIR(4)	;GET WILD STRING BP
	HRROI	2,STAR		;GET *
	STCMP			;COMPARE
	SKIPN	1		;SAME?
	 TDO	FL,BITTAB(4)	; YES, REMEMBER LATER
	AOBJN	4,BITLOP
	RET
 
EXPTAB:	100000,,		;DEV
	010000,,		;DIR
	001000,,		;NAME
	000100,,		;EXT
	000010,,		;VER
 
BITTAB:	FL$WDR			;DIR = *
	FL$WFL			;FILE = *
	FL$WEX			;EXT = *
	FL$WVR			;VER = *

SEARCH:	SKIPL	J,THEJOB	;DO ONLY ONE JOB?
	 PJRST	DOJOB		; YES.
 
	MOVE	1,['JOBTTY]
	SYSGT
	 .LOSE
	MOVE	J,2		;GET JOB AOBJN
JOBLOP:	CALL	DOJOB
	AOBJN	J,JOBLOP
	RET
 
DOJOB:	MOVEI	1,(J)		;GET JOB NUMBER
	HRROI	2,USRNUM	;GET 1 VALUE INTO USRNUM
	MOVEI	3,.JIUNO	;GET USER NUMBER
	GETJI			;GET JOB INFO
	 JRST	CPOPJ		; NO JOB..
 
	SKIPE	2,THEUSR	;ONLY ONE USER?
	 CAMN	2,USRNUM	; YES, MATCH?
	  TRNA			;  THIS JOB IS OK
	   RET			;   THIS ONE IS NOT
 
	MOVE	2,[SIXBIT "MAXJFN"]
	CALL	GETJS0
	JUMPE	2,CPOPJ		;ANY?
	MOVN	F,2
	MOVSI	F,(F)		;GET AOBJN FOR FILES
	ADDI	F,1
 
FILTOP:	MOVE	2,[SIXBIT "FILSTS"]
	CALL	GETFIL
	TLNN	2,(GS%NAM+GS%ASG)
	 JRST	FILBOT
	MOVEM	2,FILSTS
	MOVE	BP,[ASCIIP TMPSTR]
 
	MOVE	2,[SIXBIT "FILDDN"] ;GET ^DEV,,DIR#
	CALL	GETFIL		;GET JSB FILE WORD
	HLRZ	2,2		;GET DEV STRBLK PTR
	MOVEM	BP,TMPDEV	;STORE BP
	CALL	GETSTR		;GET DEVICE STRING
	TLNE	FL,(FL$WDV)	;ANY DEVICE?
	 JRST	CHKDIR		; YES, NO NEED TO CHECK
	MOVE	1,TMPDEV
	MOVE	2,WLDDEV
	CALL	.WILD
	 JRST	FILBOT
 
CHKDIR:	MOVE	2,[SIXBIT "FILDNM"] ;GET ^DIR,,^ATRIB
	CALL	GETFIL
	HLRZ	2,2		;GET DIR STRBLK PTR
	MOVEM	BP,TMPDIR
	CALL	GETSTR
	TLNE	FL,(FL$WDR)	;ALLOW ANY DIR?
	 JRST	CHKFIL		; YES, DONT BOTHER
	MOVE	1,TMPDIR
	MOVE	2,WLDDIR
	CALL	.WILD
	 JRST	FILBOT
 
CHKFIL:	MOVE	2,[SIXBIT "FILNEN"] ;GET ^NAME,,^EXT
	CALL	GETFIL
	PUSH	P,2
	HLRZ	2,2		;GET FILE STRBLKPTR
	MOVEM	BP,TMPFIL	;STORE FILE BP
	CALL	GETSTR		;GET STRING
	TLNE	FL,(FL$WFL)	;TOTALLY WILD FILE?
	 JRST	CHKEXT		; YES, PUNT THE .WILD CALL
	MOVE	1,TMPFIL
	MOVE	2,WLDFIL
	CALL	.WILD
	 JRST [	POP	P,(P)
		JRST	FILBOT ]
CHKEXT:	POP	P,2		;GET EXT
	MOVEM	BP,TMPEXT	;STORE EXT BP
	CALL	GETSTR		;GET STRING
	TLNE	FL,(FL$WEX)	;EXT=*?
	 JRST	CHKVER		; YES, GO RIGHT TO VERSION
	MOVE	1,TMPEXT
	MOVE	2,WLDEXT
	CALL	.WILD
	 JRST	FILBOT
 
CHKVER:	MOVE	2,[SIXBIT "FILVER"] ;GET FORK,,VERSION
	CALL	GETFIL
	MOVEI	2,(2)		;ISOLATE VERSION
	MOVEM	BP,TMPVER
	MOVE	1,BP
	MOVEI	3,10.
	NOUT
	 TRNA
	 MOVE	BP,1
	SETZ	1,
	IDPB	1,BP
	TLNE	FL,(FL$WVR)	;ANY VERSION WILL DO
	 JRST	WINNER		; WE HAVE A WINNER
	MOVE	1,TMPVER
	MOVE	2,WLDVER
	CALL	.WILD
	 JRST	FILBOT
 
WINNER:	CALL	HDRCHK
	MOVEI	1,.PRIOU
	MOVEI	2,(J)
	MOVE	3,[NO%LFL\Field(3,NO%COL)\10.]
	NOUT
	 .LOSE
 
	MOVEI	2,(F)
	MOVE	3,[NO%LFL\Field(4,NO%COL)\10]
	NOUT
	 .LOSE
	TYPE	"  "
 
	MOVE	BP,[ASCIIP [ASCIZ 'Not logged in']]
	HRROI	1,USRBUF
	MOVE	2,USRNUM
	JUMPE	2,NOUSRN
	DIRST
	 .LOSE
	SETZ	3,
	IDPB	3,1
	MOVE	BP,[ASCIIP USRBUF]
NOUSRN:	MOVEI	4,15.
	CALL	TFIELD
 
TYPDEV:	MOVE	1,TMPDEV	;GET DEVICE
	CALL	ISNULL
	 JRST	TYPDIR
	MOVE	1,TMPDEV
	PSOUT
	TYPE	":"
TYPDIR:	MOVE	1,TMPDIR
	CALL	ISNULL
	 JRST	TYPFIL
	TYPE	"<"
	MOVE	1,TMPDIR
	PSOUT
	TYPE	">"
TYPFIL:	MOVE	1,TMPFIL
	PSOUT
	TYPE	"."
	MOVE	1,TMPEXT
	PSOUT
	MOVE	1,TMPVER
	CALL	ISNULL
	 JRST	TYPEND
	TYPE	"."
	MOVE	1,TMPVER
	PSOUT
TYPEND:	TYPECR	""
FILBOT:	AOBJN	F,FILTOP
	RET
 
GETFIL:	MOVEI	3,(F)		;GET JFN INDEX
	IMUL	3,MLJFN
	TRNA
GETJS0:	 SETZ	3,
GETJSB:	MOVEI	1,.RDJSB
	MOVEI	4,(J)
	MONRD
	 ERJMP	NOMONRD
	JUMPN	1,[SETZ	2, ? RET]
CPOPJ:	RET
 
GETSTR:	ANDI	2,-1		;KEEP ONLY RIGHT HALF
	JUMPE	2,STR.X		;IF NO POINTER, RETURN
	SUB	2,JSVAR		;REMOVE JSB OFFSET
	MOVEM	2,TXTPTR	;SAVE THE OFFSET
	MOVEI	5,8.		;THIS MANY WORDS TO GET
GETS.L:	MOVE	2,[SIXBIT 'JSVAR'] ;BASE ADDRESS OF WORD
	AOS	3,TXTPTR	;INCREMENT TO NEXT WORD
	CALL	GETJSB		;READ THE WORD
 
	MOVE	4,[ASCIIP 2]
	MOVEI	3,5
STR.L:	ILDB	1,4
	JUMPE	1,STR.X
	IDPB	1,BP
	SOJG	3,STR.L
	SOJG	5,GETS.L
STR.X:	SETZ	1,
	IDPB	1,BP
	RET
 
NOMONRD:
	HRROI	1,[ASCIZ "MONRD JSYS cannot be used"]
	ESOUT
	.LOGOUT

;SUBROUTINE TO COMPARE A STRING TO A WILD-CARD STRING. (FROM WILD% JSYS)
;ARGS:	T1/  BYTE POINTER TO STRING TO BE CHECKED
;	T2/  BYTE POINTER TO WILDCARD STRING
;
;RETURNS +1:	NO MATCH
;	 +2:	TEST STRING IS MATCHED BY WILD STRING.
 
.WILD:	SETZB	4,SVMSK		;INITIALIZE OLD CHAR AND MASK
 
CHKWLL:	ILDB	3,2		;GET NEXT CHAR OF MASK
	JUMPE	3,[		;END OF MASK..
		CAIN	4,"*	;DID WILD STRING END IN ASTERISK
		 JRST	CPOPJ1	;YES, STRINGS MATCH
		ILDB	3,1	;GET NEXT CHAR FROM TEST STRING
		JUMPN	3,FAIL	;IF NOT ALSO DONE, STRETCH MASK
		JRST	CPOPJ1]	;OTHERWISE STRINGS MATCH
	MOVE	4,3		;SAVE NEWEST CHAR FOR LATER USE
	CAIN	4,"*		;FULL WILDCARD?
	 JRST [	MOVEM 1,SVPTR	;YES, REMEMBER CURRENT POINTERS
		MOVEM 2,SVMSK	;IN CASE WE HAVE TO STRETCH MASK
		JRST CHKWLL]	;CONTINUE
	ILDB	3,1		;GET NEXT CHAR OF TEST STRING
	JUMPE	3,CPOPJ		;IF NO MORE, PARTIAL MATCH
	CAIE	3,(4)		;CHARACTERS FROM THE TWO STRINGS MATCH?
	 CAIN	4,"%		;OR IS THIS THE SINGLE WILDCARD CHAR?
	  JRST	CHKWLL		;YES, CONTINUE
 
FAIL:	SKIPN	2,SVMSK		;WAS THERE A PREVIOUS ASTERISK?
	 RET			;NO, THEN STRINGS DON'T MATCH
	IBP	SVPTR		;YES, ADVANCE THE TEST STRING POINTER
	MOVE	1,SVPTR		;GET NEW POINTER
	JRST	CHKWLL		;TRY AGAIN
 
;CHECK IF BP POINTS TO NULL STRING
; 1/	BP
;	CALL	ISNULL
;	 <NULL>
;	<NOT NULL>
ISNULL:	MOVE	2,1		;GET BP COPY
	ILDB	3,2		;GET FIRST BYTE
	CAIE	3,0		;NULL?
CPOPJ1:	 AOS	(P)		; NO
	RET			;YES
 
DIE:	CALL	BARF
	.LOGOUT
 
; 4/	COUNT
; BP/	BYTE PTR
TFIELD:	ILDB	1,BP
	JUMPE	1,EFIELD
	PBOUT
	SOJGE	4,TFIELD
	TYPE	"!"
	RET
 
EFIELD:	MOVEI	1,<" >
	PBOUT
	SOJGE	4,.-1
	RET
 
HDRCHK:	TLOE	FL,(FL$HDR)
	 RET
	TYPE	"Job JFN  User            File
"
	RET
 
JUNK:	END	3,,EV
  