Google
 

Trailing-Edge - PDP-10 Archives - AP-D543V_SB - fildae.mac
There are 7 other files named fildae.mac in the archive. Click here to see a list.
	TITLE	FILDAE - TELL FILSER HIGHEST ACCESS ALLOWED TO A FILE
	SUBTTL	J.M.FLEMMING/JMF	21-MAR-77
	SEARCH	MACTEN,UUOSYM,SCNMAC
	.REQUEST	REL:SCAN
	.REQUEST	REL:HELPER
;***COPYRIGHT 1976, 1977, DIGITAL EQUIPMENT CORP., MAYNARD MASS.***

VFILDAE==1			;VERSION NUMBER
VWHO==0				;WHO EDITED LAST
VMINOR==0			;MINOR VERSION NUMBER
VEDIT==16			;EDIT NUMBER

.JBVER==137

	LOC	.JBVER		;PUT VERSION NUMBER IN .JBVER
	BYTE	(3)VWHO(9)VFILDAE(6)VMINOR(18)VEDIT
	RELOC

	SUBTTL	DEFINITIONS

;ACCUMULATOR ASSIGNMENTS
T1=1				;TEMPORARY ACCUMULATORS
T2=2				; ..
T3=3				; ..
T4=4				; ..
P1=5				;PRESERVED ACCUMULATORS
P2=6				; ..
P3=7				; ..
P4=10				; ..
J=11				;JOB NUMBER OF FILE ACCESSOR
D=12				;PPN OF FILE ACCESSOR
C=13				;CODE FROM FILSER INDICATING MESSAGE TYPE
M=16				;ADDRESS OF THE IPCF MESSAGE
P=17				;PUSH DOWN LIST POINTER

;ERROR
DEFINE ERROR<HALT	.>
;I/O CHANNEL ASSIGNMENTS
DSK==1

;LENGTH OF THE PUSH-DOWN LIST
PDLL==400

;LOCATIONS IN THE IPCF MESSAGE
M.CODE==0			;HIGHEST ACCESS ATTEMPTED,,REASON FILE DAEMON WAS CALLED
M.STR==1			;FILE STR WHERE FILE BEING ACCESSED WAS FOUND
M.FILE=2			;NAME OF THE FILE BEING ACCESSED
M.EXT==3			;EXTENSION OF THE FILE BEING ACCESSED
M.PPN==4			;DIRECTORY OF THE FILE BEING ACCESSED
M.PATH==5			;PATH TO THE FIE WITHIN THE DIRECTORY

;HIGHEST FUNCTION ALLOWED
FNCCPR==15			;CHANGE PROTECTION
FNCCNM==14			;CHANGE NAME
FNCDEL==13			;DELETE
FNCCAT==12			;CHANGE ATTRIBUTES
FNCTRN==11			;TRUNCATE
FNCSUP==10			;SUPERCEDE
FNCCRE==7			;CREATE
FNCUPD==6			;UPDATE
FNCAPP==5			;APPEND
FNCDLL==4			;DEALLOCATE
FNCALL==3			;ALLOCATE
FNCRED==2			;READ
FNCEXE==1			;EXECUTE
FNCNAA==0			;NO ACCESS ALLOWED
	SUBTTL	SCAN INTERFACE MACROS

DEFINE SWTCHS,<
SS RUN,FOO,0			;DON'T ALLOW SCAN'S BUILT IN RUN SWITCH
SS CREATE,FCREAT,0,FS.NOS	;ALLOW CREATE IN A DIRECTORY PROTECTED AGAINST CREATE
SL LOG,FLOG,LOGS,LOGSAL		;LOG ACCESS TO THE FILE
SS NOLOG,FLOG,0,0		;DON'T LOG ACCESS TO THE FILE (FOR COMPATABILITY)
SS EXIT,FEXIT,0,FS.NOS		;IF LOGGING, LOG EXIT IF A PROGRAM IS BEING RUN
SS CLOSE,FCLOSE,0,FS.NOS	;IF LOGGING, LOG CLOSE OF A FILE
SS ALL,FSWICH,FNCCPR		;ALL ACCESS ALLOWED
SS RENAME,FSWICH,FNCDEL		;RENAME ALLOWED
SS WRITE,FSWICH,FNCSUP		;WRITE (SUPERSEDE) ALLOWED
SS UPDATE,FSWICH,FNCUPD		;UPDATE ALLOWED
SS APPEND,FSWICH,FNCAPP		;APPEND ALLOWED
SS READ,FSWICH,FNCRED		;READ ALLOWED
SS EXECUTE,FSWICH,FNCEXE	;EXECUTION ALLOWED
SS NONE,FSWICH,FNCNAA		;NO ACCESS ALLOWED
SS XONLY,FXONLY,0,FS.NOS	;ONLY GRANT PROGRAM ACCESS IF IT IS EXUCUTE ONLY
SP PROGRAM,FPRGM,.SWFIL##,PRO,FS.VRQ
>

KEYS	(LOGS,<ALL,NONE,SUCCESSES,FAILURES>)

MX.PRO==.FXLEN
PD.PRO==0
DEFINE FNC(TEXT)<
	[ASCIZ	/TEXT/]>

;TABLE OF HIGHEST ACCESS ATTEMPTED BY ACCESSOR
; USED TO LOG HIGHEST ACCESS ATTEMPTED IN ACCESS.LOG
ACCESS:	FNC	<Execute>
	FNC	<Read>
	FNC	<Allocate>
	FNC	<Deallocate>
	FNC	<Append>
	FNC	<Update>
	FNC	<Create>
	FNC	<Supercede>
	FNC	<Truncate>
	FNC	<Change Attributes>
	FNC	<Delete>
	FNC	<Change Name>
	FNC	<Change Protection>
ACTION:	FNC	<Input Close>
	FNC	<Output Close>
	FNC	<Program Execution Terminated>
	FNC	<Execution>
DOSCAN	(S)			;DEFINE SCAN TABLES
	SUBTTL	MAIN LOOP

FILDAE:	RESET			;RESET THE WORLD
	MOVE	P,[-PDLL,,PDL]	;SETUP A PUSH DOWN LIST POINTER
	PUSHJ	P,FDINIT	;INITIALIZE THE FILE DAEMON
	MOVE	T1,.JBFF	;FIRST FREE LOCATION
	MOVEM	T1,SAVFF	;SAVE THAT TO REINITIALIZE SIZE
	MOVX	T1,%LDFFA	;FULL FILE ACCESS PPN
	GETTAB	T1,		;GET THAT
	  ERROR			;MUST BE IMPLEMENTED
	MOVEM	T1,FFAPPN	;SAVE FULL FILE ACCESS PPN
	OUTSTR	[ASCIZ /DETACHING
./]				;TELL THE WORLD
	SETO	T1,		;OUR TTY
	GETLCH	T1		;GET ITS LINE NUMBER
	HRLZS	T1		;LINE NUMBER,,DETACH
	ATTACH	T1,		;DETATCH FROM THE TERMINAL
	  JFCL			;OH WELL
FILDA1:	MOVE	P,[-PDLL,,PDL]	;SCAN DOESN'T ALWAYS RETURN WITH THE STACK RIGHT
	MOVEI	T1,.POPJ##	;SET TO THROW OUTPUT FROM SCAN AWAY
	MOVEM	T1,TYO		;WHERE SCAN GOES TO TYPE OUT CHARACTERS
	MOVE	T1,SAVFF	;OUR ORIGINAL SIZE
	MOVEM	T1,.JBFF	;RESET WHERE BUFFERS, ETC. GO
	CORE	T1,		;REDUCE TO ORIGINAL SIZE
	  JFCL			;CAN'T WIN THEM ALL
	PUSHJ	P,FDRECV	;GET AN IPCF MESSAGE FROM FILSER
	MOVEI	T1,.RBAUT	;GET DATA FROM THE RIB THROUGH THE AUTHOR
	MOVEM	T1,LEB.BL	;STORE THAT
	MOVE	T1,[FO.PRV+.FORED(DSK)]
	MOVEM	T1,FOP.BL	;READ INVOKING PRIVILEDGES
	MOVE	T1,M.STR(M)	;FILE STRUCTURE
	MOVEM	T1,FOP.DV	;STORE THAT FOR OPEN PART OF FILOP.
	MOVE	T1,[SIXBIT /ACCESS/]
	MOVEM	T1,LEB.FL	;FILE NAME OF THE ACCESS LIST
	MOVSI	T1,(SIXBIT /USR/)
	MOVEM	T1,LEB.XT	;EXTENSION OF THE ACCESS LIST
	SETZM	FOP.BH		;NO BUFFERS ARE NEEDED
	SETZM	FOP.NB		; ..
	SETZM	LEB.AW		;ZERO THE ATTRIBUTES WORD
	MOVEI	T1,LEB.PB	;ADDRESS OF THE PATH BLOCK
	MOVEM	T1,LEB.PT	;STORE THAT
	HLRZ	T2,M.EXT(M)	;FILE OR DIRECTORY EXTENSION
	CAIE	C,.FLDDA	;A DIRECTORY ACCESS?
	MOVEI	T2,0		;NO, TREAT IT AS A FILE EVEN IF THE
				; EXTENSION IS SFD OR UFD
	MOVE	T1,M.PPN(M)	;FILE'S DIRECTORY
	CAIN	T2,'UFD'	;IS THE FILE A DIRECTORY?
	MOVE	T1,M.FILE(M)	;YES, FILE NAME IS PPN
	MOVEM	T1,LEB.PP	;STORE PPN
	MOVEI	T1,M.PATH(M)	;ADDRESS OF THE PATH IN THE MESSAGE
	MOVE	T4,[LEB.SF,,LEB.SF+1]
	SETZB	T3,LEB.SF	;ZERO THE PATH BLOCK
	BLT	T4,LEB.SF+4	; ..
FILDA2:	SKIPN	T4,(T1)		;GET NEXT SFD FROM MESSAGE
	JRST	FILDA3		;THE LAST ONE
	MOVEM	T4,LEB.SF(T3)	;STORE SFD IN LOOKUP BLOCK
	ADDI	T1,1		;POINT AT NEXT SFD
	AOJA	T3,FILDA2	;NEXT PATH ELEMENT
FILDA3:	MOVE	T1,M.FILE(M)	;FILE NAME
	CAIN	T2,'SFD'	;READING AN SFD AS A FILE?
	MOVEM	T1,LEB.SF(T3)	;YES, STORE FILE NAME AS LAST ELEMENT OF THE PATH
	MOVE	T1,[7,,FOP.BL]	;LOOKUP ACCESS.USR AND GET THE ACTUAL PATH
	FILOP.	T1,		; WHERE IT WAS FOUND
	  JRST	[JUMPE T1,FILD21;JUMP IF FILE NOT FOUND
		JRST FILD22]	;ALLOW NO ACCESS TO THE FILE
	MOVE	T1,LEB.AT	;AUTHOR OF ACCESS.USR
	CAME	T1,LEB.PP	;SAME AS OWNER OF THE FILE?
	CAMN	T1,FFAPPN	;NO, FULL FILE ACCESS PPN?
	CAIA			;YES, SCAN ACCESS.USR
	JRST	FILD21		;NO, TREAT IT THE SAME AS IF THERE WAS NO ACCESS.USR
	CAIN	C,.FLDDA	;DIRECTORY ACCESS?
	JRST	FILDA4		;YES
	SETOM	IPS.DT+.IPCS1	;MAKE SURE ACCOUNTING LINE IS OUTPUT TO
				; THE LOG FILE IF EXIT OR CLOSE
	CAIE	C,.FLDCA	;FILE ACCESS?
	CAIN	C,.FLDPG	;OR RUNNING A PROGRAM?
FILDA4:	TDZA	T1,T1		;YES, SEE IF ACCESS IS ALLOWED
	JRST	FILD27		;NO, MUST BE CLOSE OR PROGRAM EXECUTION TERMINATED
				; JUST GO MAKE A LOG ENTRY
	SETZB	T2,PATHMM	;ASSUME ACCESS.USR WAS FOUND ON THE SAME
				; PATH AS THE FILE BEING ACCESSED
FILDA5:	MOVE	T3,PTH.PP(T1)	;DIRECTORY COMPONENT ON PATH TO ACCESS.USR
	CAME	T3,LEB.PP(T2)	;SAME AS COMPONENT ON THE PATH TO THE FILE?
	SETOM	PATHMM		;NO, PATH IN ACCESS.USR MUST MATCH PATH TO FILE
	JUMPE	T3,FILDA6	;JUMP IF THE ENTIRE PATH HAS BEEN EXAMINED
	ADDI	T1,1		;POINT AT NEXT DIRECTORY COMPONENT
	AOJA	T2,FILDA5	;AND SEE IF NEXT COMPONENTS MATCH
;HERE TO SCAN ACCESS.USR LOOKING FOR A FILESPEC MATCH
FILDA6:	SETOM	SCNBLK		;INITIALIZE SCAN BLOCK
	MOVE	T1,[SCNBLK,,SCNBLK+1]
	BLT	T1,SCNBLK+SCNBKL-1
	MOVE	T1,PTH.BL	;FILE STRUCTURE NAME
	MOVEM	T1,SCNDEV	;STORE THAT FOR SCAN
	MOVE	T1,[SIXBIT /ACCESS/]
	MOVEM	T1,SCNNAM	;FILE NAME
	MOVSI	T1,(SIXBIT /USR/)
	HLLM	T1,SCNEXT	;FILE EXTENSION
	MOVE	T1,[FX.DIR+FX.PHY]
	MOVEM	T1,SCNMOD	;FORCE A PHYSICAL ONLY OPEN
	MOVEI	T1,PTH.PP	;PATH TO ACCESS.USR
	MOVEI	T2,SCNDIR	;WHERE SCAN WANTS THE PATH FOR AN INDIRECT FILE
	MOVEI	T3,.FXLND	;MAXIMUM LENGTH OF A FULL PATH
FILDA7:	SKIPN	T4,(T1)		;SKIP IF NEXT DIRECTORY COMPONENT WAS SPECIFIED
	JRST	FILDA8		;FULL PATH HAS BEEN COPIED
	MOVEM	T4,(T2)		;STORE DIRECTORY COMPONENT IN SCAN BLOCK
	ADDI	T1,1		;NEXT COMPONENT IN THE PATH
	ADDI	T2,2		;NEXT WORD IN THE SCAN BLOCK
	SOJG	T3,FILDA7	;COPY THE ENTIRE PATH
FILDA8:	SETZM	(T2)		;INDICATE END
	MOVE	T1,[5,,[0
			0
			XWD	0,TYPE
			XWD	SCNBKL,SCNBLK
			XWD	.POPJ##,FILD22]]
	PUSHJ	P,.ISCAN##	;INITIALIZE SCAN
FILDA9:	MOVE	T1,[7,,[IOWD	SL,SN
			XWD	SD,SM
			XWD	0,SP
			0
			XWD	CLRALL,CLRFIL
			XWD	ALIN,ALOUT
			XWD	0,APLSTY]]
	PUSHJ	P,.TSCAN##	;SCAN ACCESS.USR
;HERE TO SEE IF THE PPN OF THE ACCESSOR MATCHES PPN'S SPECIFIED IN ACCESS.USR
	MOVE	T1,NINFIL	;NUMBER OF INPUT FILES
	MOVE	P2,T1		;ALSO TO P2
	JUMPE	T1,FILDA9	;JUMP IF NO INPUT FILES SPECIFIED
	MOVE	P1,.JBFF	;CURRENT FIRST FREE LOCATION
	IMULI	T1,INLEN	;NUMBER OF INPUT FILES * LENGTH OF INPUT SCAN BLOCK
	SUB	P1,T1		;ADDRESS OF FIRST INPUT SCAN BLOCK
FILD10:	SKIPGE	.FXMOD(P1)	;ILLEGAL IF A DEVICE NAME WAS SPECIFIED
	SKIPE	.FXNAM(P1)	;ILLEGAL IF A FILE NAME WAS SPECIFIED
	JRST	FILD11		;SKIP THIS ILLEGAL SCAN BLOCK
	SKIPN	.FXEXT(P1)	;ILLEGAL IF AN EXTENSION WAS SPECIFIED
	SKIPE	.FXDIR+2(P1)	;ILLEGAL IF SFD'S WERE SPECIFIED
	JRST	FILD11		;SKIP THIS ILLEGAL SCAN BLOCK
	MOVX	T1,FX.DIR	;DIRECTORY WAS SPECIFIED BIT
	TDNN	T1,.FXMOD(P1)	;WAS A DIRECTORY SPECIFIED?
	JRST	FILD11		;NO, SKIP THIS ILLEGAL SCAN BLOCK
	SKIPN	T1,.FXDIR(P1)	;A REAL PPN TYPED?
	SKIPA	T1,M.PPN(M)	;NO, MUST BE [-], USE DEFAULT
	SKIPA	T3,.FXDIM(P1)	;PPN MASK FORM ACCESS.USR
	SETO	T3,		;PPN MASK OF [*,*]
	MOVE	T2,D		;PPN OF ACCESSOR
	PUSHJ	P,MATCHS	;DOES THE PPN FROM ACCESS.USR MATCH THE PPN 
				; OF THE ACCESSOR?
	  CAIA			;NO, LOOK AT THE NEXT ENTRY IN ACCESS.USR
	JRST	FILD12		;YES, ALLOW ACCESS AS SPECIFIED BY ACCESS.USR
FILD11:	ADDI	P1,INLEN	;NEXT SCAN BLOCK
	SOJG	P2,FILD10	;LOOK AT ALL PPNS ON THE LINE FROM ACCESS.USR
	JRST	FILDA9		;READ THE NEXT LINE FROM ACCESS.USR
;HERE WHEN ACCESSOR'S PPN WAS FOUND IN ACCESS.USR.
; NOW SEE IF THE FILE SPEC MATCHES THE LEFT HAND SIDE AND IF SO,
; USE SWITCH VALUE FOR HIGHEST ACCESS ALLOWED TO THE FILE
FILD12:	SKIPN	I.PRGM(P1)	;WAS /PROGRAM SEEN?
	JRST	FILD16		;NO, SEE IF FILE SPEC MATCHES
;HERE WHEN /PROGRAM WAS SPECIFIED IN ACCESS.USR
	SKIPN	I.PRGM+.FXEXT(P1)
	SKIPE	I.PRGM+.FXDIR+2(P1)
	JRST	FILD11		;SKIP THIS ILLEGAL SCAN BLOCK
	MOVE	T1,I.PRGM+.FXNAM(P1)
	HRLZ	T2,J		;JOB NUMBER OF THE ACCESSOR
	HRRI	T2,.GTRFN	;NAME OF THE PROGRAM THAT THE ACCESSOR IS RUNNING
	GETTAB	T2,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	MOVE	T3,I.PRGM+.FXNMM(P1)
	PUSHJ	P,MATCHS	;SEE IF PROGRAM SPECIFIED IN ACCESS.USR
				; MATCHS THE PROGRAM THE ACCESSOR IS RUNNING
	  JRST	FILD11		;IT DOESN'T, LOOK AT THE NEXT ENTRY ON THIS LINE
;HERE WHEN PROGRAM NAMES MATCH
	SKIPGE	I.PRGM+.FXMOD(P1)
	JRST	FILD15		;NO DEVICE WAS SPECIFIED
	HRLZ	P3,J		;JOB NUMBER OF THE ACCESSOR
	HRRI	P3,.GTRDV	;STR WHERE THE ACCESSING PROGRAM CAME FROM
	GETTAB	P3,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	MOVE	T1,I.PRGM+.FXDEV(P1)
	MOVEM	T1,ACS.WB	;STORE DEVICE NAME FROM ACCESS.USR
	MOVE	T1,[3,,ACS.WB]	;ARGUMENT TO PATH.
	PATH.	T1,		;GET INFO ABOUT THE DEVICE
	  JRST	FILD11		;NO SUCH DEVICE, LOOK AT NEXT ENTRY
	MOVX	T1,PT.LIB	;IN CASE WE HAVE A LIB SET AND LIB WAS SPECIFIED
	TDNE	T1,ACS.WB+.PTSWT; IN ACCESS.USR, DON'T ALLOW LIB
	JRST	FILD11		; SINCE IT MAKES NO SINCE
	LDB	T1,[POINTR (ACS.WB+.PTSWT,PT.SLT)]
	CAXN	T1,.PTSLA	;ALL SEARCH LIST?
	JRST	FILD15		;YES, DEVICES MATCH
	MOVX	T2,PT.IPP	;AN IMPLIED PPN?
	TDNN	T2,ACS.WB+.PTSWT;TEST THAT
	JRST	FILD14		;NO, PROBABLY STR NAME OR DSK
;HERE IF THE DEVICE FROM ACCESS.USR HAS AN IMPLIED PPN
	SKIPE	I.PRGM+.FXDIR(P1)
	JRST	FILD11		;PPN WAS SPECIFIED, THAT'S ILLEGAL
	MOVE	T2,ACS.WB+.PTPPN;GET THE IMPLIED PPN
	MOVEM	T2,I.PRGM+.FXDIR(P1)
	SETOM	I.PRGM+.FXDIM(P1)
	MOVX	T2,FX.DIR	;DIRECTORY WAS SPECIFIED BIT
	IORM	T2,I.PRGM+.FXMOD(P1);INDICATE THAT
	CAXE	T1,.PTSLS	;SYS SEARCH LIST?
	JRST	FILD14		;NO, NEED MORE INFORMATION
;HERE IF THE SEARCH LIST FOR THE DEVICE SPECIFIED IN ACCESS.USR IS
; THE SYS SEARCH LIST
	MOVEI	T1,0		;FIRST STR IN THE SYS SEARCH LIST
FILD13:	SYSSTR	T1,		;GET THE NEXT STR FROM THE SYS SEARCH LIST
	  ERROR			;WHAT?
	JUMPE	T1,FILD11	;JUMP IF ALL STRS IN SYS SEARCH LIST HAVE BEEN CHECKED
	CAMN	T1,P3		;SAME AS THE STR WHERE THE ACCESSING PROGRAM CAME FROM?
	JRST	FILD15		;YES, DEVICE NAMES MATCH
	JRST	FILD13		;NO, LOOK AT NEXT STR IN S.S.L.
;HERE IF THE SEARCH LIST FOR THE DEVICE SPECIFIED IN ACCESS.USR IS
; NOT THE SYS SEARCH LIST
FILD14:	MOVE	T1,[5,,ACS.WB]	;ARGUMENT TO DSKCHR
	DSKCHR	T1,		;GET DSK CHARACTERISTICS
	  JRST	FILD11		;NOT A DSK?
	LDB	T1,[POINTR (T1,DC.TYP)]
XX==.DCTDS			;CREF THE SYMBOL USED IN THE JUMPE
	JUMPE	T1,FILD15	;IF GENERIC, THEN ITS DSK AND DEVICE NAMES MATCH
	CAXE	T1,.DCTFS	;FILE STR NAME?
	JRST	FILD11		;NO, ANYTHING ELSE IS ILLEGAL
	CAME	P3,ACS.WB+.DCSNM;SAME AS THE NAME FROM ACCESS.USR?
	JRST	FILD11		;NO, LOOK ONWARD
;HERE WHEN THE FILE STRUCTURE WHERE THE PROGRAM CAME FROM MATCHES
; THE FILE STRUCTURE SPECIFIED IN ACCESS.USR
FILD15:	HRLZ	T2,J		;JOB NUMBER OF THE ACCESSOR
	HRRI	T2,.GTRDI	;DIRECTORY WHERE THE ACCESSING PROGRAM CAME FROM
	GETTAB	T2,		;GET THAT
	  ERROR			;HUH?
	JUMPE	T2,FILD11	;CAN'T MATCH IF NOT FROM DSK
	MOVX	T1,FX.DIR	;DIRECTORY WAS SPECIFIED BIT
	TDNE	T1,I.PRGM+.FXMOD(P1)
	SKIPN	T1,I.PRGM+.FXDIR(P1)
	SKIPA	T1,M.PPN(M)	;NOT SPECIFIED OR [-], USE DEFAULT OF OWNER'S PPN
	SKIPA	T3,I.PRGM+.FXDIM(P1)
	SETO	T3,		;-1 FOR PPN MASK
	MOVE	T4,IPR.BL+.IPCFC;CAPABILITIES
	SKIPLE	I.XO(P1)	;EXECUTE ONLY PROGRAM REQUIRED?
	TXNE	T4,IP.SXO	;YES, AND IS THE ACCESSING PROGRAM EXECUTE ONLY?
	PUSHJ	P,MATCHS	;DOES DIRECTORY FROM ACCESS.USR MATCH THE
				; DIRECTORY THAT THE ACCESSING PROGRAM CAME FROM?
	  JRST	FILD11		;NO, PRESS ON
;HERE TO SEE IF STR WHERE FILE IS BEING ACCESSED MATCHES STR FROM ACCESS.USR
FILD16:	SKIPE	PPRGM		;/PROGRAM SPECIFIED IN OUTPUT FILE SPEC?
	JRST	FILDA9		;YES, ERROR, LOOK AT NEXT LINE IN ACCESS.USR
	SKIPGE	OUTBLK+.FXMOD	;WAS A DEVICE SPECIFIED?
	JRST	FILD17		;NO
	MOVE	T1,OUTBLK+.FXDEV;DEVICE NAME SPECIFIED IN ACCESS.USR
	CAME	T1,M.STR(M)	;DOES IT MATCH STR NAME WHERE THE FILE IS BEING ACCESSED?
	JRST	FILDA9		;NO, READ THE NEXT LINE FROM ACCESS.USR
;HERE TO SEE IF FILE NAMES MATCH
FILD17:	SKIPN	T1,OUTBLK+.FXNAM;FILE NAME FROM ACCESS.USR
	JRST	FILD18		;NONE SPECIFIED, FILE NAMES MATCH
	MOVE	T2,M.FILE(M)	;FILE NAME OF FILE BEING ACCESSED
	MOVE	T3,OUTBLK+.FXNMM;FILE NAME MASK FROM ACCESS.USR
	PUSHJ	P,MATCHS	;DO THE FILE NAMES MATCH?
	  JRST	FILDA9		;NO, LOOK AT THE NEXT LINE IN ACCESS.USR
;HERE TO SEE IF FILE EXTENSIONS MATCH
FILD18:	HLLZ	T1,OUTBLK+.FXEXT;EXTENSION FROM ACCESS.USR
	MOVE	T2,M.EXT(M)	;EXTENSION OF THE FILE BEING ACCESSED
	HRLZ	T3,OUTBLK+.FXEXT;EXTENSION MASK FROM ACCESS.USR
	PUSHJ	P,MATCHS	;DO THE EXTENSIONS MATCH?
	  JRST	FILDA9		;NO, LOOK AT THE NEXT LINE IN ACCESS.USR
;HERE TO SEE IF PATHS MATCH. THEY MUST IF PATHMM.NE.0 OR A PATH WAS
; SPECIFIED IN ACCESS.USR
	MOVX	T1,FX.DIR	;DIRECTORY WAS SPECIFIED BIT
	TDNE	T1,OUTBLK+.FXMOD;WAS A DIRECTORY SPECIFIED IN ACCESS.USR?
	SKIPE	T1,OUTBLK+.FXDIR;YES, WAS IT [,]?
	JRST	FILD19		;NO
	MOVE	T1,M.PPN(M)	;YES, FILL IN DEFAULT DIRECTORY
	MOVEM	T1,OUTBLK+.FXDIR; IN THE SCAN BLOCK
	SETOM	OUTBLK+.FXDIM	;AND THE DEFAULT MASK
FILD19:	SKIPN	PATHMM		;MUST PATH IN ACCESS.USR MATCH PATH TO THE FILE?
	SKIPE	OUTBLK+.FXDIR	;NO, WAS A DIRECTORY SPECIFIED IN ACCESS.USR
	SKIPA	T2,LEB.PP	;YES, DIRECTORIES MUST MATCH
	JRST	FILD23		;NO, FILE SPECS MATCH
	MOVE	T3,OUTBLK+.FXDIM;DIRECTORY WILD CARD MASK
	PUSHJ	P,MATCHS	;SEE IF DIRECTORIES MATCH
	  JRST	FILDA9		;NO MATCH, READ NEXT LINE IN ACCESS.USR
	MOVEI	P2,OUTBLK+.FXDIR+2;ADDRESS OF THE PATH IN THE SCAN BLOCK
	MOVEI	P3,M.PATH(M)	;ADDRESS OF THE PATH TO THE FILE BEING ACCESSED
	MOVEI	P4,.FXLND	;MAXIMUM LENGTH OF A PATH
FILD20:	MOVE	T1,(P2)		;DIRECTORY COMPONENT FROM THE SCAN BLOCK
	SKIPN	T2,(P3)		;COMPONENT FROM THE MONITOR
	JUMPE	T1,FILD23	;JUMP IF DIRECTORIES MATCH
	MOVE	T3,1(P2)	;DIRECTORY MASK FROM THE SCAN BLOCK
	PUSHJ	P,MATCHS	;SEE IF DIRECTORY COMPONENTS MATCH
	  JRST	FILDA9		;THEY DON'T, LOOK AT THE NEXT LINE IN ACCESS.USR
	ADDI	P2,2		;NEXT ENTRY IN THE SCAN BLOCK
	ADDI	P3,1		;NEXT ELEMENT OF THE PATH
	SOJG	P4,FILD20	;LOOP OVER ALL ELEMENTS OF THE DIRECTORY SPEC
	JRST	FILD23		;TELL FILSER THE ANSWER
;HERE WHEN ACCESS.USR WASN'T FOUND. RETURN DEFAULT VALUE (FNCAPP) AS HIGHEST ACCESS
; ALLOWED TO THE FILE OR (FNCCPR) IF FULL FILE ACCESS PROGRAM
FILD21:	MOVE	T1,IPR.BL+.IPCFC;ACCESSOR'S CAPABILITIES
	CAME	D,FFAPPN	;[1,2]?
	TXNE	T1,IP.JAC	;OR JACCT?
	SKIPA	T1,[FNCCPR]	;YES, ALLOW ALL ACCESS
;HERE IF NO ACCESS IS TO BE ALLOWED TO THE FILE
FILD22:	MOVEI	T1,FNCNAA	;NO ACCESS ALLOWED
	SETZM	PLOG		;DON'T LOG ACCESS
	MOVEI	P1,PLOG-I.LOG	;USE STICKY LOG SWITCH
	JRST	FILD24		;TELL FILSER THE ANSWER
;HERE WHEN FILE BEING ACCESSED MATCHES FILE SPEC FOUND IN ACCESS.USR
FILD23:	SKIPGE	T1,I.SWCH(P1)	;HIGHEST ACCESS ALLOWED TO THE FILE
	MOVEI	T1,FNCNAA	;IF NONE SPECIFIED, ALLOW NO ACCESS
;HERE TO SEE IF THE ACCESSOR IS ATTEMPTING TO CREATE THE FILE
	HLRZ	T2,M.CODE(M)	;ACCESS BEING ATTEMPTED
	CAIN	T2,FNCCRE	;CREATE?
	SKIPG	I.CRE(P1)	;CREATE ALLOWED?
	JRST	FILD24		;NO, ALLOW ONLY ACCESS SPECIFIED IN ACCESS.USR
	MOVEI	T1,FNCCRE	;YES, ALLOW THE CREATE
;HERE TO SEE IF A PROTECTION CODE WAS SPECIFIED IN ACCESS.USR
; IF SO, TELL FILSER TO CREATE THE FILE WITH THIS PROTECTION CODE
	MOVX	T2,FX.PRO	;PROTECTION MASK
	TDNN	T2,OUTBLK+.FXMOM;A PROTECTION CODE SPECIFIED?
	JRST	FILD24		;NO
	LDB	T2,[POINTR (OUTBLK+.FXMOD,FX.PRO)] ;YES
	DPB	T2,[POINTR (T1,FL.DPT)]
	TXO	T1,FL.DSP	;TELL FILSER THAT USER SPECIFIED CREATE PROTECTION
;HERE TO SEND HIGHEST ACCESS ALLOWED TO THE FILE BY THIS ACCESSOR
; TO FILSER
FILD24:	TXO	T1,FL.DAA	;ASK US ON EVERY REFERENCE TO THE FILE
	MOVEM	T1,IPS.DT+.IPCS1;STORE HIGHEST ACCESS ALLOWED
	HLRZ	T2,M.CODE(M)	;ACCESS BEING ATTEMPTED
	MOVEI	P2,[ASCIZ / failed
/]				;ASSUME ACCESS WILL NOT BE ALLOWED
	CAIE	C,.FLDPG	;A PROGRAM BEING RUN?
	JRST	FILD25		;NO
	HRRZS	T1		;TYPE OF ACCESS BEING ATTEMPTED
	CAIN	T1,FNCEXE	;EXECUTE ONLY FILE?
	CAILE	T1,FNCRED	;AND TRYING TO READ IT?
FILD25:	CAIG	T2,(T1)		;ACCESS REQUESTED LESS THAN ACCESS ALLOWED?
	MOVEI	P2,[ASCIZ / succeeded
/]				;YES, THE ACCESS WILL BE ALLOWED
	MOVE	T1,[1,,[.FOCLS(DSK)]]
	FILOP.	T1,		;CLOSE ACCESS.USR
	  JFCL			;SHOULDN'T HAPPEN
	SKIPLE	T1,I.LOG(P1)	;ACCESS LOGGING REQUESTED?
	CAIN	T1,LOGSNO	;OR LOG:NONE SPECIFIED?
	JRST	FILD33		;NO, SEND THE MESSAGE TO FILSER AND START OVER
	CAIN	T1,LOGSAL	;/LOG:ALL?
	JRST	FILD26		;YES, GO LOG IT
	CAIN	T1,LOGSFA	;LOG FAILURES?
	MOVEI	T2,[ASCIZ / failed
/]				;YES
	CAIN	T1,LOGSSU	;LOG SUCCESSES?
	MOVEI	T2,[ASCIZ / succeeded
/]				;YES

	CAIE	T2,(P2)		;SUCCESS OR FAILURE?
	JRST	FILD33		;NO, NO LOGGING
FILD26:	MOVE	T1,IPS.DT+.IPCS1;WORD RETURNED TO MONITOR
	SKIPLE	I.CLOS(P1)	;YES, A CLOSE SWITCH SEEN?
	TXO	T1,FL.DCL	;YES, CALL THE FILE DAEMON ON CLOSE
	CAIN	C,.FLDPG	;PROGRAM BEING RUN?
	SKIPG	I.EXIT(P1)	;AND WAS AN EXIT SWITCH SEEN?
	CAIA			;NO
	TXO	T1,FL.DXT	;YES, CALL THE FILE DAEMON ON PROGRAM EXIT
	MOVEM	T1,IPS.DT+.IPCS1;STORE CLOSE AND EXIT BITS
;HERE TO LOG ACCESS TO THE FILE
FILD27:	MOVEI	T1,.RBPRV	;4 WORD LOOKUP SO IT WILL BE FASTER IF
	MOVEM	T1,LEB.BL	; IF FILSER KNOWS ABOUT THE FILE
	MOVE	T1,[FO.PRV+.FOAPP(DSK)]
	MOVEM	T1,FOP.BL	;APPEND TO THE FILE ENVOKING PRIVS
	MOVSI	T1,(SIXBIT /LOG/)
	MOVEM	T1,LEB.XT	;EXTENSION
	MOVSI	T1,OBUF		;OUTPUT BUFFER HEADER
	MOVEM	T1,FOP.BH	;STORE THAT
	MOVSI	T1,1		;ONE INPUT BUFFER
	MOVEM	T1,FOP.NB	;STORE THAT
	HRLOI	T1,777		;ZERO ALL OF THE ATTRIBUTES WORD
	ANDCAM	T1,LEB.AW	;EXCEPT THE PROTECTION FIELD
	MOVEI	T1,PTH.BL	;ADDRESS OF THE PATH BLOCK
	MOVEM	T1,LEB.PT	;STORE THAT
	MOVEI	T1,.PTSCN	;DON'T SCAN
	MOVEM	T1,PTH.AW	;STORE THAT
	MOVE	T1,[6,,FOP.BL]	;FILOP ARGUMENT LIST
	FILOP.	T1,		;APPEND OR CREATE ON SAME PATH AS ACCESS.USR
	  JRST	FILD32		;THE ONLY REASON THIS SHOULD HAPPEN IS A RIB ERROR
	MOVEI	T1,PUTCHR	;HAVE SCAN CALL PUTCHR
	MOVEM	T1,TYO		; TO OUTPUT TO THE LOG FILE
	MOVX	T1,%CNDTM	;UNIVERSAL DATE AND TIME
	GETTAB	T1,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	PUSHJ	P,.TDTTM##	;PRINT DATE AND TIME
	MOVEI	T1,[ASCIZ / Job /]
	PUSHJ	P,.TSTRG##	;OUTPUT THE STRING
	MOVE	T1,J		;JOB NUMBER OF ACCESSOR
	PUSHJ	P,.TDECW##	;PRINT THAT
	PUSHJ	P,.TSPAC##	;PRINT A SPACE
	HRLZ	P3,J		;JOB NUMBER OF THE ACCESSOR
	HRRI	P3,.GTNM1	;FIRST PART OF THE USER'S NAME
	GETTAB	P3,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	HRLZ	P4,J		;JOB NUMBER
	HRRI	P4,.GTNM2	;SECOND HALF OF USER'S NAME
	GETTAB	P4,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	MOVE	P1,[POINT 6,P3]	;BYTE POINTER TO NAME STRING
FILD28:	SKIPN	P3		;FIRST HALF OF NAME ZERO OR BEEN ZEROED?
	JUMPE	P4,FILD29	;JUMP IF SECOND HALF HAS BEEN PRINTED
	ILDB	T1,P1		;NEXT CHARACTER OF NAME STRING
	MOVEI	T2,0		;ZERO CHARACTER POSITION
	DPB	T2,P1		; FOR END TEST
	ADDI	T1," "		;MAKE IT ASCII
	PUSHJ	P,.TCHAR##	;PUT IT IN THE OUTPUT
	JRST	FILD28		;NEXT CHARACTER IF THERE IS ONE
FILD29:	PUSHJ	P,.TSPAC##	;PRINT A SPACE
	MOVE	T1,D		;PPN OF THE ACCESSOR
	PUSHJ	P,.TPPNW##	;PRINT THAT
	PUSHJ	P,.TSPAC##	;PRINT A SPACE
	CAIN	C,.FLDPG	;A PROGRAM BEING RUN?
	JRST	FILD30		;YES
	MOVEI	T1,"("		;PRINT A LEFT PAREN
	PUSHJ	P,.TCHAR##	; ..
	HRLZ	T1,J		;JOB NUMBER OF ACCESSOR
	HRRI	T1,.GTRDV	;GET THE DEVICE WHERE
	GETTAB	T1,		; ACCESSING PROGRAM CAME FROM
	  ERROR			;SHOULDN'T HAPPEN
	PUSHJ	P,.TSIXN##	;PRINT THE PROGRAM NAME
	PUSHJ	P,.TCOLN##	;PRINT A COLON
	HRLZ	T1,J		;JOB NUMBER
	HRRI	T1,.GTRFN	;GET THE NAME OF THE ACCESSING PROGRAM
	GETTAB	T1,		; ..
	  ERROR			;SHOULDN'T FAIL
	PUSHJ	P,.TSIXN##	;PRINT THAT
	HRLZ	T1,J		;JOB NUMBER
	HRRI	T1,.GTRDI	;GET THE DIRECTORY THAT
	GETTAB	T1,		; THE ACCESSING PROGRAM CAME FROM
	  ERROR			;SHOULDN'T HAPPEN
	SKIPE	T1		;SKIP IF DIRECTORY UNKNOWN
	PUSHJ	P,.TPPNW##	;OTHERWISE, PRINT DIRECTORY
	MOVEI	T1,")"		;PRINT RIGHT PAREN
	PUSHJ	P,.TCHAR##	; ..
FILD30:	PUSHJ	P,.TCRLF##	;CARRIAGE RETURN, LINE FEED
	PUSHJ	P,.TTABC##	;PRINT A TAB
	HLRZ	T1,M.CODE(M)	;TYPE OF ACCESS BEING ATTEMPTED
	CAIE	C,.FLDDA	;DIRECTORY ACCESS?
	CAIN	C,.FLDCA	;REGULAR FILE ACCESS?
	SKIPA	T1,ACCESS-1(T1)	;ADDRESS OF ACCESS TEXT
	MOVE	T1,ACTION-.FLDCA-1(C)
	PUSHJ	P,.TSTRG##	;PRINT TYPE OF ACCESS
	CAIN	C,.FLDXT	;PROGRAM EXECUTION TERMINATED?
	JRST	FILD31		;YES, NOTHING MORE TO PRINT
	MOVEI	T1,[ASCIZ / of /]
	PUSHJ	P,.TSTRG##	;PRINT THE STRING
	MOVE	T1,M.STR(M)	;STRUCTURE NAME WHERE FILE BEING ACCESSED CAME FROM
	PUSHJ	P,.TSIXN##	;PRINT THAT
	PUSHJ	P,.TCOLN##	;PRINT A COLON
	MOVE	T1,M.FILE(M)	;ACCESSED FILE'S FILE NAME
	HLRZ	P1,M.EXT(M)	;EXTENSION
	CAIN	P1,'UFD'	;A UFD?
	PUSHJ	P,.TPPNW##	;YES, PRINT IN PPN FORMAT
	CAIE	P1,'UFD'	;A UFD
	PUSHJ	P,.TSIXN##	;NO, PRINT FILE NAME
	MOVEI	T1,"."		;PRINT A DOT
	PUSHJ	P,.TCHAR##	; ..
	HLLZ	T1,M.EXT(M)	;ACCESSED FILE'S EXTENSION
	PUSHJ	P,.TSIXN##	;PRINT THAT
	MOVEI	T1,M.PPN(M)	;ADDRESS OF FULL PATH
	TLO	T1,TS.DRP	;SO SCAN PRINTS IN PROPER FORMAT
	PUSHJ	P,.TDIRB##	;PRINT THE FULL PATH TO THE FILE
	CAIE	C,.FLDIC	;INPUT CLOSE?
	CAIN	C,.FLDOC	;OR OUTPUT CLOSE?
FILD31:	SKIPA	T1,[[ASCIZ /
/]]				;CRLF
	MOVE	T1,P2		;SUCCEEDED OR FAILED
	PUSHJ	P,.TSTRG##	;PRINT THAT
	MOVE	T1,IPS.DT+.IPCS1;FLAG BITS RETURNED TO THE MONITOR
	TXNN	T1,FL.DCL!FL.DXT;EXIT, CLOSE, OR WILL LOG EXIT OR CLOSE?
	JRST	FILD32		;NO, ALL DONE
	MOVEI	T1,[ASCIZ /	Current Runtime:/]
	PUSHJ	P,.TSTRG##	;PRINT THE STRING
	MOVE	T1,J		;JOB NUMBER OF ACCESSOR
	RUNTIM	T1,		;GET JOB'S CURRENT RUN TIME
	PUSHJ	P,.TTIME##	;PRINT THAT
	MOVEI	T1,[ASCIZ /, KCT:/]
	PUSHJ	P,.TSTRG##	;PRINT THE STRING
	HRLZ	T1,J		;JOB NUMBER
	HRRI	T1,.GTKCT	;GET CURRENT KCT
	GETTAB	T1,		; ..
	  ERROR			;SHOULDN'T HAPPEN
	PUSHJ	P,.TDECW##	;PRINT THAT
	MOVEI	T1,[ASCIZ /, Disk Reads:/]
	PUSHJ	P,.TSTRG##	;PRINT THE STRING
	HRLZ	T1,J		;JOB NUMBER
	HRRI	T1,.GTRCT	;GET JOB'S CURRENT DISK READS
	GETTAB	T1,		; ..
	  ERROR			;SHOULDN'T HAPPEN
	TXZ	T1,RC.INC	;CLEAR INCREMENTAL READS
	PUSHJ	P,.TDECW##	;PRINT CURRENT DISK READS
	MOVEI	T1,[ASCIZ /, Writes:/]
	PUSHJ	P,.TSTRG##	;PRINT THE STRING
	HRLZ	T1,J		;JOB NUMBER OF ACCESSOR
	HRRI	T1,.GTWCT	;GET THE JOB'S CURRENT DISK WRITES
	GETTAB	T1,		; ..
	  ERROR			;SHOULDN'T HAPPEN
	TXZ	T1,WC.INC	;CLEAR INCREMENTAL WRITES
	PUSHJ	P,.TDECW##	;PRINT CURRENT DISK WRITES
	PUSHJ	P,.TCRLF##	;CARRIAGE RETURN, LINE FEED
FILD32:	MOVE	T1,[1,,[.FOCLS(DSK)]]
	FILOP.	T1,		;CLOSE ACCESS.LOG
	  JFCL			;IGNORE ERROR
FILD33:	MOVE	T1,IPR.BL+.IPCFS;PID OF [SYSTEM]GOPHER
	MOVEM	T1,IPS.BL+.IPCFR;STORE THAT AS THE RECEIVER'S PID
	SETZM	IPS.BL+.IPCFL	;ZERO THE FLAGS
	MOVEM	J,IPS.DT+.IPCS0	;JOB NUMBER OF THE ACCESSOR
	PUSHJ	P,FDSEND	;SEND THE RESPONSE TO [SYSTEM]GOPHER
	JRST	FILDA1		;RETURN TO THE TOP OF THE LOOP
	SUBTTL	SCAN INTERFACE

;HERE TO INITIALIZE THE WORLD
CLRALL:	SETZM	NINFIL		;ZERO NUMBER OF INPUT FILES
	SETOM	PEXIT		;STICKY EXIT SWITCH
	SETOM	PCLOSE		;STICKY CLOSE SWITCH
	SETOM	PSWICH		;INITIALIZE STICKY SWITCH
	SETOM	PLOG		; AND STICKY LOG SWITCH
	SETZM	FPRGM		;INITIALIZE PROGRAM SWITCH
	SETOM	PCREAT		;INITIALIZE STICKY CREATE SWITCH
	SETOM	PXONLY		;INITIALIZE STICKY XONLY SWITCH
	POPJ	P,		;RETURN TO SCAN

;HERE TO INITIALIZE THE PER-FILE SWITCH AREA
CLRFIL:	SETZM	FPRGM		;INITIALIZE PROGRAM SWITCH
	SETOM	FEXIT		;LOCAL EXIT SWITCH
	SETOM	FCLOSE		;LOCAL CLOSE SWITCH
	SETOM	FSWICH		;INITIALIZE THE SWITCH
	SETOM	FLOG		;LOCAL LOG SWITCH
	SETOM	FCREAT		;LOCAL CREATE SWITCH
	SETOM	FXONLY		;LOCAL XONLY SWITCH
	POPJ	P,		;AND RETURN


;HERE TO ALLOCATE AN INPUT FILESPEC AREA
ALIN:	MOVE	T1,.JBFF	;GET ADDRESS OF NEXT AREA
	MOVEI	T2,INLEN(T1)	;GET ADDRESS OF NEXT AREA
	MOVEM	T2,.JBFF	;SAVE IT
	CAMG	T2,.JBREL	;NEED MORE CORE?
	JRST	ALIN1		;NO
	CORE	T2,		;AND GET THE CORE
	  ERROR			;WHOOPS
ALIN1:	MOVEI	T2,INLEN	;LOAD THE LENGTH
	MOVEI	T3,1(T1)	;GET THE ADR+1
	HRLI	T3,-1(T3)	;ADR,,ADR+1
	SETZM	0(T1)		;CLEAR THE FIRST WORD
	BLT	T3,INLEN-1(T4)	;AND BLT THE BLOCK
	MOVSI	T3,FPRGM	;ADDRESS OF THE PROGRAM BLOCK
	HRRI	T3,I.PRGM(T1)	;WHERE IT IS IN THE SCAN BLOCK
	BLT	T3,INLEN-1(T1)	;BLT THE BLOCK
	MOVE	T3,FSWICH	;GET SWITCH
	MOVEM	T3,I.SWCH(T1)	;STORE IT
	MOVE	T3,FLOG		;VALUE OF THE LOG SWITCH
	MOVEM	T3,I.LOG(T1)	;STORE THAT IN THE SCAN BLOCK
	MOVE	T3,FEXIT	;VALUE OF THE EXIT SWITCH
	MOVEM	T3,I.EXIT(T1)	;STORE THAT IN THE SCAN BLOCK
	MOVE	T3,FCLOSE	;VALUE OF THE CLOSE SWITCH
	MOVEM	T3,I.CLOS(T1)	;STORE THAT
	MOVE	T3,FCREAT	;VALUE OF THE CREATE SWITCH
	MOVEM	T3,I.CRE(T1)	;STORE THAT IN THE SCAN BLOCK
	MOVE	T3,FXONLY	;VALUE OF THE XONLY SWITCH
	MOVEM	T3,I.XO(T1)	;STORE THAT
	AOS	NINFIL		;INCREMENT FILE COUNTER
	POPJ	P,		;AND RETURN
;HERE TO ALLOCATE AN OUTPUT FILESPEC BLOCK
ALOUT:	MOVE	T1,[OUTBLK,,OUTBLK+1]
	SETZM	OUTBLK		;ZERO THE OUTPUT SCAN BLOCK
	BLT	T1,OUTBLK+OUTLEN-1
	MOVE	T1,FSWICH	;VALUE OF STICKY SWITCH
	MOVEM	T1,PSWICH	;STORE THAT
	MOVE	T1,FLOG		;VALUE OF STICKY LOG SWITCH
	MOVEM	T1,PLOG		;STORE THAT
	MOVE	T1,FPRGM	;VALUE OF STICKY PROGRAM SWITCH
	MOVEM	T1,PPRGM	;STORE THAT
	MOVE	T1,FEXIT	;VALUE OF STICKY EXIT SWITCH
	MOVEM	T1,PEXIT	;STORE THAT
	MOVE	T1,FCLOSE	;VALUE OF STICKY CLOSE SWITCH
	MOVEM	T1,PCLOSE	;STORE THAT
	MOVE	T1,FCREAT	;VALUE OF STICKY CREATE SWITCH
	MOVEM	T1,PCREAT	;STORE THAT
	MOVE	T1,FXONLY	;VALUE OF STICKY XONLY SWITCH
	MOVEM	T1,PXONLY	;STORE THAT
	MOVEI	T1,OUTBLK	;ADDRESS OF OUTPUT FILE SPEC SCAN BLOCK
	MOVEI	T2,OUTLEN	;LENGTH, RETURNED TO SCAN
	POPJ	P,		;AND RETURN TO SCAN

;HERE TO APPLY STICKY SWITCHES
APLSTY:	MOVE	T1,PSWICH	;LOAD THE GLOBAL SWITCH
	SKIPGE	FSWICH		;WAS A LOCAL SWITCH SPECIFIED?
	MOVEM	T1,FSWICH	;NO, USE THE  GLOBAL SWITCH
	MOVE	T1,PLOG		;GLOBAL LOG SWITCH
	SKIPGE	FLOG		;LOCAL SPECIFIED?
	MOVEM	T1,FLOG		;NO, USE GLOBAL VALUE
	MOVE	T1,PEXIT	;GLOBAL EXIT SWITCH
	SKIPGE	FEXIT		;LOCAL SPECIFIED?
	MOVEM	T1,FEXIT	;NO, USE GLOBAL VALUE
	MOVE	T1,PCLOSE	;GLOBAL CLOSE SWITCH
	SKIPGE	FCLOSE		;LOCAL SPECIFIED?
	MOVEM	T1,FCLOSE	;NO, USE GLOBAL VALUE
	MOVE	T1,PCREAT	;GLOBAL CREATE SWITCH
	SKIPGE	FCREAT		;LOCAL SPECIFIED?
	MOVEM	T1,FCREAT	;NO, USE GLOBAL VALUE
	MOVE	T1,PXONLY	;GLOBAL XONLY SWITCH
	SKIPGE	FXONLY		;LOCAL SPECIFIED?
	MOVEM	T1,FXONLY	;NO, USE GLOBAL VALUE
	POPJ	P,		;AND RETURN
;HERE TO OUTPUT CHARACTERS FROM SCAN (NORMALLY THROW AWAY OUTPUT UNLESS LOGGING)
TYPE:	JRST	@TYO		;CPOPJ OR PUTCHR

;SUBROUTINE TO SEE IF COMPONENTS OF A FILE SPEC MATCH
;CALLING SEQUENCE:
;	MOVE	T1,USER SUPPLIED COMPONENT
;	MOVE	T2,COMPONENT TO MATCH AGAINST
;	MOVE	T3,MASK
;	PUSHJ	P,MATCHS
;RETURNS CPOPJ IF COMPONENTS DON'T MATCH, CPOPJ1 IF THEY DO

MATCHS:	XOR	T2,T1		;XOR (ACCESS.USR) WITH FILE SPEC
	AND	T2,T3		;APPLY WILD CARD MASK
	JUMPE	T2,.POPJ1##	;JUMP IF MATCH
	POPJ	P,		;NO MATCH

;HERE TO OUTPUT DATA TO ACCESS.LOG IGNORING I/O ERRORS

PUTCHR:	SOSGE	OBUF+2		;BUFFER FULL?
	JRST	[OUTPUT DSK,	;YES, OUTPUT IT
		JRST PUTCHR]	;AND STORE CHARACTER IN THE NEW BUFFER
	IDPB	T1,OBUF+1	;STORE THE CHARACTER
	POPJ	P,		;AND RETURN TO SCAN
	SUBTTL	INITIALIZATION

FDINIT:	MOVX	T1,%IPCML	;MAXIMUM LENGTH OF AN IPCF MESSAGE
	GETTAB	T1,		;GET THAT
	  ERROR			;IPCF MUST BE IMPLEMENTED
	MOVE	T2,.JBFF	;FIRST FREE LOCATION IN CORE IMAGE
	HRLM	T1,IPCSDT	;MAX LENGTH IF MESSAGE
	HRRM	T2,IPCSDT	;START OF MESSAGE (WHERE IT WILL BE RECEIVED)
	ADDI	T1,1(T2)	;LAST WORD IN RECEIVE BLOCK
	MOVEM	T1,.JBFF	;STORE THAT AS NEW FIRST FREE LOCATION
	CAMG	T1,.JBREL	;ALREADY HAVE ENOUGH CORE FOR MESSAGE?
	JRST	FDINI1		;YES
	CORE	T1,		;NO, GET ENOUGH CORE
	  ERROR			;WHOOPS
FDINI1:	MOVX	T1,%SIIPC	;PID OF [SYSTEM]IPCC
	GETTAB	T1,		;GET THAT
	  ERROR			;SHOULDN'T HAPPEN
	MOVEM	T1,IPCPID	;SAVE IT
	MOVX	T1,%SIFDA	;OUR PID
	GETTAB	T1,		;GET THAT
	  ERROR			;MUST BE IMPLEMENTED
	MOVEM	T1,OURPID	;SAVE THAT
	JUMPN	T1,.POPJ##	;INITIALIZATION IS COMPLETE IF PID EXISTS
	MOVX	T1,IP.CFP	;PRIVILEGED
	MOVEM	T1,IPS.BL+.IPCFL; SEND
	MOVE	T1,IPCPID	; TO [SYSTEM]IPCC
	MOVEM	T1,IPS.BL+.IPCFR; ..
	MOVX	T1,.IPCSC	;CREATE A PID
	MOVEM	T1,IPS.DT+.IPCS0; ..
	PJOB	T1,		;GET OUR JOB NUMBER
	MOVEM	T1,IPS.DT+.IPCS1;WHO TO CREATE A PID FOR
	PUSHJ	P,FDSEND	;SEND THE REQUEST TO [SYSTEM]IPCC
	PUSHJ	P,FDRECV	;WAIT FOR A RESPONSE
	MOVE	T1,.IPCS2(M)	;PID WHICH WAS CREATED FOR US
	MOVEM	T1,OURPID	;REMEMBER THAT
	MOVX	T1,.IPCSQ	;SET QUOTA
	MOVEM	T1,IPS.DT+.IPCS0; ..
	MOVE	T1,OURPID	;FROM US
	MOVEM	T1,IPS.DT+.IPCS1; ..
	MOVEI	T1,-1		;SET SEND AND RECEIVE QUOTAS TO 777
	MOVEM	T1,IPS.DT+.IPCS2; ..
	PUSHJ	P,FDSEND	;SEND REQUEST TO [SYSTEM]IPCC
	PUSHJ	P,FDRECV	;WAIT FOR A RESPONSE
	MOVX	T1,.IPCWP	;ADD AN ENTRY TO THE SYSTEM PID TABLE
	MOVEM	T1,IPS.DT+.IPCS0; ..
	MOVX	T1,.IPCPF	;WHERE TO ADD IT
	MOVEM	T1,IPS.DT+.IPCS1; ..
	MOVE	T1,OURPID	;PUT OUR PID IN .GTSID
	MOVEM	T1,IPS.DT+.IPCS2; ..
	PUSHJ	P,FDSEND	;ESTABLISH OURSELVES AS [SYSTEM]FILE DAEMON
;	PJRST	FDRECV		;WAIT FOR A RESPONSE
	SUBTTL	IPCF INTERFACE

FDRECV:	SETZM	IPR.BL+.IPCFL	;ZERO FLAGS WORD (BLOCKING RECEIVE)
	MOVE	T1,IPCSDT	;LENGTH,,ADDRESS OF DATA
	MOVEM	T1,IPR.BL+.IPCFP;STORE THAT IN DESCRIPTOR BLOCK
	MOVE	T1,[6,,IPR.BL]	;IPCF RECEIVE ARGUMENT LIST
	IPCFR.	T1,		;RECEIVE A PACKET
	  CAIA			;ERROR
	JRST	FDREC1		;RECEIVE OK
	CAIE	T1,IPCTL%	;IS THE MESSAGE TO LONG?
	ERROR			;NO, WHOOPS
	MOVX	T1,IP.CFT+IP.CFV;TRUNCATE MESSAGE TO ZERO LENGTH
	MOVEM	T1,IPR.BL+.IPCFL;STORE THAT
	IPCFR.	T1,		;PITCH THE PACKET
	  ERROR			;SHOULDN'T HAPPEN
	JRST	FDRECV		;RECEIVE ANOTHER PACKET
FDREC1:	MOVE	T1,IPR.BL+.IPCFL;FLAGS
	TXNE	T1,IP.CFC	;WEED OUT JUNK MAIL (FROM THE SYSTEM)?
	TXNE	T1,IP.CFP	;NO, PRIVILEGED?
	JRST	FDRECV		;YES, PITCH IT
	ANDX	T1,IP.CFM	;ISOLATE TURNED AROUND MESSAGE FIELD
	CAIN	T1,.IPCFN	;A TURNED AROUND MESSAGE?
	JRST	FDRECV		;YES, PITCH IT
	MOVE	T1,IPR.BL+.IPCFL;GET FLAGS AGAIN
	ANDX	T1,IP.CFE	;ISOLATE ERROR FIELD
	JUMPN	T1,FDRECV	;PITCH IT IF NON-ZERO ERROR FIELD
	MOVE	J,IPR.BL+.IPCFC	;FIELD CONTAINING SENDING JOB'S JOB NUMBER
	ANDX	J,IP.SJN	;ISOLATE JOB NUMBER OF SENDER
	HRRZ	M,IPCSDT	;ADDRESS OF THE DATA PORTION OF THE PACKET
	HLL	M,IPR.BL+.IPCFP	;LENGTH OF DATA
	MOVE	D,IPR.BL+.IPCFU	;PPN OF SENDER
	HRRZ	C,M.CODE(M)	;REASON WE WERE CALLED
	POPJ	P,		;RETURN TO CALLER

FDSEND:	MOVE	T1,OURPID	;OUR PID
	MOVEM	T1,IPS.BL+.IPCFS;STORE AS SENDER'S PID
FDSEN1:	MOVE	T1,[4,,IPS.BL]	;IPCF SEND ARGUMENT LIST
	IPCFS.	T1,		;SEND THE MESSAGE
	  CAIA			;ERROR RETURN (ONLY IF NO MONITOR FREE CORE)
	POPJ	P,		;ALL IS WELL, RETURN
	CAXE	T1,IPCRY%	;NO ROOM ERROR?
	ERROR			;NO, WHAT NOW?
	MOVEI	T1,1		;SLEEP ONE SECOND
	SLEEP	T1,		; ..
	JRST	FDSEN1		;AND TRY AGAIN
	SUBTTL	STORAGE

PDL:	BLOCK	PDLL		;PUSH DOWN LIST
NINFIL:	BLOCK	1		;NUMBER OF INPUT FILES
SAVFF:	BLOCK	1		;SAVE INITIAL VALUE OF .JBFF
FFAPPN:	BLOCK	1		;FULL FILE ACCESS PPN
IPCSDT:	BLOCK	1		;LENGTH,,ADDRESS OF IPCF RECEIVE DATA
IPCPID:	BLOCK	1		;PID OF [SYSTEM]IPCC
OURPID:	BLOCK	1		;PID OF THE FILE DAEMON
PATHMM:	BLOCK	1		;FLAG SAYING PATHS MUST MATCH
TYO:	BLOCK	1		;OUTPUT ROUTINE'S ADDRESS (CPOPJ OR PUTCHR)
IBUF:	BLOCK	3		;INPUT BUFFER HEADER
OBUF:	BLOCK	3		;OUTPUT BUFFER HEADER
OUTBLK:	BLOCK	.FXBFR		;SCAN BLOCK FOR OUTPUT FILE SPEC
	OUTLEN==.FXBFR		;LENGTH OF SCAN BLOCK

	PHASE	0
INBLK:	BLOCK	.FXLEN		;PROTOTYPE INPUT FILE SPEC SCAN BLOCK
I.SWCH:	BLOCK	1		;VALUE OF ACCESS SWITCH
I.LOG:	BLOCK	1		;VALUE OF LOG SWITCH
I.EXIT:	BLOCK	1		;VALUE OF EXIT SWITCH
I.CLOS:	BLOCK	1		;VALUE OF CLOSE SWITCH
I.CRE:	BLOCK	1		;VALUE OF CREATE SWITCH
I.XO:	BLOCK	1		;VALUE OF XONLY SWITCH
I.PRGM:	BLOCK	.FXLEN		;VALUE OF PROGRAM SWITCH
	INLEN==.-INBLK		;LENGTH OF SCAN BLOCK
	DEPHASE

FPRGM:	BLOCK	.FXLEN		;SCAN BLOCK FOR FILE SPEC FROM PROGRAM SWITCH

SCNBLK:				;SCAN BLOCK USED FOR READING ACCESS.USR
				; AS AN INDIRECT FILE
SCNDEV:	BLOCK	1		;DEVICE
SCNNAM:	BLOCK	2		;SIXBIT /ACCESS/
SCNEXT:	BLOCK	1		;SIXBIT /USR/
SCNMOD:	BLOCK	2		;MODIFIERS
SCNDIR:	BLOCK	2*.FXLND	;PATH TO ACCESS.USR
SCNBKL==.-SCNBLK		;LENGTH OF SCAN BLOCK
	0			;ALWAYS TERMINATE WITH A ZERO
FOO:	BLOCK	1		;SWITCH TO DEFEAT SCAN'S /RUN SWITCH
FCREAT:	BLOCK	1		;CREATE SWITCH
PCREAT:	BLOCK	1		;STICKY CREATE SWITCH
FSWICH:	BLOCK	1		;FILE SWITCH
PSWICH:	BLOCK	1		;STICKY SWITCH
FLOG:	BLOCK	1		;LOG SWITCH
PLOG:	BLOCK	1		;STICKY LOG SWITCH
PPRGM:	BLOCK	1		;STICKY PROGRAM SWITCH
FEXIT:	BLOCK	1		;EXIT SWITCH
PEXIT:	BLOCK	1		;STICKY EXIT SWITCH
FCLOSE:	BLOCK	1		;CLOSE SWITCH
PCLOSE:	BLOCK	1		;STICKY CLOSE SWITCH
FXONLY:	BLOCK	1		;XONLY SWITCH
PXONLY:	BLOCK	1		;STICKY XONLY SWITCH
IPS.BL:	BLOCK	3		;IPCF SEND BLOCK
	3,,IPS.DT		;LENGTH,,ADDRESS OF DATA
IPS.DT:	BLOCK	3		;IPCF SEND DATA
IPR.BL:	BLOCK	6		;IPCF RECEIVE BLOCK

FOP.BL:	BLOCK	1		;FILOP BLOCK
FOP.MD:	UU.PHS+.IOASC		;PHYSICAL ONLY, ASCII MODE
FOP.DV:	0			;DEVICE
FOP.BH:	0			;BUFFER HEADERS
FOP.NB:	0			;NUMBER OF BUFFERS
FOP.LB:	LEB.BL			;LOOKUP/ENTER BLOCK ADDRESS
FOP.PB:	10,,PTH.BL		;WHERE TO RETURN PATH TO THE FILE
LEB.BL:	.RBAUT			;EXTENDED LOOKUP/ENTER BLOCK
LEB.PT:	LEB.PB			;ADDRESS OF PATH
LEB.FL:	0			;FILE NAME
LEB.XT:	0			;EXTENSION
LEB.AW:	0			;ATTRIBUTES WORD
	BLOCK	.RBAUT-.RBPRV-1	;UNINTERESTING ARGUMENTS RETURNED FROM EXTENDED LOOKUP
LEB.AT:	0			;AUTHOR OF ACCESS.USR
LEB.PB:	0			;PATH
LEB.SS:	.PTSCY			;SCAN SWITCH
LEB.PP:	0			;PPN
LEB.SF:	BLOCK	5		;SFD'S
	0			;ALWAYS TERMINATE WITH A ZERO
PTH.BL:	0			;PATH BLOCK
PTH.AW:	0			;ATTRIBUTES WORD
PTH.PP:	0			;PPN
PTH.SF:	BLOCK	5		;SFD'S
	0			;ALWAYS TERMINATE WITHA ZERO

ACS.WB:	BLOCK	5		;WORKING STORAGE FOR PATH AND DSKCHR UUOS


	END	FILDAE