(FILECREATED "14-AUG-83 18:04:22" {PHYLUM}<LISPCORE>SOURCES>NSFILING.;7 81666  

      changes to:  (VARS NSFILINGCOMS)

      previous date: " 8-AUG-83 14:49:48" {PHYLUM}<LISPCORE>SOURCES>NSFILING.;6)


(* Copyright (c) 1983 by Xerox Corporation)

(PRETTYCOMPRINT NSFILINGCOMS)

(RPAQQ NSFILINGCOMS ([COMS (DECLARE: DONTCOPY EVAL@COMPILE (FILES (LOADCOMP)
								  SPP FILEIO)
				     (ADDVARS (LITATOM.HIT.LIST ACCESS.ERROR ACCESS.PROBLEM 
								ARGUMENT.PROBLEM ATTRIBUTE.SEQUENCE 
								ATTRIBUTE.TYPE ATTRIBUTE.TYPE.ERROR 
								ATTRIBUTE.TYPE.SEQUENCE 
								ATTRIBUTE.VALUE.ERROR 
								CHANGE.ATTRIBUTES CONNECTION.ERROR 
								CONNECTION.PROBLEM CONTROL.SEQUENCE 
								CONTROL.TYPE CONTROL.TYPE.ERROR 
								CONTROL.TYPE.SEQUENCE 
								CONTROL.VALUE.ERROR FILE.ID 
								\FILING.ATTRIBUTE.TYPE.SEQUENCE 
								FILING.SUBSET.FOR.PRINTING 
								GET.ATTRIBUTES HANDLE.ERROR 
								HANDLE.PROBLEM INSERTION.ERROR 
								INSERTION.PROBLEM 
								\READ.FILING.ATTRIBUTE.SEQUENCE 
								SCOPE.SEQUENCE SCOPE.TYPE 
								SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
								SERVICE.ERROR SERVICE.PROBLEM 
								SESSION.ERROR SESSION.PROBLEM 
								SIMPLE.VERIFIER SPACE.ERROR 
								SPACE.PROBLEM TRANSFER.ERROR 
								TRANSFER.PROBLEM UNDEFINED.ERROR 
								\WRITE.FILING.ATTRIBUTE.SEQUENCE 
								CLOSE.NSFILING.CONNECTIONS 
								\DIRECTORY.LIST.TO.PATHNAME 
								\GETFILINGCONNECTION 
								\NSFILING.CLOSEFILE \NSFILING.CONNECT 
								\NSFILING.CREATE.DIRECTORY 
								\NSFILING.DELETEFILE 
								\NSFILING.DIRECTORYNAMEP 
								\NSFILING.EVENTFN \NSFILING.FULLNAME 
								\NSFILING.GENERATEFILES 
								\NSFILING.GETEOFPTR \NSFILING.GETFILE 
								\NSFILING.GETFILEINFO 
								\NSFILING.GETFILENAME 
								\NSFILING.HOSTNAMEP \NSFILING.INIT 
								\NSFILING.INTERNAL.CLOSE 
								\NSFILING.LIST \NSFILING.LOGIN 
								\NSFILING.LOGOUT 
								\NSFILING.LOGOUT.INTERNAL 
								\NSFILING.NEXTFILE \NSFILING.OPENFILE 
								\NSFILING.SETFILEINFO 
								\PATHNAME.TO.DIRECTORY.LIST 
								\VALID.FILING.CONNECTIONP]
	(COMS (* Filing Protocol.)
	      [P (COURIERPROGRAM FILING (10 2)
				 TYPES
				 [(ATTRIBUTE.TYPE LONGCARDINAL)
				  (ATTRIBUTE.TYPE.SEQUENCE (SEQUENCE ATTRIBUTE.TYPE))
				  [ATTRIBUTE (RECORD (TYPE ATTRIBUTE.TYPE)
						     (VALUE (SEQUENCE UNSPECIFIED]
				  (ATTRIBUTE.SEQUENCE (SEQUENCE ATTRIBUTE))
				  (CONTROL.TYPE (ENUMERATION (LOCK 0)
							     (TIMEOUT 1)))
				  (CONTROL.TYPE.SEQUENCE (SEQUENCE CONTROL.TYPE))
				  (CONTROL (CHOICE (LOCK 0 LOCK)
						   (TIMEOUT 1 TIMEOUT)))
				  (CONTROL.SEQUENCE (SEQUENCE CONTROL))
				  (LOCK (ENUMERATION (NONE 0)
						     (SHARE 1)
						     (EXCLUSIVE 2)))
				  (TIMEOUT CARDINAL)
				  (SCOPE.TYPE (ENUMERATION (COUNT 0)
							   (DIRECTION 1)
							   (FILTER 2)))
				  (SCOPE (CHOICE (COUNT 0 COUNT)
						 (DIRECTION 1 DIRECTION)
						 (FILTER 2 FILTER)))
				  (SCOPE.SEQUENCE (SEQUENCE SCOPE))
				  (COUNT CARDINAL)
				  (DIRECTION (ENUMERATION (FORWARD 0)
							  (BACKWARD 1)))
				  (FILTER (CHOICE (LESS 0 (RECORD (ATTRIBUTE ATTRIBUTE)
								  (INTERPRETATION INTERPRETATION)))
						  (LESS.OR.EQUAL 1 (RECORD (ATTRIBUTE ATTRIBUTE)
									   (INTERPRETATION 
										   INTERPRETATION)))
						  (EQUAL 2 (RECORD (ATTRIBUTE ATTRIBUTE)
								   (INTERPRETATION INTERPRETATION)))
						  (NOT.EQUAL 3 (RECORD (ATTRIBUTE ATTRIBUTE)
								       (INTERPRETATION INTERPRETATION)
								       ))
						  (GREATER.OR.EQUAL 4 (RECORD (ATTRIBUTE ATTRIBUTE)
									      (INTERPRETATION 
										   INTERPRETATION)))
						  (GREATER 5 (RECORD (ATTRIBUTE ATTRIBUTE)
								     (INTERPRETATION INTERPRETATION)))
						  (AND 6 (SEQUENCE FILTER))
						  (OR 7 (SEQUENCE FILTER))
						  (NOT 8 FILTER)
						  (NONE 9 NIL)
						  (ALL 10 NIL)
						  (MATCHES 11 ATTRIBUTE)))
				  (INTERPRETATION (ENUMERATION (NONE 0)
							       (BOOLEAN 1)
							       (CARDINAL 2)
							       (LONG.CARDINAL 3)
							       (TIME 4)
							       (INTEGER 5)
							       (LONG.INTEGER 6)
							       (STRING 7)))
				  (CREDENTIALS (AUTHENTICATION . CREDENTIALS))
				  (HANDLE (ARRAY 2 UNSPECIFIED))
				  (SESSION (RECORD (TOKEN (ARRAY 2 UNSPECIFIED))
						   (VERIFIER VERIFIER)))
				  (VERIFIER (AUTHENTICATION . VERIFIER))
				  (SIMPLE.VERIFIER (AUTHENTICATION . SIMPLE.VERIFIER))
				  (FILE.ID (ARRAY 5 UNSPECIFIED))
				  (USER (CLEARINGHOUSE . NAME))
				  (ORDERING (RECORD (KEY ATTRIBUTE.TYPE)
						    (ASCENDING BOOLEAN)
						    (INTERPRETATION INTERPRETATION)))
				  (ACCESS.LIST (RECORD (ENTRIES (SEQUENCE ACCESS.ENTRY))
						       (DEFAULTED BOOLEAN)))
				  (ACCESS.ENTRY (RECORD (KEY (CLEARINGHOUSE . NAME))
							(TYPE (ENUMERATION (INDIVIDUAL 0)
									   (ALIAS 1)
									   (GROUP 2)
									   (OTHER 3)))
							(ACCESS UNSPECIFIED)))
				  (ARGUMENT.PROBLEM (ENUMERATION (ILLEGAL 0)
								 (DISALLOWED 1)
								 (UNREASONABLE 2)
								 (UNIMPLEMENTED 3)
								 (DUPLICATED 4)
								 (MISSING 5)))
				  (ACCESS.PROBLEM (ENUMERATION (ACCESS.RIGHTS.INSUFFICIENT 0)
							       (ACCESS.RIGHTS.INDETERMINATE 1)
							       (FILE.CHANGED 2)
							       (FILE.DAMAGED 3)
							       (FILE.IN.USE 4)
							       (FILE.NOT.FOUND 5)
							       (FILE.OPEN 6)))
				  (CONNECTION.PROBLEM (ENUMERATION (NO.ROUTE 0)
								   (NO.RESPONSE 1)
								   (TRANSMISSION.HARDWARE 2)
								   (TRANSPORT.TIMEOUT 3)
								   (TOO.MANY.LOCAL.CONNECTIONS 4)
								   (TOO.MANY.REMOTE.CONNECTIONS
								     5)
								   (MISSING.COURIER 6)
								   (MISSING.PROGRAM 7)
								   (MISSING.PROCEDURE 8)
								   (PROTOCOL.MISMATCH 9)
								   (PARAMETER.INCONSISTENCY 10)
								   (INVALID.MESSAGE 11)
								   (RETURN.TIMED.OUT 12)
								   (OTHER.CALL.PROBLEM -1)))
				  (HANDLE.PROBLEM (ENUMERATION (INVALID 0)
							       (NULL.DISALLOWED 1)
							       (DIRECTORY.REQUIRED 2)))
				  (INSERTION.PROBLEM (ENUMERATION (POSITION.UNAVAILABLE 0)
								  (FILE.NOT.UNIQUE 1)
								  (LOOP.IN.HIERARCHY 2)))
				  (SERVICE.PROBLEM (ENUMERATION (CANNOT.AUTHENTICATE 0)
								(SERVICE.FULL 1)
								(SERVICE.UNAVAILABLE 2)
								(SESSION.IN.USE 3)))
				  (SESSION.PROBLEM (ENUMERATION (TOKEN.INVALID 0)))
				  (SPACE.PROBLEM (ENUMERATION (ALLOCATION.EXCEEDED 0)
							      (ATTRIBUTE.AREA.FULL 1)
							      (MEDIUM.FULL 2)))
				  (TRANSFER.PROBLEM (ENUMERATION (ABORTED 0)
								 (CHECKSUM.INCORRECT 1)
								 (FORMAT.INCORRECT 2)
								 (NO.RENDEZVOUS 3)
								 (WRONG.DIRECTION 4]
				 PROCEDURES
				 ((LOGON ARGS (CREDENTIALS VERIFIER)
					 RESULTS
					 (SESSION)
					 ERRORS
					 (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR 
							       UNDEFINED.ERROR)
					 0)
				  (LOGOFF ARGS (SESSION)
					  ERRORS
					  (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR 
								UNDEFINED.ERROR)
					  1)
				  (CONTINUE ARGS (SESSION)
					    RESULTS
					    (CARDINAL)
					    ERRORS
					    (AUTHENTICATION.ERROR SESSION.ERROR UNDEFINED.ERROR)
					    19)
				  (OPEN ARGS (ATTRIBUTE.SEQUENCE HANDLE CONTROL.SEQUENCE SESSION)
					RESULTS
					(HANDLE)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR CONTROL.TYPE.ERROR 
						      CONTROL.VALUE.ERROR HANDLE.ERROR SESSION.ERROR 
						      UNDEFINED.ERROR)
					2)
				  (CLOSE ARGS (HANDLE SESSION)
					 ERRORS
					 (AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR 
							       UNDEFINED.ERROR)
					 3)
				  (CREATE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE SESSION)
					  RESULTS
					  (HANDLE)
					  ERRORS
					  (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
							AUTHENTICATION.ERROR CONTROL.TYPE.ERROR 
							CONTROL.VALUE.ERROR HANDLE.ERROR 
							INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
							UNDEFINED.ERROR)
					  4)
				  (DELETE ARGS (HANDLE SESSION)
					  ERRORS
					  (ACCESS.ERROR AUTHENTICATION.ERROR HANDLE.ERROR 
							SESSION.ERROR UNDEFINED.ERROR)
					  5)
				  (GET.ATTRIBUTES ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SESSION)
						  RESULTS
						  (ATTRIBUTE.SEQUENCE)
						  ERRORS
						  (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR 
								AUTHENTICATION.ERROR HANDLE.ERROR 
								SESSION.ERROR UNDEFINED.ERROR)
						  8)
				  (CHANGE.ATTRIBUTES ARGS (HANDLE ATTRIBUTE.SEQUENCE SESSION)
						     ERRORS
						     (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR 
								   ATTRIBUTE.VALUE.ERROR 
								   AUTHENTICATION.ERROR HANDLE.ERROR 
								   INSERTION.ERROR SESSION.ERROR 
								   SPACE.ERROR UNDEFINED.ERROR)
						     9)
				  (COPY ARGS (HANDLE HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE 
						     SESSION)
					RESULTS
					(HANDLE)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR CONTROL.TYPE.ERROR 
						      CONTROL.VALUE.ERROR HANDLE.ERROR 
						      INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
						      UNDEFINED.ERROR)
					10)
				  (MOVE ARGS (HANDLE HANDLE ATTRIBUTE.SEQUENCE SESSION)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR HANDLE.ERROR 
						      INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
						      UNDEFINED.ERROR)
					11)
				  (STORE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE 
						      BULK.DATA.SOURCE SESSION)
					 RESULTS
					 (HANDLE)
					 ERRORS
					 (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						       AUTHENTICATION.ERROR CONNECTION.ERROR 
						       CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
						       HANDLE.ERROR INSERTION.ERROR SESSION.ERROR 
						       SPACE.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
					 12)
				  (RETRIEVE ARGS (HANDLE BULK.DATA.SINK SESSION)
					    ERRORS
					    (ACCESS.ERROR AUTHENTICATION.ERROR CONNECTION.ERROR 
							  HANDLE.ERROR SESSION.ERROR TRANSFER.ERROR 
							  UNDEFINED.ERROR)
					    13)
				  (REPLACE ARGS (HANDLE ATTRIBUTE.SEQUENCE BULK.DATA.SOURCE SESSION)
					   ERRORS
					   (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
							 AUTHENTICATION.ERROR CONNECTION.ERROR 
							 HANDLE.ERROR SESSION.ERROR SPACE.ERROR 
							 TRANSFER.ERROR UNDEFINED.ERROR)
					   14)
				  (FIND ARGS (HANDLE SCOPE.SEQUENCE CONTROL.SEQUENCE SESSION)
					RESULTS
					(HANDLE)
					ERRORS
					(ACCESS.ERROR AUTHENTICATION.ERROR CONTROL.TYPE.ERROR 
						      CONTROL.VALUE.ERROR HANDLE.ERROR 
						      SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
						      SESSION.ERROR UNDEFINED.ERROR)
					17)
				  (LIST ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SCOPE.SEQUENCE 
						     BULK.DATA.SINK SESSION)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR CONNECTION.ERROR 
						      HANDLE.ERROR SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
						      SESSION.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
					18))
				 ERRORS
				 ((ATTRIBUTE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
							0)
				  (ATTRIBUTE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
							 1)
				  (CONTROL.TYPE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
						      2)
				  (CONTROL.VALUE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
						       3)
				  (SCOPE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
						    4)
				  (SCOPE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
						     5)
				  (ACCESS.ERROR ARGS (ACCESS.PROBLEM)
						6)
				  (AUTHENTICATION.ERROR ARGS ((AUTHENTICATION . PROBLEM))
							7)
				  (CONNECTION.ERROR ARGS (CONNECTION.PROBLEM)
						    8)
				  (HANDLE.ERROR ARGS (HANDLE.PROBLEM)
						9)
				  (INSERTION.ERROR ARGS (INSERTION.PROBLEM)
						   10)
				  (SERVICE.ERROR ARGS (SERVICE.PROBLEM)
						 11)
				  (SESSION.ERROR ARGS (SESSION.PROBLEM)
						 12)
				  (SPACE.ERROR ARGS (SPACE.PROBLEM)
					       13)
				  (TRANSFER.ERROR ARGS (TRANSFER.PROBLEM)
						  14)
				  (UNDEFINED.ERROR ARGS (CARDINAL)
						   15]
	      (* Lisp support.)
	      (DECLARE: DONTCOPY [CONSTANTS (\FILING.ALL.ATTRIBUTE.TYPES (QUOTE (-1)))
					    (\FILING.DEFAULT.TIMEOUT -1)
					    (\FILING.UNLIMITED.COUNT -1)
					    (\FILING.NULL.FILTER (QUOTE (ALL)))
					    (\FILING.NULL.HANDLE (QUOTE (0 0)))
					    (\FILING.NULL.FILE.ID (QUOTE (0 0 0 0 0)))
					    (\FILING.LOWEST.VERSION 0)
					    (\FILING.HIGHEST.VERSION -1)
					    [\FILING.ATTRIBUTES (QUOTE ((CHECKSUM 0 CARDINAL)
									(CHILDREN.UNIQUELY.NAMED
									  1 BOOLEAN)
									(CREATED.BY 2 USER)
									(CREATED.ON 3 TIME)
									(FILE.ID 4 FILE.ID)
									(IS.DIRECTORY 5 BOOLEAN)
									(IS.TEMPORARY 6 BOOLEAN)
									(MODIFIED.BY 7 USER)
									(MODIFIED.ON 8 TIME)
									(NAME 9 STRING)
									(NUMBER.OF.CHILDREN 10 
											 CARDINAL)
									(ORDERING 11 ORDERING)
									(PARENT.ID 12 FILE.ID)
									(POSITION 13 (SEQUENCE 
										      UNSPECIFIED))
									(READ.BY 14 USER)
									(READ.ON 15 TIME)
									(SIZE.IN.BYTES 16 
										     LONGCARDINAL)
									(FILE.TYPE 17 LONGCARDINAL)
									(VERSION 18 CARDINAL)
									(ACCESS.LIST 19 ACCESS.LIST)
									(DEFAULT.ACCESS.LIST 20 
										      ACCESS.LIST)
									(PATHNAME 21 STRING]
					    (LISP.TO.NS.FILE.ATTRIBUTES (QUOTE ((IWRITEDATE 
										      MODIFIED.ON)
										(IREADDATE READ.ON)
										(ICREATIONDATE 
										       CREATED.ON)
										(LENGTH SIZE.IN.BYTES]
			(RECORDS NSFILINGSTREAM FILING.CONNECTION \NSFILING.GENFILESTATE)
			(GLOBALVARS \NSFILING.CONNECTIONS \NSFILING.DEVICE))
	      (INITRECORDS NSFILINGSTREAM FILING.CONNECTION)
	      (INITVARS (\NSFILING.LOCK (CREATE.MONITORLOCK (QUOTE NSFILING)))
			(\NSFILING.CONNECTIONS NIL))
	      (FNS \NSFILING.LOGIN \NSFILING.LOGOUT \NSFILING.LOGOUT.INTERNAL \NSFILING.CONNECT 
		   \PATHNAME.TO.DIRECTORY.LIST \PATHNAME.TO.DIRECTORY.LIST.INTERNAL 
		   \DIRECTORY.LIST.TO.PATHNAME \NSFILING.CREATE.DIRECTORY \NSFILING.LIST 
		   \NSFILING.LISTVERSIONS \FILING.ATTRIBUTE.TYPE.SEQUENCE \FILING.ATTRIBUTE.TYPE 
		   \READ.FILING.ATTRIBUTE.SEQUENCE \READ.FILING.ATTRIBUTE 
		   \WRITE.FILING.ATTRIBUTE.SEQUENCE \WRITE.FILING.ATTRIBUTE NSDIRECTORY 
		   NSCREATEDIRECTORY \NSFILING.INIT \GETFILINGCONNECTION \VALID.FILING.CONNECTIONP 
		   \LOGGED.ONTO.NSFILESERVERP CLOSE.NSFILING.CONNECTIONS \NSFILING.OPENFILE 
		   \NSFILING.GETFILE \NSFILING.ORIGINAL.GETFILE \NSFILING.CLOSEFILE 
		   \NSFILING.INTERNAL.CLOSE \NSFILING.FULLNAME \NSFILING.EVENTFN \NSFILING.DELETEFILE 
		   \NSFILING.HOSTNAMEP \NSFILING.DIRECTORYNAMEP \NSFILING.GETFILENAME 
		   \NSFILING.GETFILEINFO \NSFILING.SETFILEINFO \NSFILING.GENERATEFILES 
		   \NSFILING.NEXTFILE \NSFILING.GETEOFPTR)
	      (P (\NSFILING.INIT)))
	(COMS (* Printer subset of Filing Protocol.)
	      [P (COURIERPROGRAM FILING.SUBSET.FOR.PRINTING (16 2)
				 TYPES
				 ((ATTRIBUTE.SEQUENCE (FILING . ATTRIBUTE.SEQUENCE))
				  (ATTRIBUTE.TYPE.SEQUENCE (FILING . ATTRIBUTE.TYPE.SEQUENCE))
				  (CONTROL.SEQUENCE (FILING . CONTROL.SEQUENCE))
				  (CREDENTIALS (AUTHENTICATION . CREDENTIALS))
				  (HANDLE (FILING . HANDLE))
				  (SIMPLE.VERIFIER (AUTHENTICATION . SIMPLE.VERIFIER))
				  (SCOPE.SEQUENCE (FILING . SCOPE.SEQUENCE))
				  (SESSION (FILING . SESSION))
				  (VERIFIER (AUTHENTICATION . VERIFIER))
				  (ARGUMENT.PROBLEM (FILING . ARGUMENT.PROBLEM))
				  (ACCESS.PROBLEM (FILING . ACCESS.PROBLEM))
				  (HANDLE.PROBLEM (FILING . HANDLE.PROBLEM))
				  (INSERTION.PROBLEM (FILING . INSERTION.PROBLEM))
				  (SERVICE.PROBLEM (FILING . SERVICE.PROBLEM))
				  (SESSION.PROBLEM (FILING . SESSION.PROBLEM))
				  (SPACE.PROBLEM (FILING . SPACE.PROBLEM)))
				 PROCEDURES
				 ((LOGON ARGS (CREDENTIALS VERIFIER)
					 RESULTS
					 (SESSION)
					 ERRORS
					 (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR 
							       UNDEFINED.ERROR)
					 (FILING . LOGON))
				  (LOGOFF ARGS (SESSION)
					  ERRORS
					  (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR 
								UNDEFINED.ERROR)
					  (FILING . LOGOFF))
				  (CONTINUE ARGS (SESSION)
					    RESULTS
					    (CARDINAL)
					    ERRORS
					    (AUTHENTICATION.ERROR SESSION.ERROR UNDEFINED.ERROR)
					    (FILING . CONTINUE))
				  (OPEN ARGS (ATTRIBUTE.SEQUENCE HANDLE CONTROL.SEQUENCE SESSION)
					RESULTS
					(HANDLE)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR CONTROL.TYPE.ERROR 
						      CONTROL.VALUE.ERROR HANDLE.ERROR SESSION.ERROR 
						      UNDEFINED.ERROR)
					(FILING . OPEN))
				  (CLOSE ARGS (HANDLE SESSION)
					 ERRORS
					 (AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR 
							       UNDEFINED.ERROR)
					 (FILING . CLOSE))
				  (DELETE ARGS (HANDLE SESSION)
					  ERRORS
					  (ACCESS.ERROR AUTHENTICATION.ERROR HANDLE.ERROR 
							SESSION.ERROR UNDEFINED.ERROR)
					  (FILING . DELETE))
				  (STORE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE 
						      BULK.DATA.SOURCE SESSION)
					 RESULTS
					 (HANDLE)
					 ERRORS
					 (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						       AUTHENTICATION.ERROR CONNECTION.ERROR 
						       CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
						       HANDLE.ERROR INSERTION.ERROR SESSION.ERROR 
						       SPACE.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
					 (FILING . STORE))
				  (LIST ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SCOPE.SEQUENCE 
						     BULK.DATA.SINK SESSION)
					ERRORS
					(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						      AUTHENTICATION.ERROR CONNECTION.ERROR 
						      HANDLE.ERROR SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
						      SESSION.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
					(FILING . LIST)))
				 ERRORS
				 ((ATTRIBUTE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
							(FILING . ATTRIBUTE.TYPE.ERROR))
				  (ATTRIBUTE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
							 (FILING . ATTRIBUTE.VALUE.ERROR))
				  (CONTROL.TYPE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
						      (FILING . CONTROL.TYPE.ERROR))
				  (CONTROL.VALUE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
						       (FILING . CONTROL.VALUE.ERROR))
				  (SCOPE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
						    (FILING . SCOPE.TYPE.ERROR))
				  (SCOPE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
						     (FILING . SCOPE.VALUE.ERROR))
				  (ACCESS.ERROR ARGS (ACCESS.PROBLEM)
						(FILING . ACCESS.ERROR))
				  (AUTHENTICATION.ERROR ARGS ((AUTHENTICATION . PROBLEM))
							(FILING . AUTHENTICATION.ERROR))
				  (CONNECTION.ERROR ARGS (CONNECTION.PROBLEM)
						    (FILING . CONNECTION.ERROR))
				  (HANDLE.ERROR ARGS (HANDLE.PROBLEM)
						(FILING . HANDLE.ERROR))
				  (INSERTION.ERROR ARGS (INSERTION.PROBLEM)
						   (FILING . INSERTION.ERROR))
				  (SERVICE.ERROR ARGS (SERVICE.PROBLEM)
						 (FILING . SERVICE.ERROR))
				  (SESSION.ERROR ARGS (SESSION.PROBLEM)
						 (FILING . SESSION.ERROR))
				  (SPACE.ERROR ARGS (SPACE.PROBLEM)
					       (FILING . SPACE.ERROR))
				  (TRANSFER.ERROR ARGS (TRANSFER.PROBLEM)
						  (FILING . TRANSFER.ERROR))
				  (UNDEFINED.ERROR ARGS (CARDINAL)
						   (FILING . UNDEFINED.ERROR]
	      (* Lisp support.)
	      (FNS LIST.NSPRINTER.FILES))))
(DECLARE: DONTCOPY EVAL@COMPILE 
(FILESLOAD (LOADCOMP)
	   SPP FILEIO)


(ADDTOVAR LITATOM.HIT.LIST ACCESS.ERROR ACCESS.PROBLEM ARGUMENT.PROBLEM ATTRIBUTE.SEQUENCE 
					ATTRIBUTE.TYPE ATTRIBUTE.TYPE.ERROR ATTRIBUTE.TYPE.SEQUENCE 
					ATTRIBUTE.VALUE.ERROR CHANGE.ATTRIBUTES CONNECTION.ERROR 
					CONNECTION.PROBLEM CONTROL.SEQUENCE CONTROL.TYPE 
					CONTROL.TYPE.ERROR CONTROL.TYPE.SEQUENCE CONTROL.VALUE.ERROR 
					FILE.ID \FILING.ATTRIBUTE.TYPE.SEQUENCE 
					FILING.SUBSET.FOR.PRINTING GET.ATTRIBUTES HANDLE.ERROR 
					HANDLE.PROBLEM INSERTION.ERROR INSERTION.PROBLEM 
					\READ.FILING.ATTRIBUTE.SEQUENCE SCOPE.SEQUENCE SCOPE.TYPE 
					SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR SERVICE.ERROR 
					SERVICE.PROBLEM SESSION.ERROR SESSION.PROBLEM SIMPLE.VERIFIER 
					SPACE.ERROR SPACE.PROBLEM TRANSFER.ERROR TRANSFER.PROBLEM 
					UNDEFINED.ERROR \WRITE.FILING.ATTRIBUTE.SEQUENCE 
					CLOSE.NSFILING.CONNECTIONS \DIRECTORY.LIST.TO.PATHNAME 
					\GETFILINGCONNECTION \NSFILING.CLOSEFILE \NSFILING.CONNECT 
					\NSFILING.CREATE.DIRECTORY \NSFILING.DELETEFILE 
					\NSFILING.DIRECTORYNAMEP \NSFILING.EVENTFN \NSFILING.FULLNAME 
					\NSFILING.GENERATEFILES \NSFILING.GETEOFPTR \NSFILING.GETFILE 
					\NSFILING.GETFILEINFO \NSFILING.GETFILENAME 
					\NSFILING.HOSTNAMEP \NSFILING.INIT \NSFILING.INTERNAL.CLOSE 
					\NSFILING.LIST \NSFILING.LOGIN \NSFILING.LOGOUT 
					\NSFILING.LOGOUT.INTERNAL \NSFILING.NEXTFILE 
					\NSFILING.OPENFILE \NSFILING.SETFILEINFO 
					\PATHNAME.TO.DIRECTORY.LIST \VALID.FILING.CONNECTIONP)
)



(* Filing Protocol.)

(COURIERPROGRAM FILING (10 2)
		TYPES
		[(ATTRIBUTE.TYPE LONGCARDINAL)
		 (ATTRIBUTE.TYPE.SEQUENCE (SEQUENCE ATTRIBUTE.TYPE))
		 [ATTRIBUTE (RECORD (TYPE ATTRIBUTE.TYPE)
				    (VALUE (SEQUENCE UNSPECIFIED]
		 (ATTRIBUTE.SEQUENCE (SEQUENCE ATTRIBUTE))
		 (CONTROL.TYPE (ENUMERATION (LOCK 0)
					    (TIMEOUT 1)))
		 (CONTROL.TYPE.SEQUENCE (SEQUENCE CONTROL.TYPE))
		 (CONTROL (CHOICE (LOCK 0 LOCK)
				  (TIMEOUT 1 TIMEOUT)))
		 (CONTROL.SEQUENCE (SEQUENCE CONTROL))
		 (LOCK (ENUMERATION (NONE 0)
				    (SHARE 1)
				    (EXCLUSIVE 2)))
		 (TIMEOUT CARDINAL)
		 (SCOPE.TYPE (ENUMERATION (COUNT 0)
					  (DIRECTION 1)
					  (FILTER 2)))
		 (SCOPE (CHOICE (COUNT 0 COUNT)
				(DIRECTION 1 DIRECTION)
				(FILTER 2 FILTER)))
		 (SCOPE.SEQUENCE (SEQUENCE SCOPE))
		 (COUNT CARDINAL)
		 (DIRECTION (ENUMERATION (FORWARD 0)
					 (BACKWARD 1)))
		 (FILTER (CHOICE (LESS 0 (RECORD (ATTRIBUTE ATTRIBUTE)
						 (INTERPRETATION INTERPRETATION)))
				 (LESS.OR.EQUAL 1 (RECORD (ATTRIBUTE ATTRIBUTE)
							  (INTERPRETATION INTERPRETATION)))
				 (EQUAL 2 (RECORD (ATTRIBUTE ATTRIBUTE)
						  (INTERPRETATION INTERPRETATION)))
				 (NOT.EQUAL 3 (RECORD (ATTRIBUTE ATTRIBUTE)
						      (INTERPRETATION INTERPRETATION)))
				 (GREATER.OR.EQUAL 4 (RECORD (ATTRIBUTE ATTRIBUTE)
							     (INTERPRETATION INTERPRETATION)))
				 (GREATER 5 (RECORD (ATTRIBUTE ATTRIBUTE)
						    (INTERPRETATION INTERPRETATION)))
				 (AND 6 (SEQUENCE FILTER))
				 (OR 7 (SEQUENCE FILTER))
				 (NOT 8 FILTER)
				 (NONE 9 NIL)
				 (ALL 10 NIL)
				 (MATCHES 11 ATTRIBUTE)))
		 (INTERPRETATION (ENUMERATION (NONE 0)
					      (BOOLEAN 1)
					      (CARDINAL 2)
					      (LONG.CARDINAL 3)
					      (TIME 4)
					      (INTEGER 5)
					      (LONG.INTEGER 6)
					      (STRING 7)))
		 (CREDENTIALS (AUTHENTICATION . CREDENTIALS))
		 (HANDLE (ARRAY 2 UNSPECIFIED))
		 (SESSION (RECORD (TOKEN (ARRAY 2 UNSPECIFIED))
				  (VERIFIER VERIFIER)))
		 (VERIFIER (AUTHENTICATION . VERIFIER))
		 (SIMPLE.VERIFIER (AUTHENTICATION . SIMPLE.VERIFIER))
		 (FILE.ID (ARRAY 5 UNSPECIFIED))
		 (USER (CLEARINGHOUSE . NAME))
		 (ORDERING (RECORD (KEY ATTRIBUTE.TYPE)
				   (ASCENDING BOOLEAN)
				   (INTERPRETATION INTERPRETATION)))
		 (ACCESS.LIST (RECORD (ENTRIES (SEQUENCE ACCESS.ENTRY))
				      (DEFAULTED BOOLEAN)))
		 (ACCESS.ENTRY (RECORD (KEY (CLEARINGHOUSE . NAME))
				       (TYPE (ENUMERATION (INDIVIDUAL 0)
							  (ALIAS 1)
							  (GROUP 2)
							  (OTHER 3)))
				       (ACCESS UNSPECIFIED)))
		 (ARGUMENT.PROBLEM (ENUMERATION (ILLEGAL 0)
						(DISALLOWED 1)
						(UNREASONABLE 2)
						(UNIMPLEMENTED 3)
						(DUPLICATED 4)
						(MISSING 5)))
		 (ACCESS.PROBLEM (ENUMERATION (ACCESS.RIGHTS.INSUFFICIENT 0)
					      (ACCESS.RIGHTS.INDETERMINATE 1)
					      (FILE.CHANGED 2)
					      (FILE.DAMAGED 3)
					      (FILE.IN.USE 4)
					      (FILE.NOT.FOUND 5)
					      (FILE.OPEN 6)))
		 (CONNECTION.PROBLEM (ENUMERATION (NO.ROUTE 0)
						  (NO.RESPONSE 1)
						  (TRANSMISSION.HARDWARE 2)
						  (TRANSPORT.TIMEOUT 3)
						  (TOO.MANY.LOCAL.CONNECTIONS 4)
						  (TOO.MANY.REMOTE.CONNECTIONS 5)
						  (MISSING.COURIER 6)
						  (MISSING.PROGRAM 7)
						  (MISSING.PROCEDURE 8)
						  (PROTOCOL.MISMATCH 9)
						  (PARAMETER.INCONSISTENCY 10)
						  (INVALID.MESSAGE 11)
						  (RETURN.TIMED.OUT 12)
						  (OTHER.CALL.PROBLEM -1)))
		 (HANDLE.PROBLEM (ENUMERATION (INVALID 0)
					      (NULL.DISALLOWED 1)
					      (DIRECTORY.REQUIRED 2)))
		 (INSERTION.PROBLEM (ENUMERATION (POSITION.UNAVAILABLE 0)
						 (FILE.NOT.UNIQUE 1)
						 (LOOP.IN.HIERARCHY 2)))
		 (SERVICE.PROBLEM (ENUMERATION (CANNOT.AUTHENTICATE 0)
					       (SERVICE.FULL 1)
					       (SERVICE.UNAVAILABLE 2)
					       (SESSION.IN.USE 3)))
		 (SESSION.PROBLEM (ENUMERATION (TOKEN.INVALID 0)))
		 (SPACE.PROBLEM (ENUMERATION (ALLOCATION.EXCEEDED 0)
					     (ATTRIBUTE.AREA.FULL 1)
					     (MEDIUM.FULL 2)))
		 (TRANSFER.PROBLEM (ENUMERATION (ABORTED 0)
						(CHECKSUM.INCORRECT 1)
						(FORMAT.INCORRECT 2)
						(NO.RENDEZVOUS 3)
						(WRONG.DIRECTION 4]
		PROCEDURES
		((LOGON ARGS (CREDENTIALS VERIFIER)
			RESULTS
			(SESSION)
			ERRORS
			(AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			0)
		 (LOGOFF ARGS (SESSION)
			 ERRORS
			 (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			 1)
		 (CONTINUE ARGS (SESSION)
			   RESULTS
			   (CARDINAL)
			   ERRORS
			   (AUTHENTICATION.ERROR SESSION.ERROR UNDEFINED.ERROR)
			   19)
		 (OPEN ARGS (ATTRIBUTE.SEQUENCE HANDLE CONTROL.SEQUENCE SESSION)
		       RESULTS
		       (HANDLE)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR HANDLE.ERROR 
				     SESSION.ERROR UNDEFINED.ERROR)
		       2)
		 (CLOSE ARGS (HANDLE SESSION)
			ERRORS
			(AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			3)
		 (CREATE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE SESSION)
			 RESULTS
			 (HANDLE)
			 ERRORS
			 (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
				       AUTHENTICATION.ERROR CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
				       HANDLE.ERROR INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
				       UNDEFINED.ERROR)
			 4)
		 (DELETE ARGS (HANDLE SESSION)
			 ERRORS
			 (ACCESS.ERROR AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR 
				       UNDEFINED.ERROR)
			 5)
		 (GET.ATTRIBUTES ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SESSION)
				 RESULTS
				 (ATTRIBUTE.SEQUENCE)
				 ERRORS
				 (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR AUTHENTICATION.ERROR HANDLE.ERROR 
					       SESSION.ERROR UNDEFINED.ERROR)
				 8)
		 (CHANGE.ATTRIBUTES ARGS (HANDLE ATTRIBUTE.SEQUENCE SESSION)
				    ERRORS
				    (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
						  AUTHENTICATION.ERROR HANDLE.ERROR INSERTION.ERROR 
						  SESSION.ERROR SPACE.ERROR UNDEFINED.ERROR)
				    9)
		 (COPY ARGS (HANDLE HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE SESSION)
		       RESULTS
		       (HANDLE)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR HANDLE.ERROR 
				     INSERTION.ERROR SESSION.ERROR SPACE.ERROR UNDEFINED.ERROR)
		       10)
		 (MOVE ARGS (HANDLE HANDLE ATTRIBUTE.SEQUENCE SESSION)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     HANDLE.ERROR INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
				     UNDEFINED.ERROR)
		       11)
		 (STORE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE BULK.DATA.SOURCE SESSION)
			RESULTS
			(HANDLE)
			ERRORS
			(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				      CONNECTION.ERROR CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
				      HANDLE.ERROR INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
				      TRANSFER.ERROR UNDEFINED.ERROR)
			12)
		 (RETRIEVE ARGS (HANDLE BULK.DATA.SINK SESSION)
			   ERRORS
			   (ACCESS.ERROR AUTHENTICATION.ERROR CONNECTION.ERROR HANDLE.ERROR 
					 SESSION.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
			   13)
		 (REPLACE ARGS (HANDLE ATTRIBUTE.SEQUENCE BULK.DATA.SOURCE SESSION)
			  ERRORS
			  (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR 
					AUTHENTICATION.ERROR CONNECTION.ERROR HANDLE.ERROR 
					SESSION.ERROR SPACE.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
			  14)
		 (FIND ARGS (HANDLE SCOPE.SEQUENCE CONTROL.SEQUENCE SESSION)
		       RESULTS
		       (HANDLE)
		       ERRORS
		       (ACCESS.ERROR AUTHENTICATION.ERROR CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
				     HANDLE.ERROR SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR SESSION.ERROR 
				     UNDEFINED.ERROR)
		       17)
		 (LIST ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SCOPE.SEQUENCE BULK.DATA.SINK SESSION)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     CONNECTION.ERROR HANDLE.ERROR SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
				     SESSION.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
		       18))
		ERRORS
		((ATTRIBUTE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
				       0)
		 (ATTRIBUTE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
					1)
		 (CONTROL.TYPE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
				     2)
		 (CONTROL.VALUE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
				      3)
		 (SCOPE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
				   4)
		 (SCOPE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
				    5)
		 (ACCESS.ERROR ARGS (ACCESS.PROBLEM)
			       6)
		 (AUTHENTICATION.ERROR ARGS ((AUTHENTICATION . PROBLEM))
				       7)
		 (CONNECTION.ERROR ARGS (CONNECTION.PROBLEM)
				   8)
		 (HANDLE.ERROR ARGS (HANDLE.PROBLEM)
			       9)
		 (INSERTION.ERROR ARGS (INSERTION.PROBLEM)
				  10)
		 (SERVICE.ERROR ARGS (SERVICE.PROBLEM)
				11)
		 (SESSION.ERROR ARGS (SESSION.PROBLEM)
				12)
		 (SPACE.ERROR ARGS (SPACE.PROBLEM)
			      13)
		 (TRANSFER.ERROR ARGS (TRANSFER.PROBLEM)
				 14)
		 (UNDEFINED.ERROR ARGS (CARDINAL)
				  15)))



(* Lisp support.)

(DECLARE: DONTCOPY 
(DECLARE: EVAL@COMPILE 

(RPAQQ \FILING.ALL.ATTRIBUTE.TYPES (-1))

(RPAQQ \FILING.DEFAULT.TIMEOUT -1)

(RPAQQ \FILING.UNLIMITED.COUNT -1)

(RPAQQ \FILING.NULL.FILTER (ALL))

(RPAQQ \FILING.NULL.HANDLE (0 0))

(RPAQQ \FILING.NULL.FILE.ID (0 0 0 0 0))

(RPAQQ \FILING.LOWEST.VERSION 0)

(RPAQQ \FILING.HIGHEST.VERSION -1)

(RPAQQ \FILING.ATTRIBUTES ((CHECKSUM 0 CARDINAL)
			   (CHILDREN.UNIQUELY.NAMED 1 BOOLEAN)
			   (CREATED.BY 2 USER)
			   (CREATED.ON 3 TIME)
			   (FILE.ID 4 FILE.ID)
			   (IS.DIRECTORY 5 BOOLEAN)
			   (IS.TEMPORARY 6 BOOLEAN)
			   (MODIFIED.BY 7 USER)
			   (MODIFIED.ON 8 TIME)
			   (NAME 9 STRING)
			   (NUMBER.OF.CHILDREN 10 CARDINAL)
			   (ORDERING 11 ORDERING)
			   (PARENT.ID 12 FILE.ID)
			   (POSITION 13 (SEQUENCE UNSPECIFIED))
			   (READ.BY 14 USER)
			   (READ.ON 15 TIME)
			   (SIZE.IN.BYTES 16 LONGCARDINAL)
			   (FILE.TYPE 17 LONGCARDINAL)
			   (VERSION 18 CARDINAL)
			   (ACCESS.LIST 19 ACCESS.LIST)
			   (DEFAULT.ACCESS.LIST 20 ACCESS.LIST)
			   (PATHNAME 21 STRING)))

(RPAQQ LISP.TO.NS.FILE.ATTRIBUTES ((IWRITEDATE MODIFIED.ON)
				   (IREADDATE READ.ON)
				   (ICREATIONDATE CREATED.ON)
				   (LENGTH SIZE.IN.BYTES)))

[CONSTANTS (\FILING.ALL.ATTRIBUTE.TYPES (QUOTE (-1)))
	   (\FILING.DEFAULT.TIMEOUT -1)
	   (\FILING.UNLIMITED.COUNT -1)
	   (\FILING.NULL.FILTER (QUOTE (ALL)))
	   (\FILING.NULL.HANDLE (QUOTE (0 0)))
	   (\FILING.NULL.FILE.ID (QUOTE (0 0 0 0 0)))
	   (\FILING.LOWEST.VERSION 0)
	   (\FILING.HIGHEST.VERSION -1)
	   [\FILING.ATTRIBUTES (QUOTE ((CHECKSUM 0 CARDINAL)
				       (CHILDREN.UNIQUELY.NAMED 1 BOOLEAN)
				       (CREATED.BY 2 USER)
				       (CREATED.ON 3 TIME)
				       (FILE.ID 4 FILE.ID)
				       (IS.DIRECTORY 5 BOOLEAN)
				       (IS.TEMPORARY 6 BOOLEAN)
				       (MODIFIED.BY 7 USER)
				       (MODIFIED.ON 8 TIME)
				       (NAME 9 STRING)
				       (NUMBER.OF.CHILDREN 10 CARDINAL)
				       (ORDERING 11 ORDERING)
				       (PARENT.ID 12 FILE.ID)
				       (POSITION 13 (SEQUENCE UNSPECIFIED))
				       (READ.BY 14 USER)
				       (READ.ON 15 TIME)
				       (SIZE.IN.BYTES 16 LONGCARDINAL)
				       (FILE.TYPE 17 LONGCARDINAL)
				       (VERSION 18 CARDINAL)
				       (ACCESS.LIST 19 ACCESS.LIST)
				       (DEFAULT.ACCESS.LIST 20 ACCESS.LIST)
				       (PATHNAME 21 STRING]
	   (LISP.TO.NS.FILE.ATTRIBUTES (QUOTE ((IWRITEDATE MODIFIED.ON)
					       (IREADDATE READ.ON)
					       (ICREATIONDATE CREATED.ON)
					       (LENGTH SIZE.IN.BYTES]
)

[DECLARE: EVAL@COMPILE 

(ACCESSFNS NSFILINGSTREAM ((NSFILING.CONNECTION (fetch F3 of DATUM)
						(replace F3 of DATUM with NEWVALUE))
			   (NSFILING.HANDLE (fetch F4 of DATUM)
					    (replace F4 of DATUM with NEWVALUE))
			   (NSFILING.ATTRIBUTES (fetch F5 of DATUM)
						(replace F5 of DATUM with NEWVALUE))))

(DATATYPE FILING.CONNECTION (FC.FILESERVER                   (* Name of fileserver.)
					   FC.COURIER.STREAM
                                                             (* Current open Courier stream for this connection.)
					   FC.SESSION        (* Courier session handle for this connection.)
					   FC.CONTINUANCE    (* Continuance of this session in seconds, in the form 
							     returned by SETUPTIMER.)
					   FC.CURRENT.DIRECTORY
                                                             (* Courier HANDLE for current directory.)
					   FC.CURRENT.PATH   (* List of directories in current path.)
					   ))

(RECORD \NSFILING.GENFILESTATE (PATTERN CONNECTION FILELIST))
]
(/DECLAREDATATYPE (QUOTE FILING.CONNECTION)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER)))

(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS \NSFILING.CONNECTIONS \NSFILING.DEVICE)
)
)
(/DECLAREDATATYPE (QUOTE FILING.CONNECTION)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER)))

(RPAQ? \NSFILING.LOCK (CREATE.MONITORLOCK (QUOTE NSFILING)))

(RPAQ? \NSFILING.CONNECTIONS NIL)
(DEFINEQ

(\NSFILING.LOGIN
  [LAMBDA (FILESERVER)                                       (* ecc " 8-AUG-83 14:12")
    (RESETLST (PROG (STREAM SESSION CONNECTION)
		    (bind CREDENTIALS MSG until SESSION
		       do (SETQ CREDENTIALS (NSLOGIN FILESERVER MSG))
			  (SETQ STREAM (COURIER.OPEN FILESERVER (QUOTE FILESERVER)
						     NIL
						     (PACK* FILESERVER "#FILING")))
			  (RESETSAVE NIL (LIST [QUOTE (LAMBDA (X)
							      (if RESETSTATE
								  then (SPP.CLOSE X T]
					       STREAM))
			  (SETQ SESSION (COURIER.CALL STREAM (QUOTE FILING)
						      (QUOTE LOGON)
						      [BQUOTE ((TYPE 0)
							       (VALUE , (COURIER.WRITE.REP
									(PARSE.CH.NAME (CAR 
										      CREDENTIALS))
									(QUOTE AUTHENTICATION)
									(QUOTE SIMPLE.CREDENTIALS]
						      (COURIER.WRITE.REP (HASH.PASSWORD (CDR 
										      CREDENTIALS))
									 (QUOTE FILING)
									 (QUOTE SIMPLE.VERIFIER))
						      (QUOTE RETURNERRORS)))
			  (if (AND SESSION (EQ (CAR SESSION)
					       (QUOTE ERROR))
				   (EQ (CADR SESSION)
				       (QUOTE AUTHENTICATION.ERROR)))
			      then (SETQ SESSION NIL)
				   (SETQ MSG "Login incorrect.")
				   (SPP.CLOSE STREAM)))
		    (if (EQ (CAR SESSION)
			    (QUOTE ERROR))
			then (ERROR (PACK* "Error while logging on to " FILESERVER)
				    SESSION))
		    (SETQ CONNECTION
		      (create FILING.CONNECTION
			      FC.FILESERVER ← FILESERVER
			      FC.COURIER.STREAM ← STREAM
			      FC.SESSION ← SESSION
			      FC.CURRENT.DIRECTORY ← \FILING.NULL.HANDLE))
		    (RESETSAVE NIL (LIST [QUOTE (LAMBDA (X)
							(if RESETSTATE
							    then (\NSFILING.LOGOUT X T]
					 CONNECTION))
		    (replace FC.CONTINUANCE of CONNECTION with (SETUPTIMER (COURIER.CALL
									     STREAM
									     (QUOTE FILING)
									     (QUOTE CONTINUE)
									     SESSION)
									   (fetch FC.CONTINUANCE
									      of CONNECTION)
									   (QUOTE SECONDS)))
		    (\NSFILING.CONNECT CONNECTION)
		    (RETURN CONNECTION])

(\NSFILING.LOGOUT
  [LAMBDA (CONNECTION ABORT?)                                (* ecc " 4-AUG-83 10:09")
    (PROG (NEWSTREAM)
          [if (NOT (AND (fetch FC.COURIER.STREAM of CONNECTION)
			(\NSFILING.LOGOUT.INTERNAL CONNECTION)))
	      then                                           (* Something was wrong with the connection;
							     try a new one.)
		   (if (NOT (AND (replace FC.COURIER.STREAM of CONNECTION
				    with (COURIER.OPEN (fetch FC.FILESERVER of CONNECTION)
						       (QUOTE FILESERVER)
						       T
						       (PACK* (fetch FC.FILESERVER of CONNECTION)
							      "#LOGOFF")))
				 (\NSFILING.LOGOUT.INTERNAL CONNECTION)))
		       then (if NSWIZARDFLG
				then (printout T "WARNING: Can't log off filing session on "
					       (fetch FC.FILESERVER of CONNECTION)
					       T]
          (replace FC.COURIER.STREAM of CONNECTION with NIL)
          (SETQ \NSFILING.CONNECTIONS (DREMOVE CONNECTION \NSFILING.CONNECTIONS])

(\NSFILING.LOGOUT.INTERNAL
  [LAMBDA (CONNECTION)                                       (* ecc "14-JUL-83 15:27")
    (PROG ((COURIERSTREAM (fetch FC.COURIER.STREAM of CONNECTION))
	   FILESTREAM)
          (RETURN (NLSETQ (RESETLST (RESETSAVE NIL (LIST (QUOTE SPP.CLOSE)
							 COURIERSTREAM T))
				    (if (SETQ FILESTREAM (fetch SPPSUBSTREAM of (GETSPPCON 
										    COURIERSTREAM)))
					then (CLOSEF? FILESTREAM))
				    (COURIER.CALL COURIERSTREAM (QUOTE FILING)
						  (QUOTE LOGOFF)
						  (fetch FC.SESSION of CONNECTION)
						  T)
				    T])

(\NSFILING.CONNECT
  [LAMBDA (CONNECTION PATHNAME)                              (* ecc " 8-AUG-83 14:17")

          (* Follow the list of directories in PATHNAME and cache the handle for the final one in the connection record.
	  The special case when PATHNAME is NIL is equivalent to connecting to the root directory. Uses cached current path 
	  to avoid useless reconnecting. WARNING: this may fail if there is ever more than one version of the same 
	  subdirectory name. To fix this we could use the same hack that's in \NSFILING.GETFILE : first enumerate the 
	  versions (also requiring the IS.DIRECTORY attribute) and then use the unique FILE.ID, but since it hasn't been a 
	  problem yet, we don't bother.)


    (PROG ((NEW.DIRLIST (\PATHNAME.TO.DIRECTORY.LIST PATHNAME))
	   (OLD.DIRLIST (fetch FC.CURRENT.PATH of CONNECTION))
	   ADDITIONAL.DIRLIST FAILURE)
          (if (AND NEW.DIRLIST (EQUAL NEW.DIRLIST OLD.DIRLIST))
	      then                                           (* Nothing needs to be done because we're already 
							     connected to this path.)
		   (RETURN T))
          (if (AND (SETQ ADDITIONAL.DIRLIST NEW.DIRLIST)
		   (bind NEW.DIR for OLD.DIR in OLD.DIRLIST
		      always (SETQ NEW.DIR (CAR ADDITIONAL.DIRLIST))
			     (SETQ ADDITIONAL.DIRLIST (CDR ADDITIONAL.DIRLIST))
			     (EQ OLD.DIR NEW.DIR)))
	      then                                           (* We're currently connected to a prefix of the desired 
							     path, so we can save some remote calls.)
		   (SETQ NEW.DIRLIST ADDITIONAL.DIRLIST)
	    else 

          (* We need to start again from the root. If we kept open the handles of all directories in the current path, we 
	  would only have to go back to the nearest common ancestor, but it's probably not worth it.)


		 (if (NOT (EQUAL (fetch FC.CURRENT.DIRECTORY of CONNECTION)
				 \FILING.NULL.HANDLE))
		     then (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
					(QUOTE FILING)
					(QUOTE CLOSE)
					(fetch FC.CURRENT.DIRECTORY of CONNECTION)
					(fetch FC.SESSION of CONNECTION)))
		 (replace FC.CURRENT.DIRECTORY of CONNECTION with (COURIER.CALL (fetch 
										FC.COURIER.STREAM
										   of CONNECTION)
										(QUOTE FILING)
										(QUOTE OPEN)
										NIL 
									      \FILING.NULL.HANDLE NIL
										(fetch FC.SESSION
										   of CONNECTION)
										T))
		 (replace FC.CURRENT.PATH of CONNECTION with NIL))
          [bind NEW.HANDLE OLD.HANDLE for NEW.DIR in NEW.DIRLIST
	     do (SETQ OLD.HANDLE (fetch FC.CURRENT.DIRECTORY of CONNECTION))
		(SETQ NEW.HANDLE (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
					       (QUOTE FILING)
					       (QUOTE OPEN)
					       [\WRITE.FILING.ATTRIBUTE.SEQUENCE
						 (BQUOTE ((NAME , NEW.DIR]
					       OLD.HANDLE NIL (fetch FC.SESSION of CONNECTION)
					       T))
		(if (NULL NEW.HANDLE)
		    then (SETQ FAILURE T)
			 (RETURN))
		(if (NOT (EQUAL OLD.HANDLE \FILING.NULL.HANDLE))
		    then (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
				       (QUOTE FILING)
				       (QUOTE CLOSE)
				       OLD.HANDLE
				       (fetch FC.SESSION of CONNECTION)))
		(replace FC.CURRENT.DIRECTORY of CONNECTION with NEW.HANDLE)
		(replace FC.CURRENT.PATH of CONNECTION with (APPEND (fetch FC.CURRENT.PATH
								       of CONNECTION)
								    (LIST NEW.DIR]
          (RETURN (NOT FAILURE])

(\PATHNAME.TO.DIRECTORY.LIST
  [LAMBDA (PATHNAME)                                         (* edited: " 2-AUG-83 14:30")
                                                             (* Return a list of the directory components of a 
							     pathname. If the pathname is NIL it refers to the root 
							     directory.)
    (\PATHNAME.TO.DIRECTORY.LIST.INTERNAL (FILENAMEFIELD PATHNAME (QUOTE DIRECTORY])

(\PATHNAME.TO.DIRECTORY.LIST.INTERNAL
  [LAMBDA (DIRS)                                             (* edited: " 2-AUG-83 15:02")
    (if DIRS
	then (PROG ((I (STRPOS ">" DIRS)))
	           (RETURN (if I
			       then [CONS (SUBATOM DIRS 1 (SUB1 I))
					  (\PATHNAME.TO.DIRECTORY.LIST.INTERNAL (SUBATOM
										  DIRS
										  (ADD1 I]
			     else (LIST (MKATOM DIRS])

(\DIRECTORY.LIST.TO.PATHNAME
  [LAMBDA (DIRLIST)                                          (* edited: " 2-AUG-83 14:33")
    (APPLY (FUNCTION PACK*)
	   (CONS "<" (OR (for DIR in DIRLIST collect (CONCAT DIR ">"))
			 ">"])

(\NSFILING.CREATE.DIRECTORY
  [LAMBDA (CONNECTION DIRECTORYNAME)                         (* ecc " 8-AUG-83 14:18")
    (PROG ((STREAM (fetch FC.COURIER.STREAM of CONNECTION))
	   (SESSION (fetch FC.SESSION of CONNECTION)))
          (COURIER.CALL STREAM (QUOTE FILING)
			(QUOTE CLOSE)
			(COURIER.CALL STREAM (QUOTE FILING)
				      (QUOTE CREATE)
				      (fetch FC.CURRENT.DIRECTORY of CONNECTION)
				      [\WRITE.FILING.ATTRIBUTE.SEQUENCE (BQUOTE ((NAME , 
										    DIRECTORYNAME)
										 (IS.DIRECTORY T)
										 (FILE.TYPE 1]
				      NIL SESSION)
			SESSION])

(\NSFILING.LIST
  [LAMBDA (CONNECTION PATTERN)                               (* ecc " 4-AUG-83 13:55")
                                                             (* Lists the files matching a wildcard pattern.
							     This is an undocumented feature.)
    (PROG ((NAME.ATTRIBUTE)
	   STREAM SEQUENCE.OF.ATTRIBUTE.SEQUENCES)
          (SETQ STREAM (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
				     (QUOTE FILING)
				     (QUOTE LIST)
				     (fetch FC.CURRENT.DIRECTORY of CONNECTION)
				     (\FILING.ATTRIBUTE.TYPE.SEQUENCE (QUOTE (NAME VERSION 
										   IS.DIRECTORY)))
				     (PROGN 

          (* The following doesn't quite work because the fileserver won't match against subdirectory names.
	  So we always enumerate the whole directory, regardless of the pattern. (BQUOTE ((FILTER (MATCHES , 
	  (\WRITE.FILING.ATTRIBUTE (QUOTE NAME) PATTERN))))))


					    NIL)
				     NIL
				     (fetch FC.SESSION of CONNECTION)))
          (SETQ SEQUENCE.OF.ATTRIBUTE.SEQUENCES (COURIER.READ.BULKDATA STREAM (QUOTE FILING)
								       (QUOTE ATTRIBUTE.SEQUENCE)))
          (CLOSEF STREAM)
          (RETURN (for SEQ in SEQUENCE.OF.ATTRIBUTE.SEQUENCES collect (\READ.FILING.ATTRIBUTE.SEQUENCE
									SEQ])

(\NSFILING.LISTVERSIONS
  [LAMBDA (CONNECTION FILENAME)                              (* ecc " 4-AUG-83 16:14")
                                                             (* Like \NSFILING.LIST but lists the versions of a 
							     particular file. Get the FILE.ID for use by 
							     \NSFILING.GETFILE)
    (PROG ((NAME.ATTRIBUTE)
	   STREAM SEQUENCE.OF.ATTRIBUTE.SEQUENCES)
          (SETQ STREAM (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
				     (QUOTE FILING)
				     (QUOTE LIST)
				     (fetch FC.CURRENT.DIRECTORY of CONNECTION)
				     (\FILING.ATTRIBUTE.TYPE.SEQUENCE (QUOTE (NAME VERSION 
										   IS.DIRECTORY 
										   FILE.ID)))
				     [BQUOTE ((FILTER (EQUAL ((ATTRIBUTE , (\WRITE.FILING.ATTRIBUTE
									   (QUOTE NAME)
									   FILENAME))
							      (INTERPRETATION STRING]
				     NIL
				     (fetch FC.SESSION of CONNECTION)))
          (SETQ SEQUENCE.OF.ATTRIBUTE.SEQUENCES (COURIER.READ.BULKDATA STREAM (QUOTE FILING)
								       (QUOTE ATTRIBUTE.SEQUENCE)))
          (CLOSEF STREAM)
          (RETURN (for SEQ in SEQUENCE.OF.ATTRIBUTE.SEQUENCES collect (\READ.FILING.ATTRIBUTE.SEQUENCE
									SEQ])

(\FILING.ATTRIBUTE.TYPE.SEQUENCE
  [LAMBDA (ATTRIBUTETYPES)                                   (* ecc " 3-AUG-83 16:39")
    (for ATTR in ATTRIBUTETYPES collect (\FILING.ATTRIBUTE.TYPE ATTR])

(\FILING.ATTRIBUTE.TYPE
  [LAMBDA (ATTR)                                             (* ecc " 3-AUG-83 16:37")
    (for X in \FILING.ATTRIBUTES do (if (EQ (CAR X)
					    ATTR)
					then (RETURN (CADR X)))
       finally (ERROR "Unknown Filing attribute" ATTR])

(\READ.FILING.ATTRIBUTE.SEQUENCE
  [LAMBDA (SEQ)                                              (* ecc " 3-AUG-83 16:35")
                                                             (* Given an ATTRIBUTE.SEQUENCE object, decode the values
							     based on the attribute types and return a list of 
							     attribute type/value pairs.)
    (for ATTR in SEQ collect (\READ.FILING.ATTRIBUTE ATTR])

(\READ.FILING.ATTRIBUTE
  [LAMBDA (ATTR)                                             (* ecc " 3-AUG-83 16:34")
                                                             (* Given an ATTRIBUTE object, decode the value based on 
							     the attribute type and return a type/value pair.)
    (bind (TYPE ←(CADR (ASSOC (QUOTE TYPE)
			      ATTR)))
	  (VALUE ←(CADR (ASSOC (QUOTE VALUE)
			       ATTR)))
       for X in \FILING.ATTRIBUTES do [if (EQP (CADR X)
					       TYPE)
					  then (RETURN (LIST (CAR X)
							     (COURIER.READ.REP VALUE (QUOTE FILING)
									       (CADDR X]
       finally (RETURN (LIST TYPE VALUE])

(\WRITE.FILING.ATTRIBUTE.SEQUENCE
  [LAMBDA (TYPE/VALUE/PAIRS)                                 (* ecc " 3-AUG-83 16:39")
                                                             (* Return a Courier ATTRIBUTE.SEQUENCE corresponding to 
							     a list of attribute types and values.)
    (for TYPE/VALUE in TYPE/VALUE/PAIRS collect (\WRITE.FILING.ATTRIBUTE (CAR TYPE/VALUE)
									 (CADR TYPE/VALUE])

(\WRITE.FILING.ATTRIBUTE
  [LAMBDA (TYPE VALUE)                                       (* ecc " 3-AUG-83 16:31")
                                                             (* Return a Courier ATTRIBUTE corresponding to the 
							     specified type and value.)
    (for X in \FILING.ATTRIBUTES do [if (EQ (CAR X)
					    TYPE)
					then (RETURN (BQUOTE ((TYPE , (CADR X))
							      (VALUE , (COURIER.WRITE.REP
								       VALUE
								       (QUOTE FILING)
								       (CADDR X]
       finally (ERROR "Unknown Filing attribute" TYPE])

(NSDIRECTORY
  [LAMBDA (PATTERN)                                          (* edited: " 2-AUG-83 14:00")
    (PROG (HOST CONNECTION LST)
          [SETQ PATTERN (\ADD.CONNECTED.DIR (OR PATTERN (QUOTE *]
          (SETQ HOST (FILENAMEFIELD PATTERN (QUOTE HOST)))
          (SETQ CONNECTION (\GETFILINGCONNECTION HOST))
          (SETQ LST (AND (\NSFILING.CONNECT CONNECTION PATTERN)
			 (\NSFILING.LIST CONNECTION)))
          (RETURN (for X in LST collect (\NSFILING.FULLNAME CONNECTION (CADR (ASSOC (QUOTE NAME)
										    X))
							    (CADR (ASSOC (QUOTE VERSION)
									 X))
							    (CADR (ASSOC (QUOTE IS.DIRECTORY)
									 X])

(NSCREATEDIRECTORY
  [LAMBDA (HOST/DIR)                                         (* ecc " 1-AUG-83 15:46")
    (PROG (REVERSE.DIRLIST ALL.BUT.LAST.DIR LAST.DIR CONNECTION)
          (SETQ HOST/DIR (\ADD.CONNECTED.DIR HOST/DIR))
          (SETQ REVERSE.DIRLIST (REVERSE (\PATHNAME.TO.DIRECTORY.LIST HOST/DIR)))
          (if [NOT (AND (SETQ ALL.BUT.LAST.DIR (REVERSE (CDR REVERSE.DIRLIST)))
			(SETQ LAST.DIR (CAR REVERSE.DIRLIST]
	      then (LISPERROR "BAD FILE NAME" HOST/DIR))
          [SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD HOST/DIR (QUOTE HOST]
          (\NSFILING.CONNECT CONNECTION (\DIRECTORY.LIST.TO.PATHNAME ALL.BUT.LAST.DIR))
          (\NSFILING.CREATE.DIRECTORY CONNECTION LAST.DIR)
          (RETURN HOST/DIR])

(\NSFILING.INIT
  [LAMBDA NIL                                                (* ecc "20-JUL-83 17:08")
    (\DEFINEDEVICE NIL (SETQ \NSFILING.DEVICE (create FDEV using \SPP.BULKDATA.DEVICE DEVICENAME ←(
								   QUOTE NSFILING)
								 OPENFILE ←(FUNCTION 
								   \NSFILING.OPENFILE)
								 CLOSEFILE ←(FUNCTION 
								   \NSFILING.CLOSEFILE)
								 GETFILEINFO ←(FUNCTION 
								   \NSFILING.GETFILEINFO)
								 SETFILEINFO ←(FUNCTION 
								   \NSFILING.SETFILEINFO)
								 GETFILEPTR ←(FUNCTION ZERO)
								 GETEOFPTR ←(FUNCTION 
								   \NSFILING.GETEOFPTR)
								 DELETEFILE ←(FUNCTION 
								   \NSFILING.DELETEFILE)
								 HOSTNAMEP ←(FUNCTION 
								   \NSFILING.HOSTNAMEP)
								 GETFILENAME ←(FUNCTION 
								   \NSFILING.GETFILENAME)
								 DIRECTORYNAMEP ←(FUNCTION 
								   \NSFILING.DIRECTORYNAMEP)
								 GENERATEFILES ←(FUNCTION 
								   \NSFILING.GENERATEFILES)
								 EVENTFN ←(FUNCTION \NSFILING.EVENTFN]
)

(\GETFILINGCONNECTION
  [LAMBDA (FILESERVER)                                       (* ecc "25-JUL-83 15:53")
                                                             (* Find a connection to this fileserver which doesn't 
							     have a file transfer outstanding,)
    (WITH.MONITOR \NSFILING.LOCK (PROG (CONNECTION)
				       (SETQ FILESERVER (CANONICAL.CH.NAME FILESERVER))
				       [SETQ CONNECTION
					 (bind (TAIL ← \NSFILING.CONNECTIONS)
					       C while TAIL
					    do               (* This control structure needed because 
							     \VALID.FILING.CONNECTIONP might do DREMOVE on 
							     \NSFILING.CONNECTIONS)
					       (SETQ C (CAR TAIL))
					       (SETQ TAIL (CDR TAIL))
					       (if (AND (EQ (fetch FC.FILESERVER of C)
							    FILESERVER)
							(\VALID.FILING.CONNECTIONP C))
						   then (RETURN C]
				       (if (NULL CONNECTION)
					   then (SETQ CONNECTION (\NSFILING.LOGIN FILESERVER))
						(push \NSFILING.CONNECTIONS CONNECTION))
				       (RETURN CONNECTION])

(\VALID.FILING.CONNECTIONP
  [LAMBDA (CONNECTION)                                       (* ecc " 4-AUG-83 10:26")
                                                             (* Try to determine if this is a usable Filing 
							     connection. If it's dead for some reason, remove it from
							     the list.)
    (PROG ((STREAM (fetch FC.COURIER.STREAM of CONNECTION))
	   N)
          (if (OR (AND STREAM (GETSPPCON STREAM)
		       (fetch SPPSUBSTREAM of (GETSPPCON STREAM)))
		  (NOT (\LOGGED.ONTO.NSFILESERVERP CONNECTION)))
	      then                                           (* There's a file transfer outstanding or user is logged
							     in under a different name.)
		   (RETURN NIL))
          [if (OR (NULL STREAM)
		  (NULL (GETSPPCON STREAM))
		  (NOT (READABLE STREAM))
		  (TIMEREXPIRED? (fetch FC.CONTINUANCE of CONNECTION)
				 (QUOTE SECONDS)))
	      then                                           (* Try to reconnect.)
		   (replace FC.COURIER.STREAM of CONNECTION
		      with (SETQ STREAM (COURIER.OPEN (fetch FC.FILESERVER of CONNECTION)
						      (QUOTE FILESERVER)
						      NIL
						      (PACK* (fetch FC.FILESERVER of CONNECTION)
							     "#FILING"]
                                                             (* Try a Courier call. If it errors out, forget this 
							     connection.)
          (NLSETQ (SETQ N (COURIER.CALL STREAM (QUOTE FILING)
					(QUOTE CONTINUE)
					(fetch FC.SESSION of CONNECTION)
					T)))
          (if N
	      then (replace FC.CONTINUANCE of CONNECTION with (SETUPTIMER N (fetch FC.CONTINUANCE
									       of CONNECTION)
									  (QUOTE SECONDS)))
		   (RETURN CONNECTION)
	    else (\NSFILING.LOGOUT CONNECTION)
		 (RETURN NIL])

(\LOGGED.ONTO.NSFILESERVERP
  [LAMBDA (CONNECTION)                                       (* ecc " 4-AUG-83 10:26")

          (* Check whether the user's current login to this host is the same as the one used for this connection.
	  The hashed password is the VERIFIER component of the SESSION record.)


    (EQP (CAADR (ASSOC (QUOTE VERIFIER)
		       (fetch FC.SESSION of CONNECTION)))
	 (HASH.PASSWORD (CDR (NSLOGIN (fetch FC.FILESERVER of CONNECTION])

(CLOSE.NSFILING.CONNECTIONS
  [LAMBDA NIL                                                (* ecc "18-JUL-83 14:45")
    (bind (TAIL ← \NSFILING.CONNECTIONS)
	  CONNECTION while TAIL
       do                                                    (* This control structure needed because 
							     \NSFILING.LOGOUT does DREMOVE on \NSFILING.CONNECTIONS)
	  (SETQ CONNECTION (CAR TAIL))
	  (SETQ TAIL (CDR TAIL))
	  (\NSFILING.LOGOUT CONNECTION T])

(\NSFILING.OPENFILE
  [LAMBDA (FILENAME ACCESS RECOG)                            (* ecc "22-JUN-83 13:30")
    (\NSFILING.GETFILE FILENAME ACCESS RECOG T NIL])

(\NSFILING.GETFILE
  [LAMBDA (FILENAME ACCESS RECOG NOERROR OPTION)             (* ecc " 8-AUG-83 14:19")

          (* Opens FILENAME for specified ACCESS and RECOG, returning a stream. If NOERROR is non-NIL, returns NIL on 
	  errors. If OPTION is NAME, HANDLE, or ATTRIBUTES, just return the appropriate information instead of a stream.
	  If OPTION is DIRECTORY, return T or NIL if FILENAME is a directory or not.)


    (PROG ((HOST (FILENAMEFIELD FILENAME (QUOTE HOST)))
	   (NAME (ROOTFILENAME FILENAME))
	   (VERSION (FILENAMEFIELD FILENAME (QUOTE VERSION)))
	   CONNECTION DESIRED.INFO (LOWEST.VERSION 65535)
	   LOWEST.VERSION.INFO
	   (HIGHEST.VERSION 0)
	   HIGHEST.VERSION.INFO FILE.ID COURIERSTREAM SESSION HANDLE FILESTREAM ATTRS FULLNAME)
          [if [OR (NULL HOST)
		  (AND (NULL NAME)
		       (NEQ OPTION (QUOTE DIRECTORY]
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "BAD FILE NAME" FILENAME]
          (SETQ CONNECTION (\GETFILINGCONNECTION HOST))
          (if (EQ OPTION (QUOTE DIRECTORY))
	      then                                           (* Just return success or failure of attempt to follow 
							     the directories in the pathname.)
		   (RETURN (\NSFILING.CONNECT CONNECTION FILENAME)))
          [if (NOT (\NSFILING.CONNECT CONNECTION FILENAME))
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "FILE NOT FOUND" FILENAME]

          (* NS fileservers don't support version numbers properly. As a work-around, we first list all versions of the 
	  file. file, also getting back the internal FILE.ID for each of them. We make a pass over this list and find the 
	  lowest and highest versions as well as the specified one, if any.)


          (bind V for ALST in (\NSFILING.LISTVERSIONS CONNECTION NAME)
	     do (SETQ V (CADR (ASSOC (QUOTE VERSION)
				     ALST)))
		(if (EQP V VERSION)
		    then (SETQ DESIRED.INFO ALST))
		(if (ILESSP V LOWEST.VERSION)
		    then (SETQ LOWEST.VERSION V)
			 (SETQ LOWEST.VERSION.INFO ALST))
		(if (IGREATERP V HIGHEST.VERSION)
		    then (SETQ HIGHEST.VERSION V)
			 (SETQ HIGHEST.VERSION.INFO ALST)))

          (* Find the FILE.ID of the appropriate version of the file. Uses the same algorithm that's in \FILESPEC in 
	  MOD44IO; it may not be correct, but it's consistent.)


          [SETQ FILE.ID (CADR (ASSOC (QUOTE FILE.ID)
				     (SELECTQ (OR VERSION RECOG)
					      ((OLD OLD/NEW)
						(SETQ VERSION HIGHEST.VERSION)
						HIGHEST.VERSION.INFO)
					      (NEW (SETQ VERSION (ADD1 (OR HIGHEST.VERSION 0)))
						   NIL)
					      (OLDEST (SETQ VERSION LOWEST.VERSION)
						      LOWEST.VERSION.INFO)
					      DESIRED.INFO]
                                                             (* Now get an open file handle for the appropriate 
							     version of the file.)
          (SETQ COURIERSTREAM (fetch FC.COURIER.STREAM of CONNECTION))
          (SETQ SESSION (fetch FC.SESSION of CONNECTION))
          (if FILE.ID
	      then                                           (* Try to open an existing file.)
		   (SETQ HANDLE (COURIER.CALL COURIERSTREAM (QUOTE FILING)
					      (QUOTE OPEN)
					      [\WRITE.FILING.ATTRIBUTE.SEQUENCE (BQUOTE
										  ((FILE.ID , FILE.ID]
					      (fetch FC.CURRENT.DIRECTORY of CONNECTION)
					      NIL SESSION T))
	    elseif [AND (EQ ACCESS (QUOTE OUTPUT))
			(MEMB RECOG (QUOTE (NIL NEW OLD/NEW]
	      then                                           (* Create a new file.)
		   (SETQ FILESTREAM (COURIER.CALL COURIERSTREAM (QUOTE FILING)
						  (QUOTE STORE)
						  (fetch FC.CURRENT.DIRECTORY of CONNECTION)
						  [\WRITE.FILING.ATTRIBUTE.SEQUENCE
						    (BQUOTE ((NAME , NAME)
							     (VERSION , VERSION]
						  NIL
						  (FUNCTION [LAMBDA (SUBSTREAM H)
						      (SETQ HANDLE H])
						  SESSION T))

          (* Write a file with a single byte in it so that we can get back the FILE.ID info. Later we can do a REPLACE 
	  operation to write the user's data.)


		   (BOUT FILESTREAM 0)
		   (CLOSEF FILESTREAM)                       (* The FUNARG we passed to the STORE operation should 
							     have set HANDLE.))
          [if (NULL HANDLE)
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "FILE NOT FOUND" FILENAME]
          (SETQ ATTRS (\READ.FILING.ATTRIBUTE.SEQUENCE (COURIER.CALL COURIERSTREAM (QUOTE FILING)
								     (QUOTE GET.ATTRIBUTES)
								     HANDLE 
								     \FILING.ALL.ATTRIBUTE.TYPES 
								     SESSION)))
          [SETQ FULLNAME (\NSFILING.FULLNAME CONNECTION NAME (CADR (ASSOC (QUOTE VERSION)
									  ATTRS]
          [if OPTION
	      then (if (NEQ OPTION (QUOTE HANDLE))
		       then                                  (* Only the HANDLE option needs to keep it open.)
			    (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE))
		   (RETURN (SELECTQ OPTION
				    (NAME FULLNAME)
				    (HANDLE (CONS (BQUOTE (HANDLE , HANDLE))
						  ATTRS))
				    (ATTRIBUTES ATTRS)
				    (SHOULDNT]
          (SETQ FILESTREAM (SELECTQ ACCESS
				    (INPUT (COURIER.CALL COURIERSTREAM (QUOTE FILING)
							 (QUOTE RETRIEVE)
							 HANDLE NIL SESSION T))
				    (OUTPUT (COURIER.CALL COURIERSTREAM (QUOTE FILING)
							  (QUOTE REPLACE)
							  HANDLE NIL NIL SESSION T))
				    (LISPERROR "ILLEGAL ARG" ACCESS)))
          (if (NULL FILESTREAM)
	      then (LISPERROR "FILE NOT FOUND" FILENAME))
          (replace FULLFILENAME of FILESTREAM with FULLNAME)
          (replace NSFILING.CONNECTION of FILESTREAM with CONNECTION)
          (replace NSFILING.HANDLE of FILESTREAM with HANDLE)
          (replace NSFILING.ATTRIBUTES of FILESTREAM with ATTRS)
          (replace DEVICE of FILESTREAM with \NSFILING.DEVICE)
          (RETURN FILESTREAM])

(\NSFILING.ORIGINAL.GETFILE
  [LAMBDA (FILENAME ACCESS RECOG NOERROR OPTION)             (* ecc " 4-AUG-83 16:16")

          (* Opens FILENAME for specified ACCESS and RECOG, returning a stream. If NOERROR is non-NIL, returns NIL on 
	  errors. If OPTION is NAME, HANDLE, or ATTRIBUTES, just return the appropriate information instead of a stream.
	  If OPTION is DIRECTORY, return T or NIL if FILENAME is a directory or not.)


    (PROG ((HOST (FILENAMEFIELD FILENAME (QUOTE HOST)))
	   (NAME (ROOTFILENAME FILENAME))
	   (VERSION (FILENAMEFIELD FILENAME (QUOTE VERSION)))
	   CONNECTION COURIERSTREAM SESSION HANDLE FILESTREAM ATTRS FULLNAME)
          [if [OR (NULL HOST)
		  (AND (NULL NAME)
		       (NEQ OPTION (QUOTE DIRECTORY]
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "BAD FILE NAME" FILENAME]
          (SETQ CONNECTION (\GETFILINGCONNECTION HOST))
          (if (EQ OPTION (QUOTE DIRECTORY))
	      then                                           (* Just return success or failure of attempt to follow 
							     the directories in the pathname.)
		   (RETURN (\NSFILING.CONNECT CONNECTION FILENAME)))
          [if (NOT (\NSFILING.CONNECT CONNECTION FILENAME))
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "FILE NOT FOUND" FILENAME]
          (SETQ COURIERSTREAM (fetch FC.COURIER.STREAM of CONNECTION))
          (SETQ SESSION (fetch FC.SESSION of CONNECTION))    (* Open appropriate version of file.
							     Note that explicit version overrides RECOG.
							     Is this right, or should conflicting VERSION and RECOG 
							     cause an error?)
          (SELECTQ ACCESS
		   ((INPUT NONE)
		     (SETQ HANDLE (COURIER.CALL COURIERSTREAM (QUOTE FILING)
						(QUOTE OPEN)
						[\WRITE.FILING.ATTRIBUTE.SEQUENCE
						  (BQUOTE ((NAME , NAME)
							   (VERSION , (OR VERSION
									  (SELECTQ RECOG
										   ((NIL OLD)
										     
									  \FILING.HIGHEST.VERSION)
										   (OLDEST 
									   \FILING.LOWEST.VERSION)
										   (LISPERROR 
										    "ILLEGAL ARG"
											      RECOG]
						(fetch FC.CURRENT.DIRECTORY of CONNECTION)
						NIL SESSION T)))
		   [OUTPUT [if [OR VERSION (MEMB RECOG (QUOTE (OLD OLD/NEW OLDEST]
			       then                          (* Try to open an existing file.)
				    (SETQ HANDLE
				      (COURIER.CALL
					COURIERSTREAM
					(QUOTE FILING)
					(QUOTE OPEN)
					[\WRITE.FILING.ATTRIBUTE.SEQUENCE
					  (BQUOTE ((NAME , NAME)
						   (VERSION , (OR VERSION (SELECTQ RECOG
										   ((OLD OLD/NEW)
										     
									  \FILING.HIGHEST.VERSION)
										   (OLDEST 
									   \FILING.LOWEST.VERSION)
										   (SHOULDNT]
					(fetch FC.CURRENT.DIRECTORY of CONNECTION)
					NIL SESSION T))
				    (if (AND (NULL HANDLE)
					     (NEQ RECOG (QUOTE OLD/NEW)))
					then (RETURN (AND (NOT NOERROR)
							  (LISPERROR "FILE NOT FOUND" FILENAME]
			   (if (NULL HANDLE)
			       then (if [NOT (MEMB RECOG (QUOTE (NIL NEW OLD/NEW]
					then (LISPERROR "ILLEGAL ARG" RECOG)
				      else                   (* Create a new file.)
					   (SETQ FILESTREAM (COURIER.CALL
					       COURIERSTREAM
					       (QUOTE FILING)
					       (QUOTE STORE)
					       (fetch FC.CURRENT.DIRECTORY of CONNECTION)
					       [\WRITE.FILING.ATTRIBUTE.SEQUENCE
						 (BQUOTE ((NAME , NAME]
					       NIL
					       (FUNCTION [LAMBDA (SUBSTREAM H)
						   (SETQ HANDLE H])
					       SESSION T))

          (* Write a file with a single byte in it so that we can get back the version number. Later we can do a REPLACE 
	  operation to write the user's data.)


					   (BOUT FILESTREAM 0)
					   (CLOSEF FILESTREAM) 
                                                             (* The FUNARG we passed to the STORE operation should 
							     have set HANDLE.)]
		   (LISPERROR "ILLEGAL ARG" ACCESS))
          [if (NULL HANDLE)
	      then (RETURN (AND (NOT NOERROR)
				(LISPERROR "FILE NOT FOUND" FILENAME]
          (SETQ ATTRS (\READ.FILING.ATTRIBUTE.SEQUENCE (COURIER.CALL COURIERSTREAM (QUOTE FILING)
								     (QUOTE GET.ATTRIBUTES)
								     HANDLE 
								     \FILING.ALL.ATTRIBUTE.TYPES 
								     SESSION)))
          [SETQ FULLNAME (\NSFILING.FULLNAME CONNECTION NAME (CADR (ASSOC (QUOTE VERSION)
									  ATTRS]
          [if OPTION
	      then (if (NEQ OPTION (QUOTE HANDLE))
		       then                                  (* Only the HANDLE option needs to keep it open.)
			    (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE))
		   (RETURN (SELECTQ OPTION
				    (NAME FULLNAME)
				    (HANDLE (CONS (LIST (QUOTE HANDLE)
							HANDLE)
						  ATTRS))
				    (ATTRIBUTES ATTRS)
				    (SHOULDNT]
          (SETQ FILESTREAM (SELECTQ ACCESS
				    (INPUT (COURIER.CALL COURIERSTREAM (QUOTE FILING)
							 (QUOTE RETRIEVE)
							 HANDLE NIL SESSION T))
				    (OUTPUT (COURIER.CALL COURIERSTREAM (QUOTE FILING)
							  (QUOTE REPLACE)
							  HANDLE NIL NIL SESSION T))
				    (LISPERROR "ILLEGAL ARG" ACCESS)))
          (if (NULL FILESTREAM)
	      then (LISPERROR "FILE NOT FOUND" FILENAME))
          (replace FULLFILENAME of FILESTREAM with FULLNAME)
          (replace NSFILING.CONNECTION of FILESTREAM with CONNECTION)
          (replace NSFILING.HANDLE of FILESTREAM with HANDLE)
          (replace NSFILING.ATTRIBUTES of FILESTREAM with ATTRS)
          (replace DEVICE of FILESTREAM with \NSFILING.DEVICE)
          (RETURN FILESTREAM])

(\NSFILING.CLOSEFILE
  [LAMBDA (FILESTREAM)                                       (* ecc "20-JUL-83 17:04")
    (PROG ((CONNECTION (fetch NSFILING.CONNECTION of FILESTREAM))
	   (HANDLE (fetch NSFILING.HANDLE of FILESTREAM)))
          (\BULK.DATA.CLOSE FILESTREAM)
          (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE)
          (replace NSFILING.HANDLE of FILESTREAM with NIL])

(\NSFILING.INTERNAL.CLOSE
  [LAMBDA (CONNECTION HANDLE)                                (* ecc "20-JUL-83 17:01")
                                                             (* Close the file with the given handle.)
    (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
		  (QUOTE FILING)
		  (QUOTE CLOSE)
		  HANDLE
		  (fetch FC.SESSION of CONNECTION])

(\NSFILING.FULLNAME
  [LAMBDA (CONNECTION FILENAME VERSION DIRECTORYFLG)         (* ecc "18-JUL-83 15:31")
    (SETQ FILENAME (PACKFILENAME (QUOTE HOST)
				 (fetch FC.FILESERVER of CONNECTION)
				 (QUOTE DIRECTORY)
				 (if DIRECTORYFLG
				     then (PACK* (\DIRECTORY.LIST.TO.PATHNAME (fetch FC.CURRENT.PATH
										 of CONNECTION))
						 FILENAME ">")
				   else (\DIRECTORY.LIST.TO.PATHNAME (fetch FC.CURRENT.PATH
									of CONNECTION)))
				 (QUOTE NAME)
				 (if (NOT DIRECTORYFLG)
				     then FILENAME)))
    (if VERSION
	then                                                 (* For aesthetic reasons, you might want this only if 
							     (AND VERSION (NOT DIRECTORYFLG)) but then DIR gets 
							     confused.)
	     (PACKFILENAME (QUOTE BODY)
			   FILENAME
			   (QUOTE VERSION)
			   VERSION)
      else FILENAME])

(\NSFILING.EVENTFN
  [LAMBDA (DEVICE EVENT)                                     (* ecc " 8-AUG-83 13:35")
    (SELECTQ EVENT
	     ((BEFORELOGOUT BEFOREMAKESYS BEFORESYSOUT)
	       (CLOSE.NSFILING.CONNECTIONS))
	     NIL])

(\NSFILING.DELETEFILE
  [LAMBDA (FILENAME DEVICE)                                  (* ecc " 1-AUG-83 14:38")
    (PROG ((ATTRS (\NSFILING.GETFILE FILENAME (QUOTE NONE)
				     (QUOTE OLDEST)
				     T
				     (QUOTE HANDLE)))
	   CONNECTION HANDLE)
          (RETURN (if ATTRS
		      then [SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD FILENAME
										 (QUOTE HOST]
			   (SETQ HANDLE (CADR (ASSOC (QUOTE HANDLE)
						     ATTRS)))
			   (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
					 (QUOTE FILING)
					 (QUOTE DELETE)
					 HANDLE
					 (fetch FC.SESSION of CONNECTION))
			   (\NSFILING.FULLNAME CONNECTION (CADR (ASSOC (QUOTE NAME)
								       ATTRS))
					       (CADR (ASSOC (QUOTE VERSION)
							    ATTRS))
					       (CADR (ASSOC (QUOTE IS.DIRECTORY)
							    ATTRS)))
		    else NIL])

(\NSFILING.HOSTNAMEP
  [LAMBDA (HOST DEVICE)                                      (* ecc "11-JUL-83 13:25")
    (if [NOT (AND (STRPOS ":" HOST)
		  (LOOKUP.NS.SERVER HOST (QUOTE FILESERVER]
	then                                                 (* To avoid useless lookups of PUP names, require 
							     Clearinghouse names to have a colon.)
	     NIL
      elseif (NULL DEVICE)
	then T
      else \NSFILING.DEVICE])

(\NSFILING.DIRECTORYNAMEP
  [LAMBDA (HOST/DIR)                                         (* ecc "22-JUN-83 13:33")
                                                             (* Returns T or NIL according to whether or not HOST/DIR
							     is a valid host/directory specification.)
    (\NSFILING.GETFILE HOST/DIR NIL NIL T (QUOTE DIRECTORY])

(\NSFILING.GETFILENAME
  [LAMBDA (NAME RECOG DEVICE)                                (* ecc "22-JUN-83 15:02")
                                                             (* Returns full file name of file or NIL if not found.)
    (\NSFILING.GETFILE NAME (QUOTE NONE)
		       RECOG T (QUOTE NAME])

(\NSFILING.GETFILEINFO
  [LAMBDA (STREAM ATTRIBUTE)                                 (* ecc "20-JUL-83 15:02")
    (PROG [(ATTRS (if (type? STREAM STREAM)
		      then (fetch NSFILING.ATTRIBUTES of STREAM)
		    else (\NSFILING.GETFILE STREAM (QUOTE NONE)
					    (QUOTE OLD)
					    T
					    (QUOTE ATTRIBUTES]
          (RETURN (SELECTQ ATTRIBUTE
			   (ALL ATTRS)
			   [WRITEDATE (GDATE (CADR (ASSOC (QUOTE MODIFIED.ON)
							  ATTRS]
			   [READDATE (GDATE (CADR (ASSOC (QUOTE READ.ON)
							 ATTRS]
			   [CREATIONDATE (GDATE (CADR (ASSOC (QUOTE CREATED.ON)
							     ATTRS]
			   (CADR (ASSOC (OR (CADR (ASSOC ATTRIBUTE LISP.TO.NS.FILE.ATTRIBUTES))
					    ATTRIBUTE)
					ATTRS])

(\NSFILING.SETFILEINFO
  [LAMBDA (STREAM ATTRIBUTE VALUE DEV)                       (* ecc " 8-AUG-83 14:20")
    (PROG (FILENAME HANDLE X CONNECTION)
          (if (SETQ X (ASSOC ATTRIBUTE LISP.TO.NS.FILE.ATTRIBUTES))
	      then (SETQ ATTRIBUTE (CADR X)))
          (SELECTQ ATTRIBUTE
		   [WRITEDATE (SETQ ATTRIBUTE (QUOTE MODIFIED.ON))
			      (SETQ VALUE (OR (IDATE VALUE)
					      (LISPERROR "ILLEGAL ARG" VALUE]
		   [READDATE (SETQ ATTRIBUTE (QUOTE READ.ON))
			     (SETQ VALUE (OR (IDATE VALUE)
					     (LISPERROR "ILLEGAL ARG" VALUE]
		   [CREATIONDATE (SETQ ATTRIBUTE (QUOTE CREATED.ON))
				 (SETQ VALUE (OR (IDATE VALUE)
						 (LISPERROR "ILLEGAL ARG" VALUE]
		   (if (NULL (ASSOC ATTRIBUTE \FILING.ATTRIBUTES))
		       then (LISPERROR "ILLEGAL ARG" ATTRIBUTE)))
          [if (type? STREAM STREAM)
	      then (SETQ FILENAME (fetch FULLFILENAME of STREAM))
		   [SETQ HANDLE (OR (fetch NSFILING.HANDLE of STREAM)
				    (CADR (ASSOC (QUOTE HANDLE)
						 (\NSFILING.GETFILE FILENAME (QUOTE NONE)
								    (QUOTE OLD)
								    T
								    (QUOTE HANDLE]
	    else (SETQ FILENAME STREAM)
		 (SETQ HANDLE (CADR (ASSOC (QUOTE HANDLE)
					   (\NSFILING.GETFILE FILENAME (QUOTE NONE)
							      (QUOTE OLD)
							      T
							      (QUOTE HANDLE]
          [SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD FILENAME (QUOTE HOST]
          (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
			(QUOTE FILING)
			(QUOTE CHANGE.ATTRIBUTES)
			HANDLE
			(\WRITE.FILING.ATTRIBUTE.SEQUENCE (LIST (LIST ATTRIBUTE VALUE)))
			(fetch FC.SESSION of CONNECTION))
          (if (type? STREAM STREAM)
	      then (replace NSFILING.ATTRIBUTES of STREAM with NIL) 
                                                             (* Set the attributes to NIL so that the next call to 
							     GETFILEINFO will go back to the fileserver for them.)
	    else (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE])

(\NSFILING.GENERATEFILES
  [LAMBDA (DEVICE PATTERN)                                   (* ecc " 3-AUG-83 16:14")
    (PROG ((HOST (FILENAMEFIELD PATTERN (QUOTE HOST)))
	   (NAME (ROOTFILENAME PATTERN))
	   (VERSION (FILENAMEFIELD PATTERN (QUOTE VERSION)))
	   CONNECTION FILELIST)
          (SETQ CONNECTION (\GETFILINGCONNECTION HOST))
          [SETQ FILELIST (if (NOT (\NSFILING.CONNECT CONNECTION PATTERN))
			     then NIL
			   elseif (STRPOS (QUOTE *)
					  NAME)
			     then                            (* Enumerate entire directory, matching against any wild
							     cards.)
				  (\NSFILING.LIST CONNECTION NAME)
			   elseif (OR (NULL VERSION)
				      (EQ VERSION (QUOTE *)))
			     then                            (* Only enumerate versions.)
				  (\NSFILING.LISTVERSIONS CONNECTION NAME)
			   else                              (* Full name was given; check existence.)
				(PROG ((F (\NSFILING.GETFILENAME PATTERN)))
				      (RETURN (AND F (LIST F]
          (RETURN (create FILEGENOBJ
			  NEXTFILEFN ←(FUNCTION \NSFILING.NEXTFILE)
			  GENFILESTATE ←(create \NSFILING.GENFILESTATE
						PATTERN ← PATTERN
						CONNECTION ← CONNECTION
						FILELIST ← FILELIST])

(\NSFILING.NEXTFILE
  [LAMBDA (GENFILESTATE SCRATCHLIST NOVERSION HOST/DIR)      (* ecc " 4-AUG-83 13:19")
    (PROG ((PATTERN (fetch PATTERN of GENFILESTATE))
	   (CONNECTION (fetch CONNECTION of GENFILESTATE))
	   (INFO (CAR (fetch FILELIST of GENFILESTATE)))
	   NAME)
          (replace FILELIST of GENFILESTATE with (CDR (fetch FILELIST of GENFILESTATE)))
          (if (NULL INFO)
	      then (RETURN NIL))
          [SETQ NAME (\NSFILING.FULLNAME CONNECTION (CADR (ASSOC (QUOTE NAME)
								 INFO))
					 (AND (NOT NOVERSION)
					      (CADR (ASSOC (QUOTE VERSION)
							   INFO)))
					 (CADR (ASSOC (QUOTE IS.DIRECTORY)
						      INFO]
          (RETURN (DCHCON (U-CASE (if (NOT HOST/DIR)
				      then (PACKFILENAME (QUOTE HOST)
							 NIL
							 (QUOTE DIRECTORY)
							 NIL
							 (QUOTE BODY)
							 NAME)
				    else NAME))
			  SCRATCHLIST])

(\NSFILING.GETEOFPTR
  [LAMBDA (STREAM)                                           (* ecc "25-JUL-83 13:47")
    (\NSFILING.GETFILEINFO STREAM (QUOTE LENGTH])
)
(\NSFILING.INIT)



(* Printer subset of Filing Protocol.)

[COURIERPROGRAM FILING.SUBSET.FOR.PRINTING (16 2)
		TYPES
		((ATTRIBUTE.SEQUENCE (FILING . ATTRIBUTE.SEQUENCE))
		 (ATTRIBUTE.TYPE.SEQUENCE (FILING . ATTRIBUTE.TYPE.SEQUENCE))
		 (CONTROL.SEQUENCE (FILING . CONTROL.SEQUENCE))
		 (CREDENTIALS (AUTHENTICATION . CREDENTIALS))
		 (HANDLE (FILING . HANDLE))
		 (SIMPLE.VERIFIER (AUTHENTICATION . SIMPLE.VERIFIER))
		 (SCOPE.SEQUENCE (FILING . SCOPE.SEQUENCE))
		 (SESSION (FILING . SESSION))
		 (VERIFIER (AUTHENTICATION . VERIFIER))
		 (ARGUMENT.PROBLEM (FILING . ARGUMENT.PROBLEM))
		 (ACCESS.PROBLEM (FILING . ACCESS.PROBLEM))
		 (HANDLE.PROBLEM (FILING . HANDLE.PROBLEM))
		 (INSERTION.PROBLEM (FILING . INSERTION.PROBLEM))
		 (SERVICE.PROBLEM (FILING . SERVICE.PROBLEM))
		 (SESSION.PROBLEM (FILING . SESSION.PROBLEM))
		 (SPACE.PROBLEM (FILING . SPACE.PROBLEM)))
		PROCEDURES
		((LOGON ARGS (CREDENTIALS VERIFIER)
			RESULTS
			(SESSION)
			ERRORS
			(AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			(FILING . LOGON))
		 (LOGOFF ARGS (SESSION)
			 ERRORS
			 (AUTHENTICATION.ERROR SERVICE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			 (FILING . LOGOFF))
		 (CONTINUE ARGS (SESSION)
			   RESULTS
			   (CARDINAL)
			   ERRORS
			   (AUTHENTICATION.ERROR SESSION.ERROR UNDEFINED.ERROR)
			   (FILING . CONTINUE))
		 (OPEN ARGS (ATTRIBUTE.SEQUENCE HANDLE CONTROL.SEQUENCE SESSION)
		       RESULTS
		       (HANDLE)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR HANDLE.ERROR 
				     SESSION.ERROR UNDEFINED.ERROR)
		       (FILING . OPEN))
		 (CLOSE ARGS (HANDLE SESSION)
			ERRORS
			(AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR UNDEFINED.ERROR)
			(FILING . CLOSE))
		 (DELETE ARGS (HANDLE SESSION)
			 ERRORS
			 (ACCESS.ERROR AUTHENTICATION.ERROR HANDLE.ERROR SESSION.ERROR 
				       UNDEFINED.ERROR)
			 (FILING . DELETE))
		 (STORE ARGS (HANDLE ATTRIBUTE.SEQUENCE CONTROL.SEQUENCE BULK.DATA.SOURCE SESSION)
			RESULTS
			(HANDLE)
			ERRORS
			(ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				      CONNECTION.ERROR CONTROL.TYPE.ERROR CONTROL.VALUE.ERROR 
				      HANDLE.ERROR INSERTION.ERROR SESSION.ERROR SPACE.ERROR 
				      TRANSFER.ERROR UNDEFINED.ERROR)
			(FILING . STORE))
		 (LIST ARGS (HANDLE ATTRIBUTE.TYPE.SEQUENCE SCOPE.SEQUENCE BULK.DATA.SINK SESSION)
		       ERRORS
		       (ACCESS.ERROR ATTRIBUTE.TYPE.ERROR ATTRIBUTE.VALUE.ERROR AUTHENTICATION.ERROR 
				     CONNECTION.ERROR HANDLE.ERROR SCOPE.TYPE.ERROR SCOPE.VALUE.ERROR 
				     SESSION.ERROR TRANSFER.ERROR UNDEFINED.ERROR)
		       (FILING . LIST)))
		ERRORS
		((ATTRIBUTE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
				       (FILING . ATTRIBUTE.TYPE.ERROR))
		 (ATTRIBUTE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM ATTRIBUTE.TYPE)
					(FILING . ATTRIBUTE.VALUE.ERROR))
		 (CONTROL.TYPE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
				     (FILING . CONTROL.TYPE.ERROR))
		 (CONTROL.VALUE.ERROR ARGS (ARGUMENT.PROBLEM CONTROL.TYPE)
				      (FILING . CONTROL.VALUE.ERROR))
		 (SCOPE.TYPE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
				   (FILING . SCOPE.TYPE.ERROR))
		 (SCOPE.VALUE.ERROR ARGS (ARGUMENT.PROBLEM SCOPE.TYPE)
				    (FILING . SCOPE.VALUE.ERROR))
		 (ACCESS.ERROR ARGS (ACCESS.PROBLEM)
			       (FILING . ACCESS.ERROR))
		 (AUTHENTICATION.ERROR ARGS ((AUTHENTICATION . PROBLEM))
				       (FILING . AUTHENTICATION.ERROR))
		 (CONNECTION.ERROR ARGS (CONNECTION.PROBLEM)
				   (FILING . CONNECTION.ERROR))
		 (HANDLE.ERROR ARGS (HANDLE.PROBLEM)
			       (FILING . HANDLE.ERROR))
		 (INSERTION.ERROR ARGS (INSERTION.PROBLEM)
				  (FILING . INSERTION.ERROR))
		 (SERVICE.ERROR ARGS (SERVICE.PROBLEM)
				(FILING . SERVICE.ERROR))
		 (SESSION.ERROR ARGS (SESSION.PROBLEM)
				(FILING . SESSION.ERROR))
		 (SPACE.ERROR ARGS (SPACE.PROBLEM)
			      (FILING . SPACE.ERROR))
		 (TRANSFER.ERROR ARGS (TRANSFER.PROBLEM)
				 (FILING . TRANSFER.ERROR))
		 (UNDEFINED.ERROR ARGS (CARDINAL)
				  (FILING . UNDEFINED.ERROR]



(* Lisp support.)

(DEFINEQ

(LIST.NSPRINTER.FILES
  [LAMBDA (PRINTSERVER)                                      (* ecc " 8-AUG-83 14:23")
    (PROG (STREAM SESSION LISTINGSTREAM SEQUENCE.OF.ATTRIBUTE.SEQUENCES)
          (SETQ STREAM (COURIER.OPEN PRINTSERVER (QUOTE PRINTSERVER)
				     NIL
				     (PACK* PRINTSERVER "#FILING")))
          (RETURN (RESETLST (RESETSAVE NIL (LIST [QUOTE (LAMBDA (X)
								(if RESETSTATE
								    then (SPP.CLOSE X T]
						 STREAM))
			    (bind CREDENTIALS MSG until SESSION
			       do (SETQ CREDENTIALS (NSLOGIN PRINTSERVER MSG))
				  (SETQ SESSION (COURIER.CALL
				      STREAM
				      (QUOTE FILING.SUBSET.FOR.PRINTING)
				      (QUOTE LOGON)
				      [BQUOTE ((TYPE 0)
					       (VALUE , (COURIER.WRITE.REP (PARSE.CH.NAME
									     (CAR CREDENTIALS))
									   (QUOTE AUTHENTICATION)
									   (QUOTE SIMPLE.CREDENTIALS]
				      (COURIER.WRITE.REP (HASH.PASSWORD (CDR CREDENTIALS))
							 (QUOTE FILING.SUBSET.FOR.PRINTING)
							 (QUOTE SIMPLE.VERIFIER))
				      T))
				  (SETQ MSG "Login incorrect."))
			    (RESETSAVE NIL (LIST (QUOTE [LAMBDA (X Y)
								(COURIER.CALL X (QUOTE 
								       FILING.SUBSET.FOR.PRINTING)
									      (QUOTE LOGOFF)
									      Y T])
						 STREAM SESSION))
			    (SETQ LISTINGSTREAM (COURIER.CALL STREAM (QUOTE 
								       FILING.SUBSET.FOR.PRINTING)
							      (QUOTE LIST)
							      \FILING.NULL.HANDLE
							      (\FILING.ATTRIBUTE.TYPE.SEQUENCE
								(QUOTE (NAME)))
							      NIL NIL SESSION))
			    (SETQ SEQUENCE.OF.ATTRIBUTE.SEQUENCES (COURIER.READ.BULKDATA
				LISTINGSTREAM
				(QUOTE FILING.SUBSET.FOR.PRINTING)
				(QUOTE ATTRIBUTE.SEQUENCE)))
			    (CLOSEF LISTINGSTREAM)
			    (for SEQ in SEQUENCE.OF.ATTRIBUTE.SEQUENCES
			       collect (CADR (ASSOC (QUOTE NAME)
						    (\READ.FILING.ATTRIBUTE.SEQUENCE SEQ])
)
(PUTPROPS NSFILING COPYRIGHT ("Xerox Corporation" 1983))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (33787 75571 (\NSFILING.LOGIN 33797 . 35872) (\NSFILING.LOGOUT 35874 . 36941) (
\NSFILING.LOGOUT.INTERNAL 36943 . 37545) (\NSFILING.CONNECT 37547 . 41203) (
\PATHNAME.TO.DIRECTORY.LIST 41205 . 41637) (\PATHNAME.TO.DIRECTORY.LIST.INTERNAL 41639 . 42047) (
\DIRECTORY.LIST.TO.PATHNAME 42049 . 42290) (\NSFILING.CREATE.DIRECTORY 42292 . 42910) (\NSFILING.LIST 
42912 . 44220) (\NSFILING.LISTVERSIONS 44222 . 45458) (\FILING.ATTRIBUTE.TYPE.SEQUENCE 45460 . 45674) 
(\FILING.ATTRIBUTE.TYPE 45676 . 45970) (\READ.FILING.ATTRIBUTE.SEQUENCE 45972 . 46409) (
\READ.FILING.ATTRIBUTE 46411 . 47088) (\WRITE.FILING.ATTRIBUTE.SEQUENCE 47090 . 47530) (
\WRITE.FILING.ATTRIBUTE 47532 . 48120) (NSDIRECTORY 48122 . 48800) (NSCREATEDIRECTORY 48802 . 49578) (
\NSFILING.INIT 49580 . 50571) (\GETFILINGCONNECTION 50573 . 51667) (\VALID.FILING.CONNECTIONP 51669 . 
53542) (\LOGGED.ONTO.NSFILESERVERP 53544 . 54032) (CLOSE.NSFILING.CONNECTIONS 54034 . 54511) (
\NSFILING.OPENFILE 54513 . 54684) (\NSFILING.GETFILE 54686 . 60687) (\NSFILING.ORIGINAL.GETFILE 60689
 . 66400) (\NSFILING.CLOSEFILE 66402 . 66822) (\NSFILING.INTERNAL.CLOSE 66824 . 67211) (
\NSFILING.FULLNAME 67213 . 68137) (\NSFILING.EVENTFN 68139 . 68374) (\NSFILING.DELETEFILE 68376 . 
69254) (\NSFILING.HOSTNAMEP 69256 . 69711) (\NSFILING.DIRECTORYNAMEP 69713 . 70078) (
\NSFILING.GETFILENAME 70080 . 70394) (\NSFILING.GETFILEINFO 70396 . 71127) (\NSFILING.SETFILEINFO 
71129 . 73182) (\NSFILING.GENERATEFILES 73184 . 74452) (\NSFILING.NEXTFILE 74454 . 75398) (
\NSFILING.GETEOFPTR 75400 . 75569)) (79692 81587 (LIST.NSPRINTER.FILES 79702 . 81585)))))
STOP