(FILECREATED "21-Feb-84 12:49:30" {PHYLUM}<LISPCORE>LIBRARY>MAILCLIENT.;6 22347  

      changes to:  (FNS \RESPTORETRIEVEMESSAGE \RECEIVEMESSAGEITEM)

      previous date: "24-Jan-84 18:33:08" {PHYLUM}<LISPCORE>LIBRARY>MAILCLIENT.;5)


(* Copyright (c) 1983, 1984 by Xerox Corporation)

(PRETTYCOMPRINT MAILCLIENTCOMS)

(RPAQQ MAILCLIENTCOMS ((COMS (* Sending mail)
			     (FNS GV.STARTSEND GV.ADDRECIPIENT GV.CHECKVALIDITY GV.STARTITEM 
				  GV.ADDTOITEM GV.SEND MS.EXPAND)
			     (* Internal sending)
			     (FNS MS.SENDOPERATION \FINDMAILSERVER \MAILSERVERSOCKETS \RECEIVEACK 
				  \RESPTOCHECKVAL \RESPTOEXPAND \RESPTOSTARTSEND)
			     (VARS (\MAILIOTIMEOUT NIL)
				   (\MAILSERVERENQUIRYSOC 46)
				   (\MAILSERVERNAME (QUOTE (Maildrop . ms)))
				   (\MAILSERVERPOLLINGSOC 44)
				   (\MAILSERVERSOCKETCACHE)
				   (\MAILSERVERRETRIEVALSOC 47))
			     (GLOBALVARS \MAILIOTIMEOUT \MAILSERVERENQUIRYSOC \MAILSERVERNAME 
					 \MAILSERVERPOLLINGSOC \MAILSERVERSOCKETCACHE 
					 \MAILSERVERRETRIEVALSOC)
			     (ADDVARS (\SYSTEMCACHEVARS \MAILSERVERSOCKETCACHE)))
		       (COMS (* Definition of a GV mail server for clients)
			     (FNS GV.PORTFROMNAME GV.POLLNEWMAIL GV.OPENMAILBOX GV.NEXTMESSAGE 
				  GV.RETRIEVEMESSAGE GV.CLOSEMAILBOX)
			     (ADDVARS (MAILSERVERTYPES (GV GV.POLLNEWMAIL GV.OPENMAILBOX 
							   GV.NEXTMESSAGE GV.RETRIEVEMESSAGE 
							   GV.CLOSEMAILBOX GV.PORTFROMNAME)))
			     (* Other ops someone might want)
			     (FNS GV.READTOC GV.WRITETOC GV.DELETEMESSAGE)
			     (* The low-level Mail Retrieval Protocol functions *)
			     (FNS MS.RETRIEVEOPERATION \CONNECTTOMAILSERVER \OPENMAILSERVER 
				  \RESPTOOPENMAILBOX \RESPTONEXTMESSAGE \RESPTORETRIEVEMESSAGE 
				  \RECEIVEMESSAGEITEM \RECEIVELONGWORD))
		       (DECLARE: DOEVAL@COMPILE DONTCOPY (EXPORT (RECORDS MAILPORT OPENEDMAILBOX 
									  NEXTMESSAGE))
				 (COMS * MAILCLIENTCONSTANTCOMS))
		       (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY (FILES (LOADCOMP)
									      GRAPEVINE PUP BSP))))



(* Sending mail)

(DEFINEQ

(GV.STARTSEND
  [LAMBDA (SENDER KEY RETURN VALIDATEFLG)                    (* M.Yonke "15-JUN-83 15:18")

          (* * returns either a socket to use to send the rest of the message on or NIL * *)


    (PROG (SENDINGSOCKET STARTSENDRESULT)
          (if (SETQ SENDINGSOCKET (\FINDMAILSERVER))
	      then (if (SETQ STARTSENDRESULT (MS.SENDOPERATION \OP.STARTSEND SENDINGSOCKET
							       (LIST (\CHECKNAME SENDER)
								     (\CHECKKEY KEY)
								     (\CHECKNAME RETURN)
								     (LIST \3BYTEKLUDGEKEY
									   (if VALIDATEFLG
									       then 1
									     else 0)))
							       (FUNCTION \RESPTOSTARTSEND)))
		       then (RETURN SENDINGSOCKET)
		     else                                    (* print the reason for failure *)
			  (printout PROMPTWINDOW "Couldn't start sending the message - reason: " 
				    STARTSENDRESULT T)
			  (RETURN NIL])

(GV.ADDRECIPIENT
  [LAMBDA (SOCKET NAME)                                      (* M.Yonke "15-JUN-83 15:20")
    (MS.SENDOPERATION \OP.ADDRECIPIENT SOCKET (LIST (\CHECKNAME NAME])

(GV.CHECKVALIDITY
  [LAMBDA (SOCKET)                                           (* M.Yonke "15-JUN-83 15:53")
    (MS.SENDOPERATION \OP.CHECKVALIDITY SOCKET NIL (FUNCTION \RESPTOCHECKVAL])

(GV.STARTITEM
  [LAMBDA (SOCKET TYPE)                                      (* M.Yonke "15-JUN-83 15:31")
                                                             (* If TYPE is not supplied assume text *)
    (MS.SENDOPERATION \OP.STARTITEM SOCKET (LIST (OR (AND TYPE (SMALLP TYPE))
						     \I.TEXT])

(GV.ADDTOITEM
  [LAMBDA (SOCKET STR)                                       (* bvm: "19-Dec-83 16:15")

          (* * * Can't use \SENDITEM here because not in usual Grapevine STR format -- no maxLength or padding -- so we do 
	  it by hand and no response is given * *)


    (PROG ((OUTSTREAM (fetch GVOUTSTREAM of SOCKET))
	   WASOPEN INSTREAM #CHARS)
          (MS.SENDOPERATION \OP.ADDTOITEM SOCKET)
          [SETQ #CHARS (OR (SELECTQ (TYPENAME STR)
				    (STRINGP (NCHARS STR))
				    (STREAM (GETFILEINFO (SETQ WASOPEN (SETQ INSTREAM STR))
							 (QUOTE LENGTH)))
				    [LITATOM (COND
					       ((INFILEP STR)
						 (GETFILEINFO (SETQ INSTREAM (OPENSTREAM
								  STR
								  (QUOTE INPUT)))
							      (QUOTE LENGTH]
				    NIL)
			   (NCHARS (SETQ STR (MKSTRING STR]
          (\SENDWORD OUTSTREAM #CHARS)
          (COND
	    (INSTREAM (OR (ZEROP (GETFILEPTR INSTREAM))
			  (SETFILEPTR INSTREAM 0))
		      (COPYBYTES INSTREAM OUTSTREAM)
		      (OR WASOPEN (CLOSEF INSTREAM)))
	    (T (for CHAR instring STR do (BOUT OUTSTREAM CHAR])

(GV.SEND
  [LAMBDA (SOCKET)                                           (* M.Yonke "15-JUN-83 15:51")
    (MS.SENDOPERATION \OP.SEND SOCKET (FUNCTION \RECEIVEACK])

(MS.EXPAND
  [LAMBDA (SOCKET NAME)                                      (* M.Yonke "15-JUN-83 15:53")

          (* * Does the mailserver Expand operation -- named to avoid conflict with the database version -- DBEXPAND * *)


    (MS.SENDOPERATION \OP.MSEXPAND SOCKET (LIST (\CHECKNAME NAME))
		      (FUNCTION \RESPTOEXPAND])
)



(* Internal sending)

(DEFINEQ

(MS.SENDOPERATION
  [LAMBDA (OP SOCKET ARGS RESPONSEFN)                        (* M.Yonke "15-JUN-83 16:03")

          (* * basic workhorse for communicating with a mail server -
	  sends an OP and ARGS and fields a response, if appropriate * *)


    (if SOCKET
	then (if (NLSETQ (PROG ((STREAM (fetch GVOUTSTREAM of SOCKET)))
			       (\SENDWORD STREAM OP)
			       (for ARG in ARGS do (\SENDITEM STREAM ARG))
			       (BSPFORCEOUTPUT STREAM)))
		 then (if RESPONSEFN
			  then (CAR (OR (NLSETQ (APPLY* RESPONSEFN (fetch GVINSTREAM of SOCKET)))
					NIL))
			else T))
      else                                                   (* We're in the middle -
							     nothing for it but to bail out)
	   EC.STREAMLOST])

(\FINDMAILSERVER
  [LAMBDA (ERRORFLG)                                         (* M.Yonke "15-JUN-83 15:16")

          (* * Open a BSP connection to a nearby, responsive mail server and returns it * *)


    (if (OPENCLOSESTSOCKET (\MAILSERVERSOCKETS ERRORFLG)
			   \MAILSERVERPOLLINGSOC \MAILSERVERENQUIRYSOC NIL \MAILIOTIMEOUT)
      elseif ERRORFLG
	then (ERROR "Couldn't open connection for" \MAILSERVERNAME)
	     NIL])

(\MAILSERVERSOCKETS
  [LAMBDA (ERRORFLG)                                         (* bvm: "21-MAY-83 20:00")
    (PROG (SOCKETS)
          (RETURN (COND
		    ([AND \MAILSERVERSOCKETCACHE (NOT (TIMEREXPIRED? (CAR \MAILSERVERSOCKETCACHE]
		      (CDR \MAILSERVERSOCKETCACHE))
		    (T (SETQ \MAILSERVERSOCKETCACHE (AND (SETQ SOCKETS
							   (LOCATESOCKETS \MAILSERVERNAME ERRORFLG))
							 (CONS (SETUPTIMER \MAILSOCKETTIMEOUT)
							       SOCKETS)))
		       SOCKETS])

(\RECEIVEACK
  [LAMBDA (STREAM)                                           (* M.Yonke " 3-JUN-83 16:43")
                                                             (* any byte will do -
							     it seems to be 0 when I've noticed)
    (if (BIN STREAM)
	then T])

(\RESPTOCHECKVAL
  [LAMBDA (INSTREAM)                                         (* bvm: "11-MAY-83 16:10")
                                                             (* As per documentation -
							     bad guys followed by count of good guys which I CONS on 
							     the front)
    (bind N until (ZEROP (SETQ N (\RECEIVEWORD INSTREAM))) collect (CONS N (\RECEIVERNAME INSTREAM))
       finally (RETURN (CONS (\RECEIVEWORD INSTREAM)
			     $$VAL])

(\RESPTOEXPAND
  [LAMBDA (INSTREAM)                                         (* bvm: "11-MAY-83 16:11")
                                                             (* As per documentation -
							     names followed by a code which I interpret and CONS on 
							     the front)
    (while (\RECEIVEBOOL INSTREAM) collect (\RECEIVERNAME INSTREAM)
       finally (RETURN (CONS (SELECTQ (BIN INSTREAM)
				      ((0 2)
					T)
				      ((1 3)
					EC.BADRNAME)
				      (SHOULDNT))
			     $$VAL])

(\RESPTOSTARTSEND
  [LAMBDA (INSTREAM)                                         (* M.Yonke "26-MAY-83 10:45")
    (SELECTC (BIN INSTREAM)
	     (\RC.SENDSTARTED T)
	     (\RC.PASSWORDINVALID (QUOTE InvalidPassword))
	     (\RC.SENDERNOTREGISTERED (QUOTE SenderNotRegistered))
	     (\RC.RETURNTONOTREGISTERED (QUOTE ReturnToNotRegistered))
	     (\RC.COMMUNICATIONFAILURE (QUOTE NetworkCommunicationsFailure))
	     (SHOULDNT])
)

(RPAQQ \MAILIOTIMEOUT NIL)

(RPAQQ \MAILSERVERENQUIRYSOC 46)

(RPAQQ \MAILSERVERNAME (Maildrop . ms))

(RPAQQ \MAILSERVERPOLLINGSOC 44)

(RPAQQ \MAILSERVERSOCKETCACHE NIL)

(RPAQQ \MAILSERVERRETRIEVALSOC 47)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS \MAILIOTIMEOUT \MAILSERVERENQUIRYSOC \MAILSERVERNAME \MAILSERVERPOLLINGSOC 
	  \MAILSERVERSOCKETCACHE \MAILSERVERRETRIEVALSOC)
)

(ADDTOVAR \SYSTEMCACHEVARS \MAILSERVERSOCKETCACHE)



(* Definition of a GV mail server for clients)

(DEFINEQ

(GV.PORTFROMNAME
  [LAMBDA (SERVERNAME)                                       (* bvm: " 1-Jan-84 17:11")
    (AND (SETQ SERVERNAME (GV.READCONNECT SERVERNAME))
	 (ETHERPORT SERVERNAME])

(GV.POLLNEWMAIL
  [LAMBDA (REGISTEREDNAME GVPORT)                            (* M.Yonke "10-AUG-83 15:41")
    (PROG ((SOC (\GETMISCSOCKET))
	   (OUTPUP (ALLOCATE.PUP))
	   (RESULT (QUOTE ?))
	   INPUP)
          (SETUPPUP OUTPUP (fetch (MAILPORT HOST#) of GVPORT)
		    (fetch (MAILPORT SOCKET#) of GVPORT)
		    \PT.LAURELCHECK NIL SOC T)
          (PUTPUPSTRING OUTPUP REGISTEREDNAME)
          (to \MAXETHERTRIES when (SETQ INPUP (EXCHANGEPUPS SOC OUTPUP NIL T))
	     do (SELECTC (fetch PUPTYPE of INPUP)
			 (\PT.NEWMAIL (SETQ RESULT T)
				      (RETURN))
			 (\PT.NONEWMAIL (SETQ RESULT NIL)
					(RETURN))
			 (\PT.NOMAILBOX (RETURN))
			 (\PT.ERROR (AND PUPTRACEFLG (PRINTERRORPUP INPUP PUPTRACEFILE))
				    (if (EQ (fetch ERRORPUPCODE of INPUP)
					    \PUPE.NOSOCKET)
					then (RETURN)))
			 NIL)
	     finally (AND PUPTRACEFLG (printout PUPTRACEFILE "Mail check timed out" T)))
          (AND INPUP (RELEASE.PUP INPUP))
          (RELEASE.PUP OUTPUP)
          (RETURN RESULT])

(GV.OPENMAILBOX
  [LAMBDA (PORT NAME PASSWORD HOSTNAME)                      (* DECLARATIONS: (RECORD (RETURNCODE #OFMESSAGES)))
                                                             (* bvm: "24-Jan-84 18:33")
    (PROG (MAILBOX INBOXRESULT)
          (COND
	    ((SETQ MAILBOX (\CONNECTTOMAILSERVER PORT))
	      (COND
		((SETQ INBOXRESULT (MS.RETRIEVEOPERATION \OP.OPENINBOX MAILBOX (LIST (\CHECKNAME
										       NAME)
										     (\CHECKKEY
										       PASSWORD))
							 (FUNCTION \RESPTOOPENMAILBOX)))
		  (SELECTC (fetch RETURNCODE of INBOXRESULT)
			   [\RC.NAMEANDPASSWORDVALID (RETURN (create OPENEDMAILBOX
								     MAILBOX ← MAILBOX
								     #OFMESSAGES ←(fetch #OFMESSAGES
										     of INBOXRESULT]
			   (\RC.NAMEISGROUP)
			   (\RC.NAMENOTREGISTERED (printout PROMPTWINDOW T NAME 
						       " not a registered in GV naming database."))
			   (\RC.COMMUNICATIONFAILURE (printout PROMPTWINDOW T 
			"Communications failure reported by GV while trying to open an inbox for"
							       T NAME ".  Please try again later."))
			   (\RC.INVALIDPASSWORD (printout T PROMPTWINDOW "Password invalid for user " 
							  NAME "."))
			   NIL))
		(T (printout PROMPTWINDOW T HOSTNAME " is busy - please try again later."])

(GV.NEXTMESSAGE
  [LAMBDA (MAILBOX)                                          (* DECLARATIONS: (RECORD (ANOTHERMESSAGE? ARCHIEVED? 
							     DELETED?)))
                                                             (* M.Yonke "10-AUG-83 12:19")
    (PROG (RESULT)
          (SETQ RESULT (MS.RETRIEVEOPERATION \OP.NEXTMESSAGE MAILBOX NIL (FUNCTION \RESPTONEXTMESSAGE)
					     ))
          (if (fetch ANOTHERMESSAGE? of RESULT)
	      then (RETURN (create NEXTMESSAGE
				   ARCHIEVEDFLG ←(fetch ARCHIEVED? of RESULT)
				   DELETEDFLG ←(fetch DELETED? of RESULT])

(GV.RETRIEVEMESSAGE
  [LAMBDA (MAILBOX MSGOUTFILE)                               (* M.Yonke "25-MAY-83 17:11")
    (PROG [(MSGOUTSTREAM (GETSTREAM MSGOUTFILE (QUOTE OUTPUT]
          (DECLARE (SPECVARS MSGOUTSTREAM))
          (RETURN (if (NLSETQ (MS.RETRIEVEOPERATION \OP.READMESSAGE MAILBOX NIL
						    (FUNCTION \RESPTORETRIEVEMESSAGE)))
		      then                                   (* presumably if an error didn't occur then we made it 
							     *)
			   T
		    else NIL])

(GV.CLOSEMAILBOX
  [LAMBDA (MAILBOX FLUSHP)                                   (* bvm: "22-SEP-83 15:25")
    [COND
      (FLUSHP (MS.RETRIEVEOPERATION \OP.FLUSH MAILBOX NIL (FUNCTION \RECEIVEACK]
    (CLOSEBSPSTREAM (fetch GVINSTREAM of MAILBOX)
		    \ETHERTIMEOUT])
)

(ADDTOVAR MAILSERVERTYPES (GV GV.POLLNEWMAIL GV.OPENMAILBOX GV.NEXTMESSAGE GV.RETRIEVEMESSAGE 
			      GV.CLOSEMAILBOX GV.PORTFROMNAME))



(* Other ops someone might want)

(DEFINEQ

(GV.READTOC
  [LAMBDA (MAILBOX)                                          (* M.Yonke "25-MAY-83 14:37")
    (MS.RETRIEVEOPERATION \OP.READTOC MAILBOX NIL (FUNCTION \RECEIVESTRING])

(GV.WRITETOC
  [LAMBDA (MAILBOX REMARK)                                   (* M.Yonke "25-MAY-83 14:37")
    (MS.RETRIEVEOPERATION \OP.WRITETOC MAILBOX (LIST REMARK)
			  (FUNCTION \RECEIVEACK])

(GV.DELETEMESSAGE
  [LAMBDA (MAILBOX)                                          (* M.Yonke "25-MAY-83 14:37")
    (MS.RETRIEVEOPERATION \OP.DELETEMESSAGE MAILBOX NIL (FUNCTION \RECEIVEACK])
)



(* The low-level Mail Retrieval Protocol functions *)

(DEFINEQ

(MS.RETRIEVEOPERATION
  [LAMBDA (OP MAILBOX ARGS RESPONSEFN)                       (* M.Yonke "25-MAY-83 11:55")

          (* * basic workhorse for communicating with a mail server -
	  sends an OP and ARGS to MAILBOX and fields a response, if appropriate)


    (PROG ((OUTSTREAM (fetch GVOUTSTREAM of MAILBOX)))
          (\SENDWORD OUTSTREAM OP)
          (for E in ARGS do (\SENDITEM OUTSTREAM E))
          (BSPFORCEOUTPUT OUTSTREAM)
          (RETURN (COND
		    (RESPONSEFN (APPLY* RESPONSEFN (fetch GVINSTREAM of MAILBOX)))
		    (T T])

(\CONNECTTOMAILSERVER
  [LAMBDA (PORT)                                             (* M.Yonke "25-MAY-83 11:33")
                                                             (* Open a BSP connection to mail server)
    (\OPENMAILSERVER PORT \MAILSERVERPOLLINGSOC \MAILSERVERRETRIEVALSOC \MAILIOTIMEOUT])

(\OPENMAILSERVER
  [LAMBDA (PORT POLLSOC CONNSOC TIMEOUT)                     (* M.Yonke "26-MAY-83 10:47")

          (* EchoMe polling to determine responsiveness is to POLLSOC, connection will go to CONNSOC.
	  We poll in order from nearest to farest by hop order, use broadcast on local net if appropriate, and hope not to 
	  engage too many folks before the real thing comes along. The basic structure of this is owed to Taft)


    (COND
      (PORT (PROG ((SOC (\GETMISCSOCKET))
		   (OUTPUP (ALLOCATE.PUP))
		   INPUP)                                    (* This sends out an echoMe packet to poll MS)
	          (SETUPPUP OUTPUP (CAR PORT)
			    (OR POLLSOC (CDR PORT)
				\MAILSERVERPOLLINGSOC)
			    \PT.ECHOME NIL SOC)
	          (RETURN (COND
			    ((AND (SETQ INPUP (EXCHANGEPUPS SOC OUTPUP NIL T))
				  (EQ (fetch PUPTYPE of INPUP)
				      \PT.IAMECHO)
				  (\OPENGVCONNECTION (CONS (fetch PUPSOURCE of INPUP)
							   (OR CONNSOC
							       (fetch PUPSOURCESOCKET of INPUP)))
						     TIMEOUT])

(\RESPTOOPENMAILBOX
  [LAMBDA (INSTREAM)                                         (* bvm: "11-MAY-83 15:55")
    (LIST (\BIN INSTREAM)
	  (\WIN INSTREAM])

(\RESPTONEXTMESSAGE
  [LAMBDA (INSTREAM)                                         (* bvm: "11-MAY-83 15:55")
    (LIST (\RECEIVEBOOL INSTREAM)
	  (\RECEIVEBOOL INSTREAM)
	  (\RECEIVEBOOL INSTREAM])

(\RESPTORETRIEVEMESSAGE
  [LAMBDA (INSTREAM)                                         (* bvm: "21-Feb-84 12:38")
    (until (\EOFP INSTREAM) do (\RECEIVEMESSAGEITEM INSTREAM) finally (BSPGETMARK INSTREAM])

(\RECEIVEMESSAGEITEM
  [LAMBDA (STREAM)                                           (* bvm: "21-Feb-84 12:42")

          (* * Ignores all items except of type text -- e.g. the message * *)


    (DECLARE (USEDFREE MSGOUTSTREAM))
    (PROG ((W (\RECEIVEWORD STREAM))
	   (LW (\RECEIVELONGWORD STREAM)))
      RETRY
          [SELECTC W
		   [\I.TEXT (to LW do (\OUTCHAR MSGOUTSTREAM (BIN STREAM]
		   (COND
		     ((EQ PUPTRACEFLG T)
		       (printout PUPTRACEFILE "FIELD " W T)
		       (to LW bind (PUPSTREAM ←(\GETSTREAM PUPTRACEFILE (QUOTE OUTPUT)))
			  do (\OUTCHAR PUPSTREAM (BIN STREAM)))
		       (TERPRI PUPTRACEFILE))
		     (T (to LW do (BIN STREAM]
          (COND
	    ((ODDP LW)
	      (BIN STREAM)))
          (RETURN W])

(\RECEIVELONGWORD
  [LAMBDA (STREAM)                                           (* bvm: "11-MAY-83 14:49")
                                                             (* Read a 32-bit number, low-word is first)
    (PROG ((LO (\WIN STREAM))
	   (HI (\WIN STREAM)))
          (RETURN (\MAKENUMBER HI LO])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY 
(* FOLLOWING DEFINITIONS EXPORTED)


[DECLARE: EVAL@COMPILE 

(RECORD MAILPORT (HOST# . SOCKET#))

(RECORD OPENEDMAILBOX (MAILBOX . PROPERTIES)
		      (PROPRECORD PROPERTIES (#OFMESSAGES)))

(PROPRECORD NEXTMESSAGE (ARCHIEVEDFLG DELETEDFLG LENGTH))
]


(* END EXPORTED DEFINITIONS)



(RPAQQ MAILCLIENTCONSTANTCOMS ((* Mail retrieval opcodes *)
			       (CONSTANTS (\OP.ADDRECIPIENT 21)
					  (\OP.ADDTOITEM 24)
					  (\OP.CHECKVALIDITY 22)
					  (\OP.HUMANMESS 520)
					  (\OP.MSEXPAND 27)
					  (\OP.SEND 26)
					  (\OP.STARTITEM 23)
					  (\OP.STARTSEND 20))
			       (CONSTANTS (\MAILSOCKETTIMEOUT 36000000))
			       (* Mail sender opcodes *)
			       (CONSTANTS (\OP.OPENINBOX 0)
					  (\OP.NEXTMESSAGE 1)
					  (\OP.READTOC 2)
					  (\OP.READMESSAGE 3)
					  (\OP.WRITETOC 4)
					  (\OP.DELETEMESSAGE 5)
					  (\OP.FLUSH 6))
			       (* return codes from "start to send a message" *)
			       (CONSTANTS (\RC.SENDSTARTED 0)
					  (\RC.PASSWORDINVALID 1)
					  (\RC.SENDERNOTREGISTERED 2)
					  (\RC.RETURNTONOTREGISTERED 3)
					  (\RC.COMMUNICATIONFAILURE 4))
			       (* return codes from "open mail box" *)
			       (CONSTANTS (\RC.NAMEISGROUP 1)
					  (\RC.NAMEANDPASSWORDVALID 2)
					  (\RC.NAMENOTREGISTERED 3)
					  (\RC.COMMUNICATIONFAILURE 4)
					  (\RC.INVALIDPASSWORD 5))
			       (* Message Item types *)
			       (CONSTANTS (\I.POSTMARK 8)
					  (\I.SENDER 16)
					  (\I.RETURNTO 24)
					  (\I.RECIPIENTS 32)
					  (\I.TEXT 520)
					  (\I.END 65535))
			       (CONSTANTS (\PT.LAURELCHECK 140)
					  (\PT.NOMAILBOX 139)
					  (\PT.NONEWMAIL 138)
					  (\PT.NEWMAIL 137))))



(* Mail retrieval opcodes *)

(DECLARE: EVAL@COMPILE 

(RPAQQ \OP.ADDRECIPIENT 21)

(RPAQQ \OP.ADDTOITEM 24)

(RPAQQ \OP.CHECKVALIDITY 22)

(RPAQQ \OP.HUMANMESS 520)

(RPAQQ \OP.MSEXPAND 27)

(RPAQQ \OP.SEND 26)

(RPAQQ \OP.STARTITEM 23)

(RPAQQ \OP.STARTSEND 20)

(CONSTANTS (\OP.ADDRECIPIENT 21)
	   (\OP.ADDTOITEM 24)
	   (\OP.CHECKVALIDITY 22)
	   (\OP.HUMANMESS 520)
	   (\OP.MSEXPAND 27)
	   (\OP.SEND 26)
	   (\OP.STARTITEM 23)
	   (\OP.STARTSEND 20))
)
(DECLARE: EVAL@COMPILE 

(RPAQQ \MAILSOCKETTIMEOUT 36000000)

(CONSTANTS (\MAILSOCKETTIMEOUT 36000000))
)



(* Mail sender opcodes *)

(DECLARE: EVAL@COMPILE 

(RPAQQ \OP.OPENINBOX 0)

(RPAQQ \OP.NEXTMESSAGE 1)

(RPAQQ \OP.READTOC 2)

(RPAQQ \OP.READMESSAGE 3)

(RPAQQ \OP.WRITETOC 4)

(RPAQQ \OP.DELETEMESSAGE 5)

(RPAQQ \OP.FLUSH 6)

(CONSTANTS (\OP.OPENINBOX 0)
	   (\OP.NEXTMESSAGE 1)
	   (\OP.READTOC 2)
	   (\OP.READMESSAGE 3)
	   (\OP.WRITETOC 4)
	   (\OP.DELETEMESSAGE 5)
	   (\OP.FLUSH 6))
)



(* return codes from "start to send a message" *)

(DECLARE: EVAL@COMPILE 

(RPAQQ \RC.SENDSTARTED 0)

(RPAQQ \RC.PASSWORDINVALID 1)

(RPAQQ \RC.SENDERNOTREGISTERED 2)

(RPAQQ \RC.RETURNTONOTREGISTERED 3)

(RPAQQ \RC.COMMUNICATIONFAILURE 4)

(CONSTANTS (\RC.SENDSTARTED 0)
	   (\RC.PASSWORDINVALID 1)
	   (\RC.SENDERNOTREGISTERED 2)
	   (\RC.RETURNTONOTREGISTERED 3)
	   (\RC.COMMUNICATIONFAILURE 4))
)



(* return codes from "open mail box" *)

(DECLARE: EVAL@COMPILE 

(RPAQQ \RC.NAMEISGROUP 1)

(RPAQQ \RC.NAMEANDPASSWORDVALID 2)

(RPAQQ \RC.NAMENOTREGISTERED 3)

(RPAQQ \RC.COMMUNICATIONFAILURE 4)

(RPAQQ \RC.INVALIDPASSWORD 5)

(CONSTANTS (\RC.NAMEISGROUP 1)
	   (\RC.NAMEANDPASSWORDVALID 2)
	   (\RC.NAMENOTREGISTERED 3)
	   (\RC.COMMUNICATIONFAILURE 4)
	   (\RC.INVALIDPASSWORD 5))
)



(* Message Item types *)

(DECLARE: EVAL@COMPILE 

(RPAQQ \I.POSTMARK 8)

(RPAQQ \I.SENDER 16)

(RPAQQ \I.RETURNTO 24)

(RPAQQ \I.RECIPIENTS 32)

(RPAQQ \I.TEXT 520)

(RPAQQ \I.END 65535)

(CONSTANTS (\I.POSTMARK 8)
	   (\I.SENDER 16)
	   (\I.RETURNTO 24)
	   (\I.RECIPIENTS 32)
	   (\I.TEXT 520)
	   (\I.END 65535))
)
(DECLARE: EVAL@COMPILE 

(RPAQQ \PT.LAURELCHECK 140)

(RPAQQ \PT.NOMAILBOX 139)

(RPAQQ \PT.NONEWMAIL 138)

(RPAQQ \PT.NEWMAIL 137)

(CONSTANTS (\PT.LAURELCHECK 140)
	   (\PT.NOMAILBOX 139)
	   (\PT.NONEWMAIL 138)
	   (\PT.NEWMAIL 137))
)
)
(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY 
(FILESLOAD (LOADCOMP)
	   GRAPEVINE PUP BSP)
)
(PUTPROPS MAILCLIENT COPYRIGHT ("Xerox Corporation" 1983 1984))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2050 5340 (GV.STARTSEND 2060 . 2997) (GV.ADDRECIPIENT 2999 . 3189) (GV.CHECKVALIDITY 
3191 . 3390) (GV.STARTITEM 3392 . 3714) (GV.ADDTOITEM 3716 . 4818) (GV.SEND 4820 . 4993) (MS.EXPAND 
4995 . 5338)) (5370 8877 (MS.SENDOPERATION 5380 . 6187) (\FINDMAILSERVER 6189 . 6642) (
\MAILSERVERSOCKETS 6644 . 7124) (\RECEIVEACK 7126 . 7415) (\RESPTOCHECKVAL 7417 . 7906) (\RESPTOEXPAND
 7908 . 8439) (\RESPTOSTARTSEND 8441 . 8875)) (9407 13432 (GV.PORTFROMNAME 9417 . 9610) (
GV.POLLNEWMAIL 9612 . 10674) (GV.OPENMAILBOX 10676 . 11995) (GV.NEXTMESSAGE 11997 . 12618) (
GV.RETRIEVEMESSAGE 12620 . 13141) (GV.CLOSEMAILBOX 13143 . 13430)) (13617 14229 (GV.READTOC 13627 . 
13818) (GV.WRITETOC 13820 . 14025) (GV.DELETEMESSAGE 14027 . 14227)) (14292 17993 (
MS.RETRIEVEOPERATION 14302 . 14891) (\CONNECTTOMAILSERVER 14893 . 15212) (\OPENMAILSERVER 15214 . 
16285) (\RESPTOOPENMAILBOX 16287 . 16448) (\RESPTONEXTMESSAGE 16450 . 16654) (\RESPTORETRIEVEMESSAGE 
16656 . 16884) (\RECEIVEMESSAGEITEM 16886 . 17674) (\RECEIVELONGWORD 17676 . 17991)))))
STOP