(FILECREATED " 8-Aug-86 16:19:07" {ROSEBOWL}<FEUERMAN>LISP>NCSERVER>NCCLIENT.;16 47330  

      changes to:  (FNS NCCLIENT.DELETENOTEFILE)

      previous date: " 6-Aug-86 15:21:35" {ROSEBOWL}<FEUERMAN>LISP>NCSERVER>NCCLIENT.;15)


(PRETTYCOMPRINT NCCLIENTCOMS)

(RPAQQ NCCLIENTCOMS ((FNS NCCLIENT.FILELOADEDP)
	(FILES (SOURCE)
	       NCCLIENTLISTENER)
	(* Only need the Server CALLER Courier program if the LISTENER isn't already loaded.)
	(P (OR (NCCLIENT.FILELOADEDP (QUOTE NCSERVERLISTENER))
	       (FILESLOAD (SOURCE)
			  NCSERVERCALLER)))
	(* * Functions to call the Courier procedures directly.)
	(FNS NCCLIENT.AREYOUTHERE NCCLIENT.LISTNOTEFILES NCCLIENT.CREATENOTEFILE 
	     NCCLIENT.DELETENOTEFILE NCCLIENT.SUBSCRIBETONOTEFILE NCCLIENT.CANCELNOTEFILESUBSCRIPTION 
	     NCCLIENT.LISTUIDS NCCLIENT.LISTCLIENTS NCCLIENT.CREATECARD NCCLIENT.DELETECARD 
	     NCCLIENT.GETCARDPART NCCLIENT.OBTAINWRITELOCK NCCLIENT.PUTCARDPART 
	     NCCLIENT.RELEASEWRITELOCK NCCLIENT.CANCELCARDPARTSUBSCRIPTION NCCLIENT.GETCARDINFO)
	(FNS NCCLIENT.GETUSERNAME)
	(* * Functions for calling server routines when the server machine is the same as the client 
	   machine.)
	(FNS NCCLIENT.LOCALLISTNOTEFILES NCCLIENT.LOCALCREATENOTEFILE NCCLIENT.LOCALDELETENOTEFILE 
	     NCCLIENT.LOCALSUBSCRIBETONOTEFILE NCCLIENT.LOCALCANCELNOTEFILESUBSCRIPTION 
	     NCCLIENT.LOCALLISTUIDS NCCLIENT.LOCALLISTCLIENTS NCCLIENT.LOCALCREATECARD 
	     NCCLIENT.LOCALDELETECARD NCCLIENT.LOCALGETCARDPART NCCLIENT.LOCALOBTAINWRITELOCK 
	     NCCLIENT.LOCALPUTCARDPART NCCLIENT.LOCALRELEASEWRITELOCK 
	     NCCLIENT.LOCALCANCELCARDPARTSUBSCRIPTION)
	(* * The GetCardPart and PutCardPart functions to be called with the BEFORE or AFTER litatom.)
	(FNS NCCLIENT.REMOTEGETFN NCCLIENT.REMOTEPUTFN)
	(* * These functions are the ones which field the calls to the Courier Server about 
	   notifications of changes to the NoteFile.)
	(FNS NCCLIENT.CARDCREATED NCCLIENT.CARDDELETED NCCLIENT.CARDPARTCHANGED 
	     NCCLIENT.WRITELOCKRELEASED NCCLIENT.WRITELOCKOBTAINED NCCLIENT.CARDSTATUSCHANGED 
	     NCCLIENT.FETCHUSERNAME)
	(* * The local handlers of Client notifications. These are called by the Server notifier if 
	   the NoteFile happens to reside on the same machine.)
	(FNS NCCLIENT.LOCALCARDCREATED NCCLIENT.LOCALCARDDELETED NCCLIENT.LOCALCARDPARTCHANGED 
	     NCCLIENT.LOCALWRITELOCKOBTAINED NCCLIENT.LOCALWRITELOCKRELEASED)
	(* * The notification queue stuff.)
	(FNS NCCLIENT.PROCESSCHANGE NCCLIENT.START.CLIENTLISTENER \NCCLIENT.PROCESS)
	(* * Miscellaneous functions.)
	(FNS NCCLIENT.LISTUSERS NCCLIENT.GETCOURIERSTREAM NCCLIENT.COURIERSTREAMFROMHOST 
	     NCCLIENT.COURIERSTREAMFROMUID NCCLIENT.GETNOTEFILEHOST NCCLIENT.GETNSADDRESS 
	     NCCLIENT.PARTCHANGEDNOTIFICATION NCCLIENT.REMOVEHOST NCCLIENT.COPYCARDPARTHEADER 
	     NCCLIENT.NSEQUAL NCCLIENT.CHANGECARDTITLE)
	(FILES NCDEVICE NCMULTIREMOTE NCNOTEFILEPROP QUEUE)
	(GLOBALVARS NCCLIENT.SERVERSTREAMS NCCLIENT.CHANGEQUEUE NCCLIENT.COURIER.MONITOR)
	[VARS (NCCLIENT.COURIER.MONITOR (CREATE.MONITORLOCK (QUOTE CourierLock]
	(INITVARS (NCCLIENT.SERVERSTREAMS NIL)
		  (NCCLIENT.CHANGEQUEUE (QUEUE.CREATE)))
	(ADDVARS (AFTERLOGOUTFORMS (COURIER.START.SERVER)))
	(DECLARE: DONTCOPY (RECORDS NSADDRESS))
	(P (COURIER.START.SERVER)
	   (NCCLIENT.START.CLIENTLISTENER))))
(DEFINEQ

(NCCLIENT.FILELOADEDP
  [LAMBDA (FILENAME)                                         (* Feuerman " 2-May-86 10:43")
    (GETPROP FILENAME (QUOTE FILEDATES])
)
(FILESLOAD (SOURCE)
	   NCCLIENTLISTENER)



(* Only need the Server CALLER Courier program if the LISTENER isn't already loaded.)

(OR (NCCLIENT.FILELOADEDP (QUOTE NCSERVERLISTENER))
    (FILESLOAD (SOURCE)
	       NCSERVERCALLER))
(* * Functions to call the Courier procedures directly.)

(DEFINEQ

(NCCLIENT.AREYOUTHERE
  [LAMBDA (NSADDRESS)                                        (* Feuerman "24-Jul-86 11:03")

          (* * Calls the Courier program to check to see if the server function is supported by the host.
	  Should include a timeout, in case the host just never responds.)


    (RESETVARS ((HELPFLAG NIL))
	         (RETURN (COND
			     ([NLSETQ (WITH.MONITOR NCCLIENT.COURIER.MONITOR
						      (COURIER.EXPEDITED.CALL (create NSADDRESS
										   using NSADDRESS 
											 NSSOCKET ← 0)
										0
										(QUOTE 
										  NoteCardsServer)
										(QUOTE AreYouThere]
			       T])

(NCCLIENT.LISTNOTEFILES
  [LAMBDA (NOTEFILEPATTERN)                                  (* Feuerman "23-Jul-86 13:04")
    (for F in [WITH.MONITOR NCCLIENT.COURIER.MONITOR
				(COURIER.EXPEDITED.CALL (NCCLIENT.GETNSADDRESS
							    (FILENAMEFIELD NOTEFILEPATTERN
									     (QUOTE HOST)))
							  0
							  (QUOTE NoteCardsServer)
							  (QUOTE ListNoteFiles)
							  (MKSTRING
							    (PROG ((UNPACKEDPATTERN (
										   UNPACKFILENAME
											
										  NOTEFILEPATTERN)))
								    (LISTPUT UNPACKEDPATTERN
									       (QUOTE HOST)
									       NIL)
								    (OR (LISTGET UNPACKEDPATTERN
										     (QUOTE NAME))
									  (LISTPUT UNPACKEDPATTERN
										     (QUOTE NAME)
										     (QUOTE *)))
								    (RETURN (PACKFILENAME 
										  UNPACKEDPATTERN]
       collect (PACK* (QUOTE {)
			  (NSNAME.TO.STRING (CH.LOOKUP.OBJECT (FILENAMEFIELD NOTEFILEPATTERN
										   (QUOTE HOST)))
					      T)
			  (QUOTE })
			  F])

(NCCLIENT.CREATENOTEFILE
  [LAMBDA (NOTEFILENAME)                                     (* Feuerman "23-Jul-86 13:05")

          (* * Called by the client to create a NoteFile on a NoteCards Server.)


    (PACK* (QUOTE {)
	     (NSNAME.TO.STRING (CH.LOOKUP.OBJECT (FILENAMEFIELD NOTEFILENAME (QUOTE HOST)))
				 T)
	     (QUOTE })
	     (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM
								      (FILENAMEFIELD NOTEFILENAME
										       (QUOTE
											 HOST)))
								    (QUOTE NoteCardsServer)
								    (QUOTE CreateNoteFile)
								    (MKSTRING (NCCLIENT.REMOVEHOST
										  NOTEFILENAME])

(NCCLIENT.DELETENOTEFILE
  [LAMBDA (NOTEFILENAME)                                     (* Feuerman " 8-Aug-86 14:04")

          (* * Deletes the file on the remote NoteCards Server.)


    (PROG [(RESULT (MKATOM (WITH.MONITOR NCCLIENT.COURIER.MONITOR
					     (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM
							       (FILENAMEFIELD NOTEFILENAME
										(QUOTE HOST)))
							     (QUOTE NoteCardsServer)
							     (QUOTE DeleteNoteFile)
							     (MKSTRING (NCCLIENT.REMOVEHOST
									   NOTEFILENAME]
	    (RETURN (AND RESULT (PACK* (QUOTE {)
					     (NSNAME.TO.STRING (CH.LOOKUP.OBJECT
								   (FILENAMEFIELD NOTEFILENAME
										    (QUOTE HOST)))
								 T)
					     (QUOTE })
					     RESULT])

(NCCLIENT.SUBSCRIBETONOTEFILE
  [LAMBDA (FILENAMEorUID)                                    (* Feuerman "23-Jul-86 13:07")

          (* * Returns a list of 4 UIDs: The Notefile UID, the Table of Contents Card UID, the Orphans UID, and the To Be 
	  Filed UID. Opens the NoteFile at the Server end if necessary.)


    (PROG [(NOTEFILENAME (COND
			     ((type? UID FILENAMEorUID)
			       (ffetch (NoteFile FullFileName) of (NC.NoteFileFromNoteFileUID
									FILENAMEorUID)))
			     (T FILENAMEorUID]
	    (RETURN (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL
				      (NCCLIENT.GETCOURIERSTREAM (FILENAMEFIELD NOTEFILENAME
										    (QUOTE HOST)))
				      (QUOTE NoteCardsServer)
				      (QUOTE SubscribeToNoteFile)
				      (LIST (QUOTE FILENAME)
					      (MKSTRING (NCCLIENT.REMOVEHOST NOTEFILENAME)))
				      \MY.NSADDRESS])

(NCCLIENT.CANCELNOTEFILESUBSCRIPTION
  [LAMBDA (UIDorFILENAMEorNoteFile)                          (* Feuerman "23-Jul-86 13:07")

          (* * Tells the Server that this client is no longer interested in the NoteFile specified by UIDorFILENAME.)


    (PROG [(REALFILENAME (COND
			     ((type? UID UIDorFILENAMEorNoteFile)
			       (ffetch (NoteFile FullFileName) of (NC.NoteFileFromNoteFileUID
									UIDorFILENAMEorNoteFile)))
			     ((type? NoteFile UIDorFILENAMEorNoteFile)
			       (ffetch (NoteFile FullFileName) of UIDorFILENAMEorNoteFile))
			     (T UIDorFILENAMEorNoteFile]
	    (RETURN (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL
				      (NCCLIENT.GETCOURIERSTREAM (FILENAMEFIELD REALFILENAME
										    (QUOTE HOST)))
				      (QUOTE NoteCardsServer)
				      (QUOTE CancelNoteFileSubscription)
				      (LIST (QUOTE FILENAME)
					      (MKSTRING (NCCLIENT.REMOVEHOST REALFILENAME)))
				      \MY.NSADDRESS])

(NCCLIENT.LISTUIDS
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "23-Jul-86 13:09")

          (* * Returns a list of all card UIDs for the NoteFile specified by NOTEFILEUID. These are all of the UIDs that are 
	  keys in the hash array on the server side.)


    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE ListUIDs)
							   NOTEFILEUID])

(NCCLIENT.LISTCLIENTS
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "23-Jul-86 13:09")

          (* * Returns a list of clients currently subscribed to the NoteFile specified by NOTEFILEUID.)


    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE ListClients)
							   NOTEFILEUID])

(NCCLIENT.CREATECARD
  [LAMBDA (NOTEFILEUID Type)                                 (* Feuerman " 1-Aug-86 14:04")

          (* * Sends off the message to the Server 
	  "I'm creating a new card.  Reserve me a spot in the NoteFile and give me the UID.")



          (* * kef 8/1/86: Added Type argument so that the server can tell others if they want it.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE CreateCard)
							   NOTEFILEUID
							   (MKSTRING Type)
							   \MY.NSADDRESS])

(NCCLIENT.DELETECARD
  [LAMBDA (NOTEFILEUID NOTECARDUID)                          (* Feuerman "23-Jul-86 13:10")

          (* * Tries to delete the card referred to by NOTECARDUID. Will fail miserably if not all of the writelocks are 
	  owned for the card. By miserably, we mean that a break window will come up.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE DeleteCard)
							   NOTEFILEUID NOTECARDUID \MY.NSADDRESS])

(NCCLIENT.GETCARDPART
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART BUCKETSTREAM)    (* Feuerman "23-Jul-86 13:10")

          (* * This is the actual construction of the Courier call.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE GetCardPart)
							   NOTEFILEUID NOTECARDUID CARDPART 
							   \MY.NSADDRESS (FUNCTION (LAMBDA (
								 BULK.DATA.STREAM)
							       (COPYBYTES BULK.DATA.STREAM 
									    BUCKETSTREAM)
							       (CLOSEF BULK.DATA.STREAM])

(NCCLIENT.OBTAINWRITELOCK
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "23-Jul-86 13:11")

          (* * Obtains the write-lock for the CARDPART of the indicated NoteCard. Returns T if successful, NIL otherwise.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE ObtainWriteLock)
							   NOTEFILEUID NOTECARDUID CARDPART 
							   \MY.NSADDRESS])

(NCCLIENT.PUTCARDPART
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART SOURCESTREAM)    (* Feuerman "23-Jul-86 13:13")

          (* * Constructs the actual courier call to the putcardpart service. Returns the Bulk data stream that the caller 
	  should copy the data onto. The caller should then finish off by closing the bulk data stream using CLOSE.BULK.DATA 
	  I think.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE PutCardPart)
							   NOTEFILEUID NOTECARDUID CARDPART
							   (FUNCTION [LAMBDA (BULK.SOURCE.STREAM)
							       (COPYBYTES SOURCESTREAM 
									    BULK.SOURCE.STREAM])
							   \MY.NSADDRESS])

(NCCLIENT.RELEASEWRITELOCK
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "23-Jul-86 13:13")

          (* * Instructs the server that this client is ready to give up the write lock for the given CARDPART.
	  Function simply returns T if the Client had the write lock and it was successfully released, NIL otherwise.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE ReleaseWriteLock)
							   NOTEFILEUID NOTECARDUID CARDPART 
							   \MY.NSADDRESS])

(NCCLIENT.CANCELCARDPARTSUBSCRIPTION
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "23-Jul-86 13:14")

          (* * Asks to be removed from the subscribers list for a particular card part.)


    (DECLARE (GLOBALVARS \MY.NSADDRESS))
    (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM NOTEFILEUID)
							   (QUOTE NoteCardsServer)
							   (QUOTE CancelCardPartSubscription)
							   NOTEFILEUID NOTECARDUID CARDPART 
							   \MY.NSADDRESS])

(NCCLIENT.GETCARDINFO
  [LAMBDA (NOTEFILEUID NOTECARDUID ASPECTS)                  (* Feuerman "30-Jul-86 07:58")
    (READ (WITH.MONITOR NCCLIENT.COURIER.MONITOR (COURIER.CALL (NCCLIENT.GETCOURIERSTREAM
								     NOTEFILEUID)
								   (QUOTE NoteCardsServer)
								   (QUOTE GetCardInfo)
								   NOTEFILEUID NOTECARDUID
								   (for Aspect in (MKLIST
											ASPECTS)
								      collect (MKSTRING Aspect])
)
(DEFINEQ

(NCCLIENT.GETUSERNAME
  [LAMBDA (ADDRESS)                                          (* Feuerman " 6-Aug-86 15:05")
    (COURIER.EXPEDITED.CALL (create NSADDRESS reusing ADDRESS NSSOCKET ← 0)
			      0
			      (QUOTE NoteCardsClient)
			      (QUOTE FetchUserName])
)
(* * Functions for calling server routines when the server machine is the same as the client 
machine.)

(DEFINEQ

(NCCLIENT.LOCALLISTNOTEFILES
  [LAMBDA (PATTERN)                                          (* Feuerman "15-May-86 15:13")

          (* * Simply calls the regular list notefiles function.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.LISTNOTEFILES (NCSERVER.REMOVEHOST PATTERN]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALLISTNOTEFILES)
						      (CAR RESULT)))
				  (T (for File in (CAR RESULT) collect (PACK* (QUOTE
											  {DSK})
											File]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALLISTNOTEFILES)
					     "Unknown Error"])

(NCCLIENT.LOCALCREATENOTEFILE
  [LAMBDA (NOTEFILENAME)                                     (* Feuerman "15-May-86 15:13")

          (* * Called by the local client for creating new notefiles.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.CREATENOTEFILE (NCSERVER.REMOVEHOST NOTEFILENAME]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALCREATENOTEFILE)
						      (CAR RESULT)))
				  (T (PACK* (QUOTE {DSK})
					      (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALCREATENOTEFILE)
					     "Unknown Error"])

(NCCLIENT.LOCALDELETENOTEFILE
  [LAMBDA (NOTEFILENAME)                                     (* Feuerman "15-May-86 15:16")

          (* * Simply calls the delete notefile routine.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.DELETENOTEFILE (NCSERVER.REMOVEHOST NOTEFILENAME]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALDELETENOTEFILE)
						      (CAR RESULT)))
				  (T (PACK* (QUOTE {DSK})
					      (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALDELETENOTEFILE)
					     "Unknown Error"])

(NCCLIENT.LOCALSUBSCRIBETONOTEFILE
  [LAMBDA (FILENAMEorUID)                                    (* Feuerman "15-May-86 15:18")

          (* * Opens a subscription to the notefile in the name of (QUOTE SELF.))


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.SUBSCRIBETONOTEFILE
					     (COND
					       ((type? UID FILENAMEorUID)
						 (LIST (QUOTE NOTEFILEUID)
							 FILENAMEorUID))
					       (T (LIST (QUOTE FILENAME)
							  FILENAMEorUID)))
					     (QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALSUBSCRIBETONOTEFILE)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALSUBSCRIBETONOTEFILE)
					     "Unknown Error"])

(NCCLIENT.LOCALCANCELNOTEFILESUBSCRIPTION
  [LAMBDA (NOTEFILEorUID)                                    (* Feuerman "15-May-86 15:19")

          (* * Removes SELF from the subscription list of the notefile.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.CANCELNOTEFILESUBSCRIPTION (COND
										  ((type? NoteFile 
										    NOTEFILEorUID)
										    NOTEFILEorUID)
										  ((type? UID 
										    NOTEFILEorUID)
										    (
								       NC.NoteFileFromNoteFileUID
										      NOTEFILEorUID))
										  ((LITATOM 
										    NOTEFILEorUID)
										    (
									  NC.NoteFileFromFileName
										      NOTEFILEorUID)))
										(QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE 
							 NCCLIENT.LOCALCANCELNOTEFILESUBSCRIPTION)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALCANCELNOTEFILESUBSCRIPTION)
					     "Unknown Error"])

(NCCLIENT.LOCALLISTUIDS
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "15-May-86 15:21")

          (* * Simply calls the regular list uids function.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.LISTUIDS NOTEFILEUID]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALLISTUIDS)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALLISTUIDS)
					     "Unknown Error"])

(NCCLIENT.LOCALLISTCLIENTS
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "15-May-86 15:20")

          (* * Simply calls the regular listclients function.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.LISTCLIENTS NOTEFILEUID]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALLISTCLIENTS)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALLISTCLIENTS)
					     "Unknown Error"])

(NCCLIENT.LOCALCREATECARD
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "15-May-86 15:21")

          (* * Reserves a spot in the NoteFile in the name of (QUOTE SELF.))


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.CREATECARD NOTEFILEUID (QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALCREATECARD)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALCREATECARD)
					     "Unknown Error"])

(NCCLIENT.LOCALDELETECARD
  [LAMBDA (NOTEFILEUID NOTECARDUID)                          (* Feuerman "15-May-86 15:22")

          (* * Simply deletes the card in the name of SELF.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.DELETECARD NOTEFILEUID NOTECARDUID (QUOTE
								  SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALDELETECARD)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALDELETECARD)
					     "Unknown Error"])

(NCCLIENT.LOCALGETCARDPART
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART BUCKETSTREAM)    (* Feuerman "15-May-86 15:23")

          (* * The BUCKETSTREAM is probably the Stream field of the NoteFile to fill with the data for the card part in 
	  question.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.GETCARDPART NOTEFILEUID NOTECARDUID CARDPART
								 (QUOTE SELF)
								 BUCKETSTREAM]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALGETCARDPART)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALGETCARDPART)
					     "Unknown Error"])

(NCCLIENT.LOCALOBTAINWRITELOCK
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "15-May-86 15:25")
    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.OBTAINWRITELOCK NOTEFILEUID NOTECARDUID CARDPART
								     (QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALOBTAINWRITELOCK)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALOBTAINWRITELOCK)
					     "Unknown Error"])

(NCCLIENT.LOCALPUTCARDPART
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART BUCKETSTREAM)    (* Feuerman "15-May-86 15:24")

          (* * BUCKETSTREAM is the stream containing the information that the PUTCARDPART function will dump into the 
	  NoteFile.)



          (* * MAJOR NOTE: The file pointer for BUCKETSTREAM must be set up correctly; this function will NOT set the file 
	  pointer to the beginning.)


    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.PUTCARDPART NOTEFILEUID NOTECARDUID CARDPART 
								 BUCKETSTREAM (QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALPUTCARDPART)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALPUTCARDPART)
					     "Unknown Error"])

(NCCLIENT.LOCALRELEASEWRITELOCK
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "15-May-86 15:25")
    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.RELEASEWRITELOCK NOTEFILEUID NOTECARDUID 
								      CARDPART (QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE NCCLIENT.LOCALRELEASEWRITELOCK)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALRELEASEWRITELOCK)
					     "Unknown Error"])

(NCCLIENT.LOCALCANCELCARDPARTSUBSCRIPTION
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman "15-May-86 15:25")
    (NCSERVER.CANCELCARDPARTSUBSCRIPTION NOTEFILEUID NOTECARDUID CARDPART (QUOTE SELF))
    (PROG [(RESULT (NCSERVER.NOBREAKEVAL (NCSERVER.CANCELCARDPARTSUBSCRIPTION NOTEFILEUID 
										NOTECARDUID CARDPART
										(QUOTE SELF]
	    (RETURN (COND
			[RESULT (COND
				  ((STRINGP (CAR RESULT))
				    (NC.ReportError (QUOTE 
							 NCCLIENT.LOCALCANCELCARDPARTSUBSCRIPTION)
						      (CAR RESULT)))
				  (T (CAR RESULT]
			(T (NC.ReportError (QUOTE NCCLIENT.LOCALCANCELCARDPARTSUBSCRIPTION)
					     "Unknown Error"])
)
(* * The GetCardPart and PutCardPart functions to be called with the BEFORE or AFTER litatom.)

(DEFINEQ

(NCCLIENT.REMOTEGETFN
  [LAMBDA (NOTEFILE NOTECARD CARDPART BEFORE.AFTER)          (* Feuerman "16-May-86 16:29")

          (* * The Get function for the remote Server device case. NOTEFILE and NOTECARD are both actual objects, NOT the 
	  UID! In the BEFORE case, we get the bucket of bits from the Server and stuff it into the Stream slot of the 
	  NoteFile. In the AFTER case, nothing is done.)


    (AND (EQ BEFORE.AFTER (QUOTE BEFORE))
	   (PROG [(CORESTREAM (replace (NoteFile Stream) of NOTEFILE
				   with (OPENSTREAM (QUOTE {NODIRCORE})
							(QUOTE BOTH]
	           (NCCLIENT.GETCARDPART (ffetch (NoteFile UID) of NOTEFILE)
					   (ffetch (Card UID) of NOTECARD)
					   CARDPART CORESTREAM)

          (* * Because we passed NIL in as the BULK.DATA.SINK argument to GetCardPart, COURIER.CALL returns in this case as 
	  its value a stream that contains the bulk data. When that bulk data stream is closed, the result specified in the 
	  Courier RETURNS clause is actually returned as the value of that CLOSEF. In this particular case, that will be 
	  NIL.)

                                                             (* Transfer the data off of the Bulk data stream, and 
							     into the local one that we'll be returning.)
	           (COND
		     ((ZEROP (GETEOFPTR CORESTREAM))
		       (NC.ReportError (QUOTE NCCLIENT.REMOTEGETFN)
					 "Retrieval of remote card part failed.")
                                                             (* If this is true, then we've retrieved nothing, so 
							     signal the error.)
		       ))
	           (SETFILEPTR CORESTREAM 0)
	           (RETURN CORESTREAM])

(NCCLIENT.REMOTEPUTFN
  [LAMBDA (NOTEFILE NOTECARD CARDPART BEFORE.AFTER)          (* Feuerman " 6-May-86 08:48")

          (* * This is the Put Function which in the BEFORE case sets up the local core stream for the caller to put stuff 
	  into, and in the after case transfers that data onto the bulk data source.)


    (SELECTQ BEFORE.AFTER
	       [BEFORE (replace (NoteFile Stream) of NOTEFILE with (OPENSTREAM (QUOTE
											 {NODIRCORE})
										       (QUOTE
											 BOTH]
	       [AFTER (PROG ((LOCALSTREAM (ffetch (NoteFile Stream) of NOTEFILE)))
			      (SETFILEPTR LOCALSTREAM 0)
			      (RETURN (NCCLIENT.PUTCARDPART (ffetch (NoteFile UID)
								   of NOTEFILE)
								(ffetch (Card UID) of NOTECARD)
								CARDPART LOCALSTREAM]
	       (SHOULDNT "BEFORE.AFTER argument should be one of 'BEFORE or 'AFTER"])
)
(* * These functions are the ones which field the calls to the Courier Server about 
notifications of changes to the NoteFile.)

(DEFINEQ

(NCCLIENT.CARDCREATED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID)
                                                             (* Feuerman " 4-Aug-86 13:46")

          (* * Fields the CARDCREATED notifications. Should return confirmation that the message was received.)



          (* * This should tell the local client that a card has appeared in the NoteFile by instantiating it in the Hash 
	  Array, complete with type and title.)


    (PROG ((NoteFile (NC.NoteFileFromNoteFileUID NOTEFILEUID)))

          (* * Probably should return confirmation that yes we got the message before asking for other information.)


	    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T)))

          (* * Now install a new card object in the hash array. Note that we expect the STATUS to be NIL at first, to be 
	  changed later on with a notification of status change. We'll assume the title to be "Untitled" until we're told 
	  otherwise also.)


	    (NC.InstallCardInNoteFile (create Card
						  NoteFile ← NoteFile
						  UID ← NOTECARDUID
						  Status ← NIL
						  Type ←[CDR (FASSOC (QUOTE TYPE)
									 (NCCLIENT.GETCARDINFO
									   (fetch (NoteFile UID)
									      of NoteFile)
									   NOTECARDUID
									   (QUOTE TYPE]
						  Title ← "Untitled"
						  IndexLoc ← -1
						  MainLoc ← -1
						  LinksLoc ← -1
						  PropListLoc ← -1
						  TitleLoc ← -1)
					NoteFile])

(NCCLIENT.CARDDELETED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID)
                                                             (* Feuerman "31-Jul-86 16:34")

          (* * Fields the CARDDELETED notifications.)



          (* * Marks the card locally as being DELETED and flushes out the caches.)


    (PROG [(Card (NC.CardFromUID NOTECARDUID (NC.NoteFileFromNoteFileUID NOTEFILEUID]
	    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T)))
	    (replace (Card Status) of Card with (QUOTE DELETED))
	    (replace (Card CardCache) of Card with NIL])

(NCCLIENT.CARDPARTCHANGED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID CARDPART)
                                                             (* Feuerman " 8-May-86 11:06")

          (* * Fields the cardpartchanged notifications. Needs to enqueue the notification to be dealt with later.
	  But acknowledge the nofication right away.)


    (QUEUE.ENQUEUE NCCLIENT.CHANGEQUEUE (LIST NOTEFILEUID NOTECARDUID CARDPART))
    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T])

(NCCLIENT.WRITELOCKRELEASED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID CARDPART)
                                                             (* Feuerman " 8-May-86 11:03")

          (* * Fields the notifications about the writelock for a cardpart having been released.)


    (PROMPTPRINT (CONCAT "Writelock released for CardPart " CARDPART " of NoteCard with UID " 
			     NOTECARDUID " of NoteFile with UID " NOTEFILEUID))
    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T])

(NCCLIENT.WRITELOCKOBTAINED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID CARDPART)
                                                             (* Feuerman " 8-May-86 11:01")

          (* * Fields the notifications that a writelock has be obtained.)


    (PROMPTPRINT (CONCAT "Writelock just obtained for CardPart " CARDPART " of NoteCard " 
			     NOTECARDUID " in NoteFile " NOTEFILEUID))
    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T])

(NCCLIENT.CARDSTATUSCHANGED
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID)
                                                             (* Feuerman " 1-Aug-86 10:08")

          (* * Notification from the server that the card status has been changed to ACTIVE, thus meaning that you will now 
	  find it in the NoteFile, and can start doing gets on it.)


    (PROG [(Card (NC.CardFromUID NOTECARDUID (NC.NoteFileFromNoteFileUID NOTEFILEUID]
	    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (QUOTE (T)))
	    (replace (Card Status) of Card with (QUOTE ACTIVE))

          (* * Now, since we're assumed to be caching the Title, better go off and find out what the new title is.
	  Remember, at this point we still think it's "Untitled" from when we first heard about the Card.)


	    (NC.GetTitle Card])

(NCCLIENT.FETCHUSERNAME
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE)                  (* Feuerman " 6-Aug-86 14:53")
    (COURIER.RETURN COURIERSTREAM PROGRAM PROCEDURE (LIST (USERNAME NIL NIL T])
)
(* * The local handlers of Client notifications. These are called by the Server notifier if 
the NoteFile happens to reside on the same machine.)

(DEFINEQ

(NCCLIENT.LOCALCARDCREATED
  [LAMBDA (NOTEFILEUID NOTECARDUID)                          (* Feuerman " 8-May-86 08:37")

          (* * Notifies SELF that a card was created.)


    (PROMPTPRINT (CONCAT "New card created for NoteFile " (ffetch (NoteFile FullFileName)
								 of (NC.NoteFileFromNoteFileUID
									NOTEFILEUID))
			     ":  " NOTECARDUID])

(NCCLIENT.LOCALCARDDELETED
  [LAMBDA (NOTEFILEUID NOTECARDUID)                          (* Feuerman " 8-May-86 08:40")

          (* * Notifies SELF that a card was deleted.)


    (PROMPTPRINT (CONCAT "Card deleted for NoteFile " (ffetch (NoteFile FullFileName)
							     of (NC.NoteFileFromNoteFileUID
								    NOTEFILEUID))
			     ":  " NOTECARDUID])

(NCCLIENT.LOCALCARDPARTCHANGED
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman " 8-May-86 12:46")

          (* * Notifies SELF that CARDPART has just changed.)


    (QUEUE.ENQUEUE NCCLIENT.CHANGEQUEUE (LIST NOTEFILEUID NOTECARDUID CARDPART))
    T])

(NCCLIENT.LOCALWRITELOCKOBTAINED
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman " 8-May-86 08:45")

          (* * Notifies SELF that the writelock for the cardpart has been obtained.)


    (PROMPTPRINT (CONCAT "Writelock has just been obtained for card part " CARDPART 
			     " of NoteCard "
			     NOTECARDUID " in NoteFile " (ffetch (NoteFile FullFileName)
							    of (NC.NoteFileFromNoteFileUID 
										      NOTEFILEUID])

(NCCLIENT.LOCALWRITELOCKRELEASED
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman " 8-May-86 08:52")

          (* * Notifies SELF that the writelock for the cardpart has been released.)


    (PROMPTPRINT (CONCAT "Writelock has just been released for card part " CARDPART 
			     " of NoteCard "
			     NOTECARDUID " in NoteFile " (ffetch (NoteFile FullFileName)
							    of (NC.NoteFileFromNoteFileUID 
										      NOTEFILEUID])
)
(* * The notification queue stuff.)

(DEFINEQ

(NCCLIENT.PROCESSCHANGE
  [LAMBDA (NOTEFILEUID NOTECARDUID CARDPART)                 (* Feuerman " 1-Aug-86 15:24")

          (* * This function handles the change message.)


    (PROG [(Card (NC.CardFromUID NOTECARDUID (NC.NoteFileFromNoteFileUID NOTEFILEUID]

          (* * I think that by setting the ActiveFlg to NIL, that forces whoever wants the SUBSTANCE TOLINKS FROMLINKS 
	  GLOBALTOLINKS or PROPLIST of the Card to "Get" it rather than "Fetch" it, thus going back to the NoteFile instead 
	  of the Cache.)


	    (SELECTQ CARDPART
		       (SUBSTANCE (replace (Card ActiveFlg) of Card with NIL)
				  (replace (Card Substance) of Card with NIL))
		       ((TOLINKS FROMLINKS GLOBALTOLINKS)
			 (replace (Card ActiveFlg) of Card with NIL)
			 (replace (Card Links) of Card with NIL))
		       (TITLE (NCCLIENT.CHANGECARDTITLE Card))
		       (PROPLIST (replace (Card ActiveFlg) of Card with NIL)
				 (replace (Card PropList) of Card with NIL))
		       [STATUS (replace (Card Status) of Card
				  with (CDR (FASSOC (QUOTE STATUS)
							  (APPLY* (fetch (NoteFile GetCardInfoFn)
								       of (
								       NC.NoteFileFromNoteFileUID
									      NOTEFILEUID))
								    Card
								    (QUOTE STATUS]
		       (SHOULDNT (CONCAT "Unknown how to deal with change in card part:  " 
					     CARDPART)))

          (* * Now recache the top level card if its cache was one that was flushed. Done to remain compatible with the end 
	  of NC.QuitCard.)


	    (if (NC.TopLevelCardP Card)
		then (NCP.ActivateCards Card])

(NCCLIENT.START.CLIENTLISTENER
  [LAMBDA NIL                                                (* Feuerman " 4-Aug-86 15:43")

          (* * Starts the client process which spends its entire time checking the change queue for change notifications.)


    (OR (PROCESSP (FIND.PROCESS (QUOTE NoteCardsClient)))
	  (ADD.PROCESS (LIST (QUOTE \NCCLIENT.PROCESS)
				 (KWOTE NCCLIENT.CHANGEQUEUE)
				 (KWOTE (FUNCTION NCCLIENT.PROCESSCHANGE)))
			 (QUOTE NAME)
			 (QUOTE NoteCardsClient)
			 (QUOTE RESTARTABLE)
			 T])

(\NCCLIENT.PROCESS
  [LAMBDA (QUEUE FN)                                         (* Feuerman " 6-Aug-86 15:21")
    (while T
       do (BLOCK)
	    [COND
	      ((CAR QUEUE)
		(APPLY FN (QUEUE.DEQUEUE QUEUE]
	    (OR (PROCESSP (FIND.PROCESS (QUOTE COURIER.LISTENER)))
		  (COURIER.START.SERVER])
)
(* * Miscellaneous functions.)

(DEFINEQ

(NCCLIENT.LISTUSERS
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman " 6-Aug-86 14:56")

          (* * Collects all of the NSAddresses of clients, and then polls them for their usernames.)


    (for Client in (NCCLIENT.LISTCLIENTS NOTEFILEUID) collect (COND
									((NCCLIENT.NSEQUAL Client 
										    \MY.NSADDRESS)
									  (QUOTE SELF))
									(T (NCCLIENT.GETUSERNAME
									     Client])

(NCCLIENT.GETCOURIERSTREAM
  [LAMBDA (HOSTorUID)                                        (* Feuerman " 2-May-86 08:30")

          (* * Given a HOSTorUID, finds the Courier Stream associated with it. This function merely hands off the argument to
	  the correct function for dealing with that type of arg.)


    (COND
      ((type? UID HOSTorUID)
	(NCCLIENT.COURIERSTREAMFROMUID HOSTorUID))
      (T (NCCLIENT.COURIERSTREAMFROMHOST HOSTorUID])

(NCCLIENT.COURIERSTREAMFROMHOST
  [LAMBDA (HOST)                                             (* Feuerman " 2-May-86 08:35")

          (* * This function returns the Courier Stream for Courier calls to HOST If a stream has already been opened for 
	  HOST, it will be saved on the GLOBALVAR propertylist NCCLIENT.SERVERSTREAMS. Otherwise, a new stream is opened and 
	  stored on that variable.)


    (PROG ([REALHOST (U-CASE (MKATOM (NSNAME.TO.STRING (CH.LOOKUP.OBJECT HOST)
							       T]
	     STREAM)
	    (RETURN (COND
			((NULL NCCLIENT.SERVERSTREAMS)
			  [SETQ NCCLIENT.SERVERSTREAMS (LIST REALHOST (COURIER.OPEN
								   (NCCLIENT.GETNSADDRESS REALHOST]
			  (LISTGET NCCLIENT.SERVERSTREAMS REALHOST))
			((AND (SETQ STREAM (LISTGET NCCLIENT.SERVERSTREAMS REALHOST))
				(OPENP STREAM)
				(SPPOUTPUTSTREAM STREAM))
			  STREAM)
			(T (LISTPUT NCCLIENT.SERVERSTREAMS REALHOST (COURIER.OPEN (
									    NCCLIENT.GETNSADDRESS
											REALHOST])

(NCCLIENT.COURIERSTREAMFROMUID
  [LAMBDA (UID)                                              (* Feuerman " 2-May-86 09:57")

          (* * If UID is found in the NC.NoteFilesHashArray, then it is the UID for a NoteFile. The Courier Stream can then 
	  be gotten off of the NoteFile's UserProps or by computing it from the host of the full file name.)


    (PROG ((NoteFile (NC.NoteFileFromNoteFileUID UID))
	     STREAM)
	    (RETURN (COND
			[NoteFile (COND
				    ((AND (SETQ STREAM (NCNOTEFILEPROP.NoteFileGetProp
						NoteFile
						(QUOTE COURIERSTREAM)))
					    (SPPOUTPUTSTREAM STREAM))
				      STREAM)
				    (T (NCNOTEFILEPROP.NoteFilePutProp
					 NoteFile
					 (QUOTE COURIERSTREAM)
					 (NCCLIENT.COURIERSTREAMFROMHOST
					   (FILENAMEFIELD (ffetch (NoteFile FullFileName)
							       of NoteFile)
							    (QUOTE HOST]
			(T (ERROR 
	     "Don't know how to find Courier Stream given a UID not in the NC.NoteFilesHashArray"])

(NCCLIENT.GETNOTEFILEHOST
  [LAMBDA (NOTEFILEUID)                                      (* Feuerman "21-Mar-86 15:04")

          (* * Figures out which host the NoteFile associated with NOTEFILEUID is living on.)



          (* * Someday we'll do this right, as soon as we have a client running in 1.3. For now, just assume the host is 
	  GNUDNIK:VISTA.)


    (QUOTE GNUDNIK:VISTA])

(NCCLIENT.GETNSADDRESS
  [LAMBDA (HOST)                                             (* Feuerman "19-Mar-86 14:18")

          (* * This function simply looks up HOST as a name in the CLEARINGHOUSE and returns the NS address, with only one 
	  change: It makes sure that the SOCKET field of the NS address is 0.0 This has proved to be the source of a lot of 
	  "Host not responding" messages in the middle of COURIER.OPENs.)


    (create NSADDRESS reusing (LOOKUP.NS.SERVER HOST)
				  NSSOCKET ← 0])

(NCCLIENT.PARTCHANGEDNOTIFICATION
  [LAMBDA (COURIERSTREAM PROGRAM PROCEDURE NOTEFILEUID NOTECARDUID CARDPART)
                                                             (* Feuerman "20-Mar-86 07:55")

          (* * The Client's function which actually responds to the part changed notification sent out by the 
	  NOTECARDSERVER.)


    (COURIER.ABORT COURIERSTREAM PROGRAM (QUOTE ServiceNotImplemented)
		     (LIST "PartChangedNotification"])

(NCCLIENT.REMOVEHOST
  [LAMBDA (FILENAME)                                         (* Feuerman "20-Mar-86 08:28")

          (* * Simple strips the host name out of FILENAME. Useful for exchanging file names between client and server, 
	  because the server will want to refer to the host as {DSK}, but the client will want to call it {GNUDNIK:VISTA} or 
	  whatever the host is called.)


    (PROG ((UNPACKEDFILENAME (UNPACKFILENAME FILENAME)))
	    (LISTPUT UNPACKEDFILENAME (QUOTE HOST)
		       NIL)
	    (RETURN (PACKFILENAME UNPACKEDFILENAME])

(NCCLIENT.COPYCARDPARTHEADER
  [LAMBDA (SOURCESTREAM DESTINATIONSTREAM)                   (* Feuerman "22-Jul-86 08:38")

          (* * ASSUMES that the pointers are already in place. Simply copies a card part header from SOURCESTREAM to 
	  DESTINATIONSTREAM. Results in advancing the stream pointers accordingly.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))              (* First, copy over the three-byte length info.)
    (COPYBYTES SOURCESTREAM DESTINATIONSTREAM 3)           (* Next, copy over the Identifier.)
    (PRINT (READ SOURCESTREAM NC.OrigReadTable)
	     DESTINATIONSTREAM NC.OrigReadTable)
    (BIN SOURCESTREAM)                                     (* Next, the version number.)
    (BOUT DESTINATIONSTREAM (BIN SOURCESTREAM))          (* Now copy over the date.)
    (NC.WriteDate DESTINATIONSTREAM (NC.ReadDate SOURCESTREAM))

          (* And finally, the UID. Someday we may have enough confidence to do this with a COPYBYTES, but for now, we should 
	  stick to the "right" way to do it.)


    (NC.WriteUID DESTINATIONSTREAM (NC.ReadUID SOURCESTREAM])

(NCCLIENT.NSEQUAL
  [LAMBDA (NSADR1 NSADR2)                                    (* Feuerman "21-Jul-86 10:41")

          (* * Returns non-NIL if NSADR1 and NSADR2 are the same NS net address.)



          (* * Added possibility that NSADR1 and/or NSADR2 could be (QUOTE SELF))



          (* * Took out checks of the NSNET and NSSOCKET fields. The reason is that for every machine, the machine number is 
	  unique throughout all eternity, or at least my lifetime. Since that number is contained in the NSHNM0 NSHNM1 and 
	  NSHNM2 fields, those are the only ones to check.)


    (OR (AND (EQ NSADR1 (QUOTE SELF))
		 (EQ NSADR2 (QUOTE SELF)))
	  (AND NSADR1 NSADR2 (type? NSADDRESS NSADR1)
		 (type? NSADDRESS NSADR2)
		 (EQ (ffetch (NSADDRESS NSHNM0) of NSADR1)
		       (ffetch (NSADDRESS NSHNM0) of NSADR2))
		 (EQ (ffetch (NSADDRESS NSHNM1) of NSADR1)
		       (ffetch (NSADDRESS NSHNM1) of NSADR2))
		 (EQ (ffetch (NSADDRESS NSHNM2) of NSADR1)
		       (ffetch (NSADDRESS NSHNM2) of NSADR2])

(NCCLIENT.CHANGECARDTITLE
  [LAMBDA (Card)                                             (* Feuerman " 6-Aug-86 14:38")
    (NC.GetTitle Card)
    (NC.GetLinks Card)
    (AND (WINDOWP (NC.FetchWindow Card))
	   (WINDOWPROP (NC.FetchWindow Card)
			 (QUOTE TITLE)
			 (NC.FetchTitle Card)))
    (for FromLink in (fetch (Card FromLinks) of Card)
       when (AND (NC.ActiveCardP (fetch (Link SourceCard) of FromLink))
		     (NC.FetchWindow (fetch (Link SourceCard) of FromLink)))
       do (NC.UpdateLinkImages (fetch (Link SourceCard) of FromLink)
				   Card])
)
(FILESLOAD NCDEVICE NCMULTIREMOTE NCNOTEFILEPROP QUEUE)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NCCLIENT.SERVERSTREAMS NCCLIENT.CHANGEQUEUE NCCLIENT.COURIER.MONITOR)
)

(RPAQ NCCLIENT.COURIER.MONITOR (CREATE.MONITORLOCK (QUOTE CourierLock)))

(RPAQ? NCCLIENT.SERVERSTREAMS NIL)

(RPAQ? NCCLIENT.CHANGEQUEUE (QUEUE.CREATE))

(ADDTOVAR AFTERLOGOUTFORMS (COURIER.START.SERVER))
(DECLARE: DONTCOPY 
[DECLARE: EVAL@COMPILE 

(DATATYPE NSADDRESS ((NSNET FIXP)
		       (NSHNM0 WORD)
		       (NSHNM1 WORD)
		       (NSHNM2 WORD)
		       (NSSOCKET WORD))
		      (ACCESSFNS (NSHOSTNUMBER (LOADNSHOSTNUMBER (LOCF (fetch NSHNM0
									    of DATUM)))
						 (STORENSHOSTNUMBER (LOCF (fetch NSHNM0
									     of DATUM))
								    NEWVALUE)))
		      (BLOCKRECORD NSADDRESS ((NSNETHI WORD)
				      (NSNETLO WORD))))
]
(/DECLAREDATATYPE (QUOTE NSADDRESS)
		  (QUOTE (FIXP WORD WORD WORD WORD))
		  [QUOTE ((NSADDRESS 0 FIXP)
			  (NSADDRESS 2 (BITS . 15))
			  (NSADDRESS 3 (BITS . 15))
			  (NSADDRESS 4 (BITS . 15))
			  (NSADDRESS 5 (BITS . 15]
		  (QUOTE 6))
)
(COURIER.START.SERVER)
(NCCLIENT.START.CLIENTLISTENER)
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3314 3496 (NCCLIENT.FILELOADEDP 3324 . 3494)) (3797 15035 (NCCLIENT.AREYOUTHERE 3807 . 
4474) (NCCLIENT.LISTNOTEFILES 4476 . 5578) (NCCLIENT.CREATENOTEFILE 5580 . 6295) (
NCCLIENT.DELETENOTEFILE 6297 . 7100) (NCCLIENT.SUBSCRIBETONOTEFILE 7102 . 8039) (
NCCLIENT.CANCELNOTEFILESUBSCRIPTION 8041 . 9080) (NCCLIENT.LISTUIDS 9082 . 9582) (NCCLIENT.LISTCLIENTS
 9584 . 10018) (NCCLIENT.CREATECARD 10020 . 10700) (NCCLIENT.DELETECARD 10702 . 11310) (
NCCLIENT.GETCARDPART 11312 . 11973) (NCCLIENT.OBTAINWRITELOCK 11975 . 12530) (NCCLIENT.PUTCARDPART 
12532 . 13349) (NCCLIENT.RELEASEWRITELOCK 13351 . 14013) (NCCLIENT.CANCELCARDPARTSUBSCRIPTION 14015 . 
14558) (NCCLIENT.GETCARDINFO 14560 . 15033)) (15036 15341 (NCCLIENT.GETUSERNAME 15046 . 15339)) (15452
 25238 (NCCLIENT.LOCALLISTNOTEFILES 15462 . 16159) (NCCLIENT.LOCALCREATENOTEFILE 16161 . 16820) (
NCCLIENT.LOCALDELETENOTEFILE 16822 . 17468) (NCCLIENT.LOCALSUBSCRIBETONOTEFILE 17470 . 18312) (
NCCLIENT.LOCALCANCELNOTEFILESUBSCRIPTION 18314 . 19390) (NCCLIENT.LOCALLISTUIDS 19392 . 19955) (
NCCLIENT.LOCALLISTCLIENTS 19957 . 20534) (NCCLIENT.LOCALCREATECARD 20536 . 21139) (
NCCLIENT.LOCALDELETECARD 21141 . 21750) (NCCLIENT.LOCALGETCARDPART 21752 . 22474) (
NCCLIENT.LOCALOBTAINWRITELOCK 22476 . 23049) (NCCLIENT.LOCALPUTCARDPART 23051 . 23927) (
NCCLIENT.LOCALRELEASEWRITELOCK 23929 . 24508) (NCCLIENT.LOCALCANCELCARDPARTSUBSCRIPTION 24510 . 25236)
) (25340 28057 (NCCLIENT.REMOTEGETFN 25350 . 27127) (NCCLIENT.REMOTEPUTFN 27129 . 28055)) (28192 33078
 (NCCLIENT.CARDCREATED 28202 . 29722) (NCCLIENT.CARDDELETED 29724 . 30373) (NCCLIENT.CARDPARTCHANGED 
30375 . 30911) (NCCLIENT.WRITELOCKRELEASED 30913 . 31456) (NCCLIENT.WRITELOCKOBTAINED 31458 . 31965) (
NCCLIENT.CARDSTATUSCHANGED 31967 . 32859) (NCCLIENT.FETCHUSERNAME 32861 . 33076)) (33231 35315 (
NCCLIENT.LOCALCARDCREATED 33241 . 33630) (NCCLIENT.LOCALCARDDELETED 33632 . 34023) (
NCCLIENT.LOCALCARDPARTCHANGED 34025 . 34321) (NCCLIENT.LOCALWRITELOCKOBTAINED 34323 . 34817) (
NCCLIENT.LOCALWRITELOCKRELEASED 34819 . 35313)) (35358 38043 (NCCLIENT.PROCESSCHANGE 35368 . 37110) (
NCCLIENT.START.CLIENTLISTENER 37112 . 37689) (\NCCLIENT.PROCESS 37691 . 38041)) (38081 46139 (
NCCLIENT.LISTUSERS 38091 . 38565) (NCCLIENT.GETCOURIERSTREAM 38567 . 39042) (
NCCLIENT.COURIERSTREAMFROMHOST 39044 . 40114) (NCCLIENT.COURIERSTREAMFROMUID 40116 . 41157) (
NCCLIENT.GETNOTEFILEHOST 41159 . 41568) (NCCLIENT.GETNSADDRESS 41570 . 42103) (
NCCLIENT.PARTCHANGEDNOTIFICATION 42105 . 42581) (NCCLIENT.REMOVEHOST 42583 . 43176) (
NCCLIENT.COPYCARDPARTHEADER 43178 . 44343) (NCCLIENT.NSEQUAL 44345 . 45468) (NCCLIENT.CHANGECARDTITLE 
45470 . 46137)))))
STOP