(FILECREATED "12-Dec-83 15:40:21" {PHYLUM}<LISPCORE>SOURCES>NSFILING.;13 63847  

      changes to:  (FNS \NSFILING.GETFILEINFO \NSFILING.GETFILEINFO.FROM.PLIST)
		   (VARS NSFILINGCOMS)

      previous date: "17-NOV-83 17:38:21" {PHYLUM}<LISPCORE>SOURCES>NSFILING.;12)


(* Copyright (c) 1983 by Xerox Corporation)

(PRETTYCOMPRINT NSFILINGCOMS)

(RPAQQ NSFILINGCOMS ((COMS (DECLARE: DONTCOPY EVAL@COMPILE (FILES (LOADCOMP)
								  SPP FILEIO)))
	(COMS (* Filing Protocol.)
	      (COURIERPROGRAMS FILING)
	      (DECLARE: DONTCOPY (CONSTANTS * NSFILINGCONSTANTS)
			(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.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 \OPENFILINGCONNECTION 
		   \CLOSEFILINGCONNECTION \NSFILING.RESETCLOSE \VALID.FILING.CONNECTIONP 
		   \LOGGED.ONTO.NSFILESERVERP CLOSE.NSFILING.CONNECTIONS \NSFILING.OPENFILE 
		   \NSFILING.GETFILE \NSFILING.OPENFILE.OPTIONS \NSFILING.CLOSEFILE 
		   \NSFILING.INTERNAL.CLOSE \NSFILING.FULLNAME \NSFILING.EVENTFN \NSFILING.DELETEFILE 
		   \NSFILING.HOSTNAMEP \NSFILING.DIRECTORYNAMEP \NSFILING.GETFILENAME 
		   \NSFILING.GETFILEINFO \NSFILING.GETFILEINFO.FROM.PLIST \NSFILING.SETFILEINFO 
		   \LISP.TO.NSFILING.ATTRIBUTE \NSFILING.GENERATEFILES \NSFILING.NEXTFILE 
		   \NSFILING.GETEOFPTR)
	      (P (\NSFILING.INIT)))
	(COMS (* Printer subset of Filing Protocol.)
	      (COURIERPROGRAMS FILING.SUBSET.FOR.PRINTING)
	      (FNS LIST.NSPRINTER.FILES))))
(DECLARE: DONTCOPY EVAL@COMPILE 
(FILESLOAD (LOADCOMP)
	   SPP FILEIO)
)



(* 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)))
(DECLARE: DONTCOPY 

(RPAQQ NSFILINGCONSTANTS [(\NSFILING.ALL.ATTRIBUTE.TYPES (QUOTE (-1)))
			  (\NSFILING.DEFAULT.TIMEOUT -1)
			  (\FILING.UNLIMITED.COUNT -1)
			  (\NSFILING.NULL.FILTER (QUOTE (ALL)))
			  (\NSFILING.NULL.HANDLE (QUOTE (0 0)))
			  (\NSFILING.NULL.FILE.ID (QUOTE (0 0 0 0 0)))
			  (\NSFILING.LOWEST.VERSION 0)
			  (\NSFILING.HIGHEST.VERSION -1)
			  [\NSFILING.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]
			  [\NSFILING.USEFUL.ATTRIBUTE.TYPES (\FILING.ATTRIBUTE.TYPE.SEQUENCE
							      (QUOTE (CREATED.ON FILE.ID IS.DIRECTORY 
										 MODIFIED.ON NAME 
										 READ.ON 
										 SIZE.IN.BYTES 
										 VERSION]
			  (\LISP.TO.NSFILING.ATTRIBUTES (QUOTE ((IWRITEDATE MODIFIED.ON)
								(IREADDATE READ.ON)
								(ICREATIONDATE CREATED.ON)
								(LENGTH SIZE.IN.BYTES])
(DECLARE: EVAL@COMPILE 

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

(RPAQQ \NSFILING.DEFAULT.TIMEOUT -1)

(RPAQQ \FILING.UNLIMITED.COUNT -1)

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

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

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

(RPAQQ \NSFILING.LOWEST.VERSION 0)

(RPAQQ \NSFILING.HIGHEST.VERSION -1)

(RPAQQ \NSFILING.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)))

(RPAQ \NSFILING.USEFUL.ATTRIBUTE.TYPES (\FILING.ATTRIBUTE.TYPE.SEQUENCE (QUOTE (CREATED.ON FILE.ID 
										     IS.DIRECTORY 
										      MODIFIED.ON 
											   NAME 
											  READ.ON 
										    SIZE.IN.BYTES 
											  VERSION))))

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

[CONSTANTS (\NSFILING.ALL.ATTRIBUTE.TYPES (QUOTE (-1)))
	   (\NSFILING.DEFAULT.TIMEOUT -1)
	   (\FILING.UNLIMITED.COUNT -1)
	   (\NSFILING.NULL.FILTER (QUOTE (ALL)))
	   (\NSFILING.NULL.HANDLE (QUOTE (0 0)))
	   (\NSFILING.NULL.FILE.ID (QUOTE (0 0 0 0 0)))
	   (\NSFILING.LOWEST.VERSION 0)
	   (\NSFILING.HIGHEST.VERSION -1)
	   [\NSFILING.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]
	   [\NSFILING.USEFUL.ATTRIBUTE.TYPES (\FILING.ATTRIBUTE.TYPE.SEQUENCE (QUOTE (CREATED.ON
										       FILE.ID 
										     IS.DIRECTORY 
										      MODIFIED.ON 
										       NAME READ.ON 
										    SIZE.IN.BYTES 
										       VERSION]
	   (\LISP.TO.NSFILING.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.)
					   FC.CACHED.ATTRIBUTES
                                                             (* Attributes from last lookup.)
					   FC.BUSY           (* This connection is in use.)
					   ))

(RECORD \NSFILING.GENFILESTATE (PATTERN CONNECTION FILELIST))
]
(/DECLAREDATATYPE (QUOTE FILING.CONNECTION)
		  (QUOTE (POINTER POINTER 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 POINTER POINTER)))

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

(RPAQ? \NSFILING.CONNECTIONS NIL)
(DEFINEQ

(\NSFILING.LOGIN
  [LAMBDA (FILESERVER)                                       (* bvm: "16-NOV-83 15:26")
    (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* (CH.NAME.TO.STRING FILESERVER)
							    " Filing")))
			  (RESETSAVE NIL (LIST (FUNCTION \SPP.CLOSE.IF.ERROR)
					       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)))
			  (COND
			    ((AND SESSION (EQ (CAR SESSION)
					      (QUOTE ERROR))
				  (EQ (CADR SESSION)
				      (QUOTE AUTHENTICATION.ERROR)))
			      (SETQ SESSION NIL)
			      (SETQ MSG "Login incorrect.")
			      (SPP.CLOSE STREAM]
		    [COND
		      ((EQ (CAR SESSION)
			   (QUOTE ERROR))
			(ERROR (CONCAT "Error while logging on to " (CH.NAME.TO.STRING FILESERVER))
			       (CDR SESSION]
		    [SETQ CONNECTION
		      (create FILING.CONNECTION
			      FC.FILESERVER ← FILESERVER
			      FC.COURIER.STREAM ← STREAM
			      FC.SESSION ← SESSION
			      FC.CURRENT.DIRECTORY ← \NSFILING.NULL.HANDLE
			      FC.BUSY ← T
			      FC.CONTINUANCE ←(SETUPTIMER (LRSH (COURIER.CALL STREAM (QUOTE FILING)
									      (QUOTE CONTINUE)
									      SESSION)
								1)
							  NIL
							  (QUOTE SECONDS]
		    (\NSFILING.CONNECT CONNECTION)           (* Connect to the root directory of the fileserver.)
		    (RETURN CONNECTION])

(\NSFILING.LOGOUT
  [LAMBDA (CONNECTION ABORT?)                                (* bvm: "16-NOV-83 17:16")
    (NLSETQ (RESETLST (RESETSAVE NIL (LIST [FUNCTION (LAMBDA (X)
					       (SETQ \NSFILING.CONNECTIONS (DREMOVE X 
									    \NSFILING.CONNECTIONS]
					   CONNECTION))
		      (COND
			([NOT (OR ABORT? (TIMEREXPIRED? (fetch FC.CONTINUANCE of CONNECTION)
							(QUOTE SECONDS))
				  (NULL (\OPENFILINGCONNECTION CONNECTION]
			  (RESETSAVE NIL (LIST (FUNCTION \NSFILING.RESETCLOSE)
					       CONNECTION))
			  (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
					(QUOTE FILING)
					(QUOTE LOGOFF)
					(fetch FC.SESSION of CONNECTION)
					T])

(\NSFILING.CONNECT
  [LAMBDA (CONNECTION PATHNAME)                              (* bvm: "17-NOV-83 15:50")

          (* 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)
          (COND
	    ((AND NEW.DIRLIST (EQUAL NEW.DIRLIST OLD.DIRLIST))
                                                             (* Nothing needs to be done because we're already 
							     connected to this path.)
	      (RETURN T)))
          (COND
	    ([AND (SETQ ADDITIONAL.DIRLIST NEW.DIRLIST)
		  (for OLD.DIR in OLD.DIRLIST always (EQ OLD.DIR (pop ADDITIONAL.DIRLIST]
                                                             (* We're currently connected to a prefix of the desired 
							     path, so we can save some remote calls.)
	      (SETQ NEW.DIRLIST ADDITIONAL.DIRLIST))
	    (T 

          (* 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.)


	       [COND
		 ((NOT (EQUAL (fetch FC.CURRENT.DIRECTORY of CONNECTION)
			      \NSFILING.NULL.HANDLE))
		   (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 
									    \NSFILING.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))
		(COND
		  ((NULL NEW.HANDLE)
		    (SETQ FAILURE T)
		    (RETURN)))
		[COND
		  ((NOT (EQUAL OLD.HANDLE \NSFILING.NULL.HANDLE))
		    (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)                                          (* bvm: "16-NOV-83 15:30")
    (PACK (CONS (QUOTE <)
		(OR (for DIR in DIRLIST join (LIST DIR (QUOTE >)))
		    (LIST (QUOTE >])

(\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 "16-AUG-83 16:38")
                                                             (* 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)
				     \NSFILING.USEFUL.ATTRIBUTE.TYPES
				     (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)                              (* bvm: "17-NOV-83 17:10")
                                                             (* 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)
				     \NSFILING.USEFUL.ATTRIBUTE.TYPES
				     [AND (NEQ (NCHARS FILENAME)
					       0)
					  (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 "18-AUG-83 16:26")
    (for X in \NSFILING.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 "18-AUG-83 16:26")
                                                             (* 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 \NSFILING.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 "18-AUG-83 16:26")
                                                             (* Return a Courier ATTRIBUTE corresponding to the 
							     specified type and value.)
    (for X in \NSFILING.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)                                          (* bvm: "16-NOV-83 17:17")
    (PROG (HOST CONNECTION LST)
          [SETQ PATTERN (\ADD.CONNECTED.DIR (OR PATTERN (QUOTE *]
          (SETQ HOST (FILENAMEFIELD PATTERN (QUOTE HOST)))
          [RESETLST (SETQ CONNECTION (\GETFILINGCONNECTION HOST T))
		    (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)                                         (* bvm: "16-NOV-83 17:17")
    (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)))
          (COND
	    ([NOT (AND (SETQ ALL.BUT.LAST.DIR (REVERSE (CDR REVERSE.DIRLIST)))
		       (SETQ LAST.DIR (CAR REVERSE.DIRLIST]
	      (LISPERROR "BAD FILE NAME" HOST/DIR)))
          (RESETLST (SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD HOST/DIR (QUOTE HOST))
							   T))
		    (\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 DORESETSAVE)                           (* bvm: "16-NOV-83 17:15")
                                                             (* Find an existing connection to this fileserver or log
							     in a new one.)
    (SETQ FILESERVER (PARSE.CH.NAME FILESERVER))
    (PROG (CONNECTION)
          [SETQ CONNECTION (WITH.MONITOR \NSFILING.LOCK
					 (COND
					   [(bind (TAIL ← \NSFILING.CONNECTIONS)
						  CONNECTION while TAIL
					       do            (* This control structure needed because 
							     \VALID.FILING.CONNECTIONP might call DREMOVE on 
							     \NSFILING.CONNECTIONS)
						  (SETQ CONNECTION (CAR TAIL))
						  (SETQ TAIL (CDR TAIL))
						  (COND
						    ((AND (NOT (fetch FC.BUSY of CONNECTION))
							  (EQUAL.CH.NAMES (fetch FC.FILESERVER
									     of CONNECTION)
									  FILESERVER)
							  (\VALID.FILING.CONNECTIONP CONNECTION))
						      (RETURN CONNECTION]
					   (T (PROG ((CONNECTION (\NSFILING.LOGIN FILESERVER)))
						    (push \NSFILING.CONNECTIONS CONNECTION)
						    (RETURN CONNECTION]
          [COND
	    (DORESETSAVE (RESETSAVE NIL (LIST (FUNCTION \NSFILING.RESETCLOSE)
					      CONNECTION]
          (RETURN CONNECTION])

(\OPENFILINGCONNECTION
  [LAMBDA (CONNECTION)                                       (* ecc "31-AUG-83 11:29")
                                                             (* Open a Courier stream to the fileserver for this 
							     connection, and mark the connection busy.
							     Returns T or NIL on success or failure.)
    (PROG ((FILESERVER (fetch FC.FILESERVER of CONNECTION))
	   STREAM)
          (SPP.CLOSE (fetch FC.COURIER.STREAM of CONNECTION)
		     T)
          [replace FC.COURIER.STREAM of CONNECTION with (SETQ STREAM (COURIER.OPEN
							    FILESERVER
							    (QUOTE FILESERVER)
							    T
							    (PACK* (CH.NAME.TO.STRING FILESERVER)
								   " Filing"]
          (RETURN (if STREAM
		      then (replace FC.CONTINUANCE of CONNECTION
			      with (SETUPTIMER (LRSH (COURIER.CALL STREAM (QUOTE FILING)
								   (QUOTE CONTINUE)
								   (fetch FC.SESSION of CONNECTION))
						     1)
					       (fetch FC.CONTINUANCE of CONNECTION)
					       (QUOTE SECONDS)))
                                                             (* Be conservative and use half the time limit.)
			   (replace FC.BUSY of CONNECTION with T])

(\CLOSEFILINGCONNECTION
  [LAMBDA (CONNECTION ABORT?)                                (* ecc "29-AUG-83 17:26")
    (PROG ((STREAM (fetch FC.COURIER.STREAM of CONNECTION)))
          (replace FC.COURIER.STREAM of CONNECTION with NIL)
          (SPP.CLOSE STREAM ABORT?)
          (replace FC.BUSY of CONNECTION with NIL])

(\NSFILING.RESETCLOSE
  [LAMBDA (X)                                                (* bvm: "16-NOV-83 17:11")
    (\CLOSEFILINGCONNECTION X RESETSTATE])

(\VALID.FILING.CONNECTIONP
  [LAMBDA (CONNECTION)                                       (* ecc "31-AUG-83 11:27")
                                                             (* Determine if this is a usable NS Filing connection.
							     If it's dead for some reason, remove it from the list.)
    (PROG NIL
          (if (NOT (\LOGGED.ONTO.NSFILESERVERP CONNECTION))
	      then                                           (* The user is logged in under a different name.)
		   (RETURN NIL)
	    elseif (TIMEREXPIRED? (fetch FC.CONTINUANCE of CONNECTION)
				  (QUOTE SECONDS))
	      then                                           (* This connection has timed out.)
		   (GO REMOVEIT)
	    elseif (NOT (\OPENFILINGCONNECTION CONNECTION))
	      then                                           (* We couldn't reconnect.)
		   (GO REMOVEIT)
	    else (RETURN T))
      REMOVEIT
          (SETQ \NSFILING.CONNECTIONS (DREMOVE CONNECTION \NSFILING.CONNECTIONS))
          (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 (ABORT?)                                           (* ecc "24-AUG-83 17:15")
    (WITH.MONITOR \NSFILING.LOCK (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 ABORT?])

(\NSFILING.OPENFILE
  [LAMBDA (FILENAME ACCESS RECOG PARAMETERS)                 (* bvm: "17-NOV-83 15:38")
    (\NSFILING.GETFILE FILENAME ACCESS RECOG T NIL PARAMETERS])

(\NSFILING.GETFILE
  [LAMBDA (FILENAME ACCESS RECOG NOERROR OPTION PARAMETERS)
                                                             (* bvm: "17-NOV-83 17:25")

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


    (RESETLST (PROG ((HOST (FILENAMEFIELD FILENAME (QUOTE HOST)))
		     (NAME (ROOTFILENAME FILENAME))
		     (VERSION (FILENAMEFIELD FILENAME (QUOTE VERSION)))
		     (HIGHEST.VERSION 0)
		     (LOWEST.VERSION 65535)
		     CONNECTION CACHE DESIRED.INFO LOWEST.VERSION.INFO HIGHEST.VERSION.INFO FILE.ID 
		     COURIERSTREAM SESSION HANDLE FILESTREAM FULLNAME)
		    [COND
		      ([OR (NULL HOST)
			   (AND (NULL NAME)
				(NEQ OPTION (QUOTE DIRECTORY]
			(RETURN (AND (NOT NOERROR)
				     (LISPERROR "BAD FILE NAME" FILENAME]
		    (SETQ CONNECTION (\GETFILINGCONNECTION HOST))
		    [COND
		      (OPTION                                (* Not going to really open the file, so close it on 
							     exit)
			      (RESETSAVE NIL (LIST (FUNCTION \NSFILING.RESETCLOSE)
						   CONNECTION]
		    [COND
		      ((EQ OPTION (QUOTE DIRECTORY))         (* Just return success or failure of attempt to follow 
							     the directories in the pathname.)
			(RETURN (\NSFILING.CONNECT CONNECTION FILENAME]
		    [COND
		      ((NOT (\NSFILING.CONNECT CONNECTION FILENAME))
			(RETURN (AND (NOT NOERROR)
				     (LISPERROR "FILE NOT FOUND" FILENAME]
		    (SETQ CACHE (fetch FC.CACHED.ATTRIBUTES of CONNECTION))
		    [COND
		      ([AND (EQ (\NSFILING.FULLNAME CONNECTION NAME VERSION)
				(CADR (ASSOC (QUOTE FULLNAME)
					     CACHE)))
			    (SETQ FILE.ID (CADR (ASSOC (QUOTE FILE.ID)
						       CACHE]
                                                             (* Cache hit.)
			(SETQ DESIRED.INFO CACHE))
		      ([bind V for ALST in (\NSFILING.LISTVERSIONS CONNECTION NAME)
			  do 

          (* 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.)


			     (SETQ V (CADR (ASSOC (QUOTE VERSION)
						  ALST)))
			     [COND
			       ((AND VERSION (IEQP V VERSION))
				 (RETURN (SETQ DESIRED.INFO ALST]
			     (COND
			       ((ILESSP V LOWEST.VERSION)
				 (SETQ LOWEST.VERSION V)
				 (SETQ LOWEST.VERSION.INFO ALST)))
			     (COND
			       ((IGREATERP V HIGHEST.VERSION)
				 (SETQ HIGHEST.VERSION V)
				 (SETQ HIGHEST.VERSION.INFO ALST)))
			  finally (RETURN (AND (NOT VERSION)
					       (SETQ DESIRED.INFO
						 (SELECTQ 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)
							  (\ILLEGAL.ARG RECOG]

          (* 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)
						   DESIRED.INFO]
		    [COND
		      ((AND DESIRED.INFO OPTION (NEQ OPTION (QUOTE HANDLE)))
                                                             (* We don't need to open the file.)
			[SETQ FULLNAME (\NSFILING.FULLNAME CONNECTION NAME
							   (CADR (ASSOC (QUOTE VERSION)
									DESIRED.INFO]
			[replace FC.CACHED.ATTRIBUTES of CONNECTION
			   with (COND
				  ((CADR (ASSOC (QUOTE FULLNAME)
						DESIRED.INFO))
				    DESIRED.INFO)
				  (T (CONS (BQUOTE (FULLNAME , FULLNAME))
					   DESIRED.INFO]
			(RETURN (SELECTQ OPTION
					 (NAME FULLNAME)
					 (ATTRIBUTES DESIRED.INFO)
					 (SHOULDNT]
		    (SETQ COURIERSTREAM (fetch FC.COURIER.STREAM of CONNECTION))
		    (SETQ SESSION (fetch FC.SESSION of CONNECTION))
                                                             (* We need to get an open file handle for the file.)
		    [COND
		      (FILE.ID                               (* 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)))
		      ([AND (EQ ACCESS (QUOTE OUTPUT))
			    (MEMB RECOG (QUOTE (NIL NEW OLD/NEW]
                                                             (* Create a new file.)
			(SETQ FILESTREAM (COURIER.CALL COURIERSTREAM (QUOTE FILING)
						       (QUOTE STORE)
						       (fetch FC.CURRENT.DIRECTORY of CONNECTION)
						       (\NSFILING.OPENFILE.OPTIONS
							 (BQUOTE ((NAME , NAME)
								  (VERSION , VERSION)
								  ,@ PARAMETERS)))
						       NIL
						       (FUNCTION [LAMBDA (SUBSTREAM FILEHANDLE)
							   (replace NSFILING.HANDLE of SUBSTREAM
							      with FILEHANDLE])
						       SESSION T]
		    [COND
		      ((AND (NULL HANDLE)
			    (NULL FILESTREAM))
			(RETURN (AND (NOT NOERROR)
				     (LISPERROR "FILE NOT FOUND" FILENAME]
		    [COND
		      ((AND HANDLE (NULL DESIRED.INFO))
			(SETQ DESIRED.INFO (\READ.FILING.ATTRIBUTE.SEQUENCE (COURIER.CALL
									      COURIERSTREAM
									      (QUOTE FILING)
									      (QUOTE GET.ATTRIBUTES)
									      HANDLE 
								 \NSFILING.USEFUL.ATTRIBUTE.TYPES 
									      SESSION]
		    (SETQ FULLNAME (\NSFILING.FULLNAME CONNECTION NAME VERSION))
		    [replace FC.CACHED.ATTRIBUTES of CONNECTION
		       with (COND
			      ((CADR (ASSOC (QUOTE FULLNAME)
					    DESIRED.INFO))
				DESIRED.INFO)
			      (T (CONS (BQUOTE (FULLNAME , FULLNAME))
				       DESIRED.INFO]
		    [COND
		      (OPTION (COND
				((NEQ OPTION (QUOTE HANDLE))
                                                             (* Only the HANDLE option needs to keep it open.)
				  (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE)))
			      (RETURN (SELECTQ OPTION
					       (NAME FULLNAME)
					       (ATTRIBUTES DESIRED.INFO)
					       (HANDLE (CONS (BQUOTE (HANDLE , HANDLE))
							     DESIRED.INFO))
					       (SHOULDNT]
		    (SETQ FILESTREAM (SELECTQ ACCESS
					      (INPUT (COURIER.CALL COURIERSTREAM (QUOTE FILING)
								   (QUOTE RETRIEVE)
								   HANDLE NIL SESSION T))
					      (OUTPUT (OR FILESTREAM (COURIER.CALL COURIERSTREAM
										   (QUOTE FILING)
										   (QUOTE REPLACE)
										   HANDLE NIL NIL 
										   SESSION T)))
					      (LISPERROR "ILLEGAL ARG" ACCESS)))
		    (COND
		      ((NULL FILESTREAM)
			(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 DESIRED.INFO)
		    (replace DEVICE of FILESTREAM with \NSFILING.DEVICE)
		    (RETURN FILESTREAM])

(\NSFILING.OPENFILE.OPTIONS
  [LAMBDA (ALIST)                                            (* bvm: "17-NOV-83 16:10")
    (for PAIR in ALIST bind ATTR/VAL when [AND (LISTP PAIR)
					       (SETQ ATTR/VAL (\LISP.TO.NSFILING.ATTRIBUTE
						   (CAR PAIR)
						   (CADR PAIR]
       collect ATTR/VAL])

(\NSFILING.CLOSEFILE
  [LAMBDA (FILESTREAM)                                       (* bvm: "16-NOV-83 17:12")
    (RESETLST (PROG (HANDLE CONNECTION)
		    (\BULK.DATA.CLOSE FILESTREAM)

          (* NOTE: As a side effect, this call may set the NSFILING.HANDLE of the stream. This happens when we're creating a
	  new file; see the FUNARG passed to the STORE call in \NSFILING.GETFILE)


		    (SETQ HANDLE (fetch NSFILING.HANDLE of FILESTREAM))
		    (SETQ CONNECTION (fetch NSFILING.CONNECTION of FILESTREAM))
		    (COND
		      ((AND HANDLE CONNECTION (\ACTIVE.SPP.STREAMP (fetch FC.COURIER.STREAM
								      of CONNECTION)))
			(RESETSAVE NIL (LIST (FUNCTION \NSFILING.RESETCLOSE)
					     CONNECTION))
			(\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE)
			(replace NSFILING.HANDLE of FILESTREAM with NIL])

(\NSFILING.INTERNAL.CLOSE
  [LAMBDA (CONNECTION HANDLE)                                (* ecc "29-AUG-83 14:50")
                                                             (* 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)
		  T])

(\NSFILING.FULLNAME
  [LAMBDA (CONNECTION FILENAME VERSION DIRECTORYFLG)         (* bvm: "16-NOV-83 15:27")
    [SETQ FILENAME (PACKFILENAME (QUOTE HOST)
				 (CH.NAME.TO.STRING (fetch FC.FILESERVER of CONNECTION)
						    T)
				 (QUOTE DIRECTORY)
				 [COND
				   (DIRECTORYFLG (CONCAT (\DIRECTORY.LIST.TO.PATHNAME (fetch 
										  FC.CURRENT.PATH
											 of 
										       CONNECTION))
							 FILENAME ">"))
				   (T (\DIRECTORY.LIST.TO.PATHNAME (fetch FC.CURRENT.PATH
								      of CONNECTION]
				 (QUOTE NAME)
				 (COND
				   ((NOT DIRECTORYFLG)
				     FILENAME]
    (COND
      (VERSION                                               (* 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))
      (T FILENAME])

(\NSFILING.EVENTFN
  [LAMBDA (DEVICE EVENT)                                     (* bvm: "17-NOV-83 14:36")
    (SELECTQ EVENT
	     (BEFORELOGOUT (CLOSE.NSFILING.CONNECTIONS T))
	     ((AFTERLOGOUT AFTERSAVEVM AFTERMAKESYS AFTERSYSOUT)
	       (\REMOVEDEVICE.NAMES DEVICE))
	     NIL])

(\NSFILING.DELETEFILE
  [LAMBDA (FILENAME DEVICE)                                  (* bvm: "16-NOV-83 17:17")
    (PROG ((ATTRS (\NSFILING.GETFILE FILENAME (QUOTE NONE)
				     (QUOTE OLDEST)
				     T
				     (QUOTE HANDLE)))
	   CONNECTION)
          (RETURN (COND
		    (ATTRS (RESETLST (SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD
									      FILENAME
									      (QUOTE HOST))
									    T))
				     (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
						   (QUOTE FILING)
						   (QUOTE DELETE)
						   (CADR (ASSOC (QUOTE HANDLE)
								ATTRS))
						   (fetch FC.SESSION of CONNECTION)))
			   (\NSFILING.FULLNAME CONNECTION (CADR (ASSOC (QUOTE NAME)
								       ATTRS))
					       (CADR (ASSOC (QUOTE VERSION)
							    ATTRS))
					       (CADR (ASSOC (QUOTE IS.DIRECTORY)
							    ATTRS])

(\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 "18-AUG-83 16:09")
                                                             (* Returns T or NIL according to whether or not HOST/DIR
							     is a valid host/directory specification.)
    (\NSFILING.GETFILE HOST/DIR (QUOTE NONE)
		       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)                                 (* bvm: "12-Dec-83 15:21")
    (COND
      [(EQ ATTRIBUTE (QUOTE ALL))
	(RESETLST (PROG (ATTRS CONNECTION)
		        [SETQ ATTRS (COND
			    ((type? STREAM STREAM)
			      (fetch NSFILING.ATTRIBUTES of STREAM))
			    (T (\NSFILING.GETFILE STREAM (QUOTE NONE)
						  (QUOTE OLD)
						  T
						  (QUOTE HANDLE]
		        (SETQ CONNECTION (\GETFILINGCONNECTION (FILENAMEFIELD (COND
										((type? STREAM STREAM)
										  (fetch FULLFILENAME
										     of STREAM))
										(T STREAM))
									      (QUOTE HOST))
							       T))
		        (RETURN (PROG1 (\READ.FILING.ATTRIBUTE.SEQUENCE
					 (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
						       (QUOTE FILING)
						       (QUOTE GET.ATTRIBUTES)
						       (CADR (ASSOC (QUOTE HANDLE)
								    ATTRS))
						       \NSFILING.ALL.ATTRIBUTE.TYPES
						       (fetch FC.SESSION of CONNECTION)))
				       (\NSFILING.INTERNAL.CLOSE CONNECTION
								 (CADR (ASSOC (QUOTE HANDLE)
									      ATTRS]
      (T (\NSFILING.GETFILEINFO.FROM.PLIST [COND
					     ((type? STREAM STREAM)
					       (fetch NSFILING.ATTRIBUTES of STREAM))
					     (T (\NSFILING.GETFILE STREAM (QUOTE NONE)
								   (QUOTE OLD)
								   T
								   (QUOTE ATTRIBUTES]
					   ATTRIBUTE])

(\NSFILING.GETFILEINFO.FROM.PLIST
  [LAMBDA (PLIST ATTRIBUTE)                                  (* bvm: "12-Dec-83 15:31")
    (COND
      (PLIST (SELECTQ ATTRIBUTE
		      [WRITEDATE (GDATE (CADR (ASSOC (QUOTE MODIFIED.ON)
						     PLIST]
		      [READDATE (GDATE (CADR (ASSOC (QUOTE READ.ON)
						    PLIST]
		      [CREATIONDATE (GDATE (CADR (ASSOC (QUOTE CREATED.ON)
							PLIST]
		      (CADR (ASSOC (OR (CADR (ASSOC ATTRIBUTE \LISP.TO.NSFILING.ATTRIBUTES))
				       ATTRIBUTE)
				   PLIST])

(\NSFILING.SETFILEINFO
  [LAMBDA (STREAM ATTRIBUTE VALUE DEV)                       (* bvm: "17-NOV-83 16:09")
    (RESETLST (PROG ((ATTR/VAL (\LISP.TO.NSFILING.ATTRIBUTE ATTRIBUTE VALUE))
		     FILENAME HANDLE CONNECTION)
		    [COND
		      ((NULL ATTR/VAL)                       (* Unsupported attribute)
			(RETURN))
		      [(type? STREAM STREAM)
			(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]
		      (T (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))
							   T))
		    (COURIER.CALL (fetch FC.COURIER.STREAM of CONNECTION)
				  (QUOTE FILING)
				  (QUOTE CHANGE.ATTRIBUTES)
				  HANDLE
				  (\WRITE.FILING.ATTRIBUTE.SEQUENCE (LIST ATTR/VAL))
				  (fetch FC.SESSION of CONNECTION))
		    (COND
		      ((type? STREAM STREAM)                 (* Set the attributes to NIL so that the next call to 
							     GETFILEINFO will go back to the fileserver for them.)
			(replace NSFILING.ATTRIBUTES of STREAM with NIL))
		      (T (\NSFILING.INTERNAL.CLOSE CONNECTION HANDLE)))
		    (RETURN T])

(\LISP.TO.NSFILING.ATTRIBUTE
  [LAMBDA (ATTRIBUTE VALUE)                                  (* bvm: "17-NOV-83 16:07")
    (PROG ((X (ASSOC ATTRIBUTE \LISP.TO.NSFILING.ATTRIBUTES)))
          [COND
	    (X (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]
		   [TYPE (SETQ ATTRIBUTE (QUOTE FILE.TYPE))
			 (SETQ VALUE (SELECTQ VALUE
					      (BINARY 0)
					      (DIRECTORY 1)
					      (TEXT 2)
					      (LISPERROR "ILLEGAL ARG" VALUE]
		   (OR (ASSOC ATTRIBUTE \NSFILING.ATTRIBUTES)
		       (RETURN)))
          (RETURN (\WRITE.FILING.ATTRIBUTE ATTRIBUTE VALUE])

(\NSFILING.GENERATEFILES
  [LAMBDA (DEVICE PATTERN)                                   (* bvm: "16-NOV-83 17:16")
    (RESETLST (PROG ((HOST (FILENAMEFIELD PATTERN (QUOTE HOST)))
		     (NAME (ROOTFILENAME PATTERN))
		     (VERSION (FILENAMEFIELD PATTERN (QUOTE VERSION)))
		     CONNECTION FILELIST)
		    (SETQ CONNECTION (\GETFILINGCONNECTION HOST T))
		    [SETQ FILELIST (COND
			((NOT (\NSFILING.CONNECT CONNECTION PATTERN))
			  NIL)
			((STRPOS (QUOTE *)
				 NAME)                       (* Enumerate entire directory, matching against any wild
							     cards.)
			  (\NSFILING.LIST CONNECTION NAME))
			((OR (NULL VERSION)
			     (EQ VERSION (QUOTE *)))         (* Only enumerate versions.)
			  (\NSFILING.LISTVERSIONS CONNECTION NAME))
			(T                                   (* 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 "16-AUG-83 17:44")
    (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 (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))))
(DEFINEQ

(LIST.NSPRINTER.FILES
  [LAMBDA (PRINTSERVER)                                      (* bvm: "16-NOV-83 15:10")
    (PROG (STREAM SESSION LISTINGSTREAM SEQUENCE.OF.ATTRIBUTE.SEQUENCES)
          (SETQ STREAM (COURIER.OPEN PRINTSERVER (QUOTE PRINTSERVER)
				     NIL
				     (PACK* (CH.NAME.TO.STRING PRINTSERVER)
					    " Subset Filing")))
          (RETURN (RESETLST (RESETSAVE NIL (LIST (FUNCTION \SPP.CLOSE.IF.ERROR)
						 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 (FUNCTION [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)
							      \NSFILING.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 (17580 57631 (\NSFILING.LOGIN 17590 . 19503) (\NSFILING.LOGOUT 19505 . 20206) (
\NSFILING.CONNECT 20208 . 23767) (\PATHNAME.TO.DIRECTORY.LIST 23769 . 24201) (
\PATHNAME.TO.DIRECTORY.LIST.INTERNAL 24203 . 24611) (\DIRECTORY.LIST.TO.PATHNAME 24613 . 24851) (
\NSFILING.CREATE.DIRECTORY 24853 . 25471) (\NSFILING.LIST 25473 . 26726) (\NSFILING.LISTVERSIONS 26728
 . 27948) (\FILING.ATTRIBUTE.TYPE.SEQUENCE 27950 . 28164) (\FILING.ATTRIBUTE.TYPE 28166 . 28466) (
\READ.FILING.ATTRIBUTE.SEQUENCE 28468 . 28905) (\READ.FILING.ATTRIBUTE 28907 . 29580) (
\WRITE.FILING.ATTRIBUTE.SEQUENCE 29582 . 30022) (\WRITE.FILING.ATTRIBUTE 30024 . 30598) (NSDIRECTORY 
30600 . 31284) (NSCREATEDIRECTORY 31286 . 32083) (\NSFILING.INIT 32085 . 33076) (\GETFILINGCONNECTION 
33078 . 34375) (\OPENFILINGCONNECTION 34377 . 35639) (\CLOSEFILINGCONNECTION 35641 . 36001) (
\NSFILING.RESETCLOSE 36003 . 36167) (\VALID.FILING.CONNECTIONP 36169 . 37225) (
\LOGGED.ONTO.NSFILESERVERP 37227 . 37715) (CLOSE.NSFILING.CONNECTIONS 37717 . 38232) (
\NSFILING.OPENFILE 38234 . 38417) (\NSFILING.GETFILE 38419 . 45985) (\NSFILING.OPENFILE.OPTIONS 45987
 . 46317) (\NSFILING.CLOSEFILE 46319 . 47187) (\NSFILING.INTERNAL.CLOSE 47189 . 47583) (
\NSFILING.FULLNAME 47585 . 48553) (\NSFILING.EVENTFN 48555 . 48852) (\NSFILING.DELETEFILE 48854 . 
49725) (\NSFILING.HOSTNAMEP 49727 . 50182) (\NSFILING.DIRECTORYNAMEP 50184 . 50567) (
\NSFILING.GETFILENAME 50569 . 50883) (\NSFILING.GETFILEINFO 50885 . 52310) (
\NSFILING.GETFILEINFO.FROM.PLIST 52312 . 52822) (\NSFILING.SETFILEINFO 52824 . 54351) (
\LISP.TO.NSFILING.ATTRIBUTE 54353 . 55330) (\NSFILING.GENERATEFILES 55332 . 56528) (\NSFILING.NEXTFILE
 56530 . 57458) (\NSFILING.GETEOFPTR 57460 . 57629)) (61888 63768 (LIST.NSPRINTER.FILES 61898 . 63766)
))))
STOP