1 HIGHER-LEVEL NS PROTOCOL FUNCTIONS The following is a description of the Interlisp-D facilities for using Xerox SPP and Courier protocols and the services based on them. 1.1 SPP Stream Interface This section describes the stream interface to the Sequenced Packet Protocol. (SPP.OPEN HOST SOCKET PROBEP NAME) This function is used to open an SPP stream. If HOST is specified, an SPP connection is initiated to HOST with remote socket SOCKET. If both HOST and PROBEP are specified, then the connection is probed for a response before returning the stream; NIL is returned if HOST doesn't respond. If HOST is NIL, a passive connection is created which listens for an incoming connection to local socket SOCKET. NAME is a mnemonic name for the connection process, mainly useful for debugging. The function returns an SPP stream, for which the standard stream operations BIN, BOUT, CLOSEF, and EOFP are defined. In particular, COPYBYTES may be used on SPP streams. The SPP stream that is returned is open for both input and output, since SPP connections are bidirectional. However, the underlying stream I/O functions use only a single buffer. Some care must therefore be exercised to insure that any buffered output data is forced out before any new data is read, and that all data up to a message boundary has been read before any new data is written. Functions described below are used for this purpose. While these restrictions may seem severe, in practice most use of SPP streams is done by the Courier remote procedure call facility, rather than directly by the programmer. Courier conforms to the model of alternating exchanges of messages quite well. SPP.USER.TIMEOUT Specifies the time, in milliseconds, to wait before deciding that a host isn't responding. (SPP.FLUSH STREAM) This function forces any buffered output data to be transmitted. (SPP.SENDEOM STREAM) This function forces out any buffered data and causes an End of Message indication to be sent. (SPP.CLOSE STREAM ABORT?) This function closes an SPP stream using the reliable termination protocol. If ABORT? is not NIL, the stream is closed even if there is an outstanding bulk data transfer in progress. (SPP.DSTYPE STREAM DSTYPE) This function gets or sets the current datastream type. If DSTYPE is specified, all subsequent packets that are sent will be of this datastream type, until the next call to SPP.DSTYPE. Since this affects the current partially-filled packet, the stream should probably be flushed (via SPP.FLUSH) before this function is called. If DSTYPE is not specified, this function returns the datastream type of the current packet being read. (SPP.READP STREAM) This function returns T or NIL depending on whether or not there is data to be read without waiting. (SPP.EOFP STREAM) This function returns T or NIL depending on whether or not the connection has been closed. (SPP.EOMP STREAM) This function returns T or NIL depending on whether or not an End of Message indication has been reached. This will only be true after the last byte of data in the message has been read. 1.2 Courier Remote Procedure Call Protocol (COURIER.OPEN HOSTNAME SERVERTYPE NOERRORFLG NAME) This function opens a Courier connection to the specified HOST and returns an SPP stream. If HOST is a LITATOM, string, or list representation of a Clearinghouse name, SERVERTYPE should specify what type of server HOST is, so that the name may be looked up in the Clearinghouse database. Currently, SERVERTYPE must be one of PRINTSERVER or FILESERVER. Normally, this function will retry the connection \MAXETHERTRIES times before generating an error. If NOERRORFLG is specified, NIL will be returned if the connection fails. The Courier connection will be given NAME, if specified. (COURIERPROGRAM NAME ...) This function is used to define Courier programs. The syntax is (COURIERPROGRAM name (programNumber versionNumber) TYPES ((typeName typeDefinition) ...) PROCEDURES ((procedureName ARGS (argType ...) RESULTS (resultType ...) ERRORS (errorName ...) procedureNumber) ...) ERRORS ((errorName ARGS (argType ...) errorNumber) ...)) ) Type definitions are written in the Courier template language, described below. Courier types may either be type names that are defined in the current Courier program, qualified names of the form (otherCourierProgram . typeName), or explicit definitions in the template language. 1.2.1 Courier Template Language This section describes how Courier types are described in Interlisp, and how corresponding values are represented. (See also the Courier protocol definition.) Predefined types: BOOLEAN is represented by T and NIL. CARDINAL is represented by integers. INTEGER is represented by integers. LONGCARDINAL is represented by integers. LONGINTEGER is represented by integers. STRING is represented by strings. UNSPECIFIED is represented by integers. Constructed types: (ENUMERATION (NAME VALUE) ... (NAME VALUE)) (ARRAY LENGTH TYPE) (SEQUENCE TYPE) (RECORD (NAME TYPE) ... (NAME TYPE)) (CHOICE (NAME VALUE TYPE) ... (NAME VALUE TYPE)) Representation of constructed types in Lisp: Objects of Courier type (ENUMERATION (UNKNOWN 0) (RED 1) (BLUE 2)) are represented by the LITATOMs UNKNOWN, RED, and BLUE. Objects of Courier type (ARRAY 3 INTEGER) are represented by lists of three integers, such as (10 1 59). Objects of Courier type (SEQUENCE BOOLEAN) are represented by arbitrary-length lists of T and NIL, such as (NIL T T NIL T). Objects of Courier type (RECORD (NETWORK LONGCARDINAL) (HOST (ARRAY 3 CARDINAL)) (SOCKET CARDINAL)) are represented by lists like ((NETWORK 174) (HOST (100 24 363)) (SOCKET 20)). Objects of Courier type (CHOICE (STATUS 0 (ENUMERATION (BUSY 0) (COMPLETE 1))) (MESSAGE 1 STRING)) are represented by lists like (STATUS COMPLETE) or (MESSAGE "Your request has completed."). (COURIER.CALL STREAM PROGRAM PROCEDURE ARG1 ... ARGn NOERRORFLG) This function calls the remote procedure PROCEDURE of the Courier program PROGRAM. STREAM is the SPP stream returned by COURIER.OPEN. The arguments should be Lisp values appropriate for the Courier types of the corresponding formal parameters of the procedure (defined under the ARGS property for the procedure). Returns results of the Courier types defined under the RESULTS property. If there is only a single result, it is returned, otherwise a list of results is returned. The NOERRORFLG argument controls the treatment of remote errors. If NOERRORFLG is NIL, a Lisp error will be generated. If NOERRORFLG is T, NIL will be returned as the result of the call. If NOERRORFLG is RETURNERRORS, the result of the call will be a list consisting of the atom ERROR followed by the Courier name of the error and any arguments. Examples: (COURIERPROGRAM EXAMPLEPROGRAM (17 1) TYPES ((PERSON.NAME (RECORD (FIRST.NAME STRING) (MIDDLE (CHOICE (NAME 0 STRING) (INITIAL 1 STRING))) (LAST.NAME STRING))) (BIRTHDAY (RECORD (YEAR CARDINAL) (MONTH STRING) (DAY CARDINAL)))) PROCEDURES ((GETBIRTHDAY ARGS (PERSON.NAME) RESULTS (BIRTHDAY) 3)) ) Defines EXAMPLEPROGRAM to be Courier program number 17, version number 1. The example defines two types, PERSON.NAME and BIRTHDAY, and one procedure, GETBIRTHDAY, whose procedure number is 3. The following code could be used to call the remote GETBIRTHDAY procedure on the host with address HOSTADDRESS. (SETQ STREAM (COURIER.OPEN HOSTADDRESS)) (COURIER.CALL STREAM (QUOTE EXAMPLEPROGRAM) (QUOTE GETBIRTHDAY) (QUOTE ((FIRST.NAME "Eric") (MIDDLE (INITIAL "C")) (LAST.NAME "Cooper")))) COURIER.CALL in this example will return a value such as ((YEAR 1959) (MONTH "January") (DAY 10)) 1.2.2 Manipulating Courier Representations Several Courier programs use values of type (SEQUENCE UNSPECIFIED) to handle user-defined or otherwise extensible object types. Often it is necessary to convert between a list of 16 bit words (the sequence of UNSPECIFIEDs) and a Courier value. The following function should be used for this purpose. (COURIER.READ.REP LIST.OF.WORDS PROGRAM TYPE) This function returns the Lisp representation of the Courier object of type TYPE defined in the Courier program PROGRAM whose underlying Courier representation is LIST.OF.WORDS. 1.2.3 Using Bulk Data Transfer with Courier Two Courier types are treated specially when they appear in the argument list of a procedure. They are BULK.DATA.SINK and BULK.DATA.SOURCE. A Courier procedure may have at most one such sink or source parameter. The result of a COURIER.CALL on such a procedure is an SPP stream, open for input or output according to whether the bulk data paramter is a sink or a source. The client uses this stream to receive or send the appropriate bulk data object. If the object consists of bytes, this may be done with the usual stream I/O functions such as COPYBYTES. If the data is a stream of Courier objects, the following function should be used. (COURIER.READ.BULKDATA STREAM PROGRAM TYPE) STREAM is the bulk data stream returned from COURIER.CALL. TYPE is the type of each Courier object in the stream. PROGRAM is the Courier program in which TYPE is defined. A list of objects of Courier type TYPE will be returned. The observant reader may wonder what happens if the Courier procedure returns one or more results, in addition to taking a bulk data parameter. If a bulk data stream is returned to the caller, what happens to the results? The answer is that the results are collected when the bulk data stream is closed, after the client has transferred the bulk data. The disposition of these results depends on what actual parameter is supplied for the formal bulk data parameter at the time of the call. If it is NIL, the results, if any, will be ignored. Otherwise, the value is assumed to be a function which to be applied to the results. A FUNARG may be used for full generality. For example, the Courier procedure to print an Interpress master uses a bulk data source to transfer the master, and also returns a request identifier. The Lisp function which performs the COURIER.CALL passes a functional to be called on this request identifier after the stream is closed and printing begins; this functional in turn spawns a process which monitors the progress of the job. (COURIERTRACE FLG REGION) This function controls the tracing of Courier remote procedure calls. It is similar to PUPTRACE and XIPTRACE, but operates at the call/return level rather than the packet level. 1.3 NS Printing This section describes the facilities that are available for printing Interpress masters on NS printservers. NS.DEFAULT.PRINTER The value of this variable is used whenever no printserver is specified for the functions described below. If its value is a LITATOM, string, or Clearinghouse name, the Clearinghouse is queried to find the address of the printserver with that name. If its value is NIL, it will be set automatically to some printserver in the local Clearinghouse domain. In environments where there is no Clearinghouse, the value of NS.DEFAULT.PRINTER must be an appropriate NSADDRESS record. (OPEN.NS.PRINTING.STREAM PRINTER DOCUMENT.NAME DOCUMENT.CREATION.DATE SENDER.NAME RECIPIENT.NAME #COPIES MEDIUM PRIORITY STAPLE? TWO.SIDED? NOWATCHDOG?) This function returns a stream for printing an Interpress master on PRINTER or on NS.DEFAULT.PRINTER as mentioned above. The caller should write the Interpress data to the stream and then close it using CLOSEF. Printing begins after the stream is closed. DOCUMENT.NAME is the document name to appear on the header page (a string). DOCUMENT.CREATION.DATE is the creation date to appear on the header page (a Lisp integer date). The default value is the time of the call. SENDER.NAME is the name of the sender to appear on the header page (a string). The default value is the name of the user. RECIPIENT.NAME is the name of the recipient to appear on the header page (a string). The default value is the name of the user. #COPIES is the number of copies to be printed. The default value is 1. MEDIUM is the medium on which the master is to be printed. This must be a Courier value of type MEDIUM, which is a list of the form (PAPER (KNOWN.SIZE NAME)), where NAME is one of the LITATOMs US.LETTER, US.LEGAL, A0 through A10, ISO.B0 through ISO.B10, and JIS.B0 through JIS.B10. The default value is determined by the printer. PRIORITY is the priority of this print request (LOW, NORMAL, or HIGH). The default value is NORMAL. STAPLE? is T or NIL depending on whether the document should be stapled. The default value is NIL. TWO.SIDED? is T or NIL depending on whether the document should be printed on two sides. The default value is NIL. NOWATCHDOG? is non-NIL if the client does not want a watchdog process to monitor the status of the printing job. (NSPRINT PRINTER FILE.NAME DOCUMENT.NAME DOCUMENT.CREATION.DATE SENDER.NAME RECIPIENT.NAME #COPIES MEDIUM PRIORITY STAPLE? TWO.SIDED?) This function prints an Interpress master on PRINTER or on NS.DEFAULT.PRINTER as mentioned above. FILE.NAME should be the name of an Interpress file to be printed. The remaining arguments are all optional, and are as described for OPEN.NS.PRINTING.STREAM above. DOCUMENT.NAME defaults to the full name of the file, and DOCUMENT.CREATION.DATE defaults to the creation date of the file. (NSPRINTER.STATUS PRINTER) This function returns the Courier value resulting from the GET.PRINTER.STATUS call. (NSPRINTER.PROPERTIES PRINTER) This function returns the Courier value resulting from the GET.PRINTER.PROPERTIES call. 1.4 Clearinghouse This section describes functions that may be used to access Clearinghouse servers. Note that these functions are used by the NS printing functions if the printserver is specified by name rather than address. (START.CLEARINGHOUSE RESTARTFLG) This function enables Clearinghouse access. It performs an expanding ring broadcast in order to find the first Clearinghouse server. If RESTARTFLG is non-NIL, the cache of Clearinghouse information is invalidated and a new broadcast is done. This may be necessary if the local Clearinghouse server goes down. CH.NET.HINT Hint as to which network the local Clearinghouse server is on, for use by START.CLEARINGHOUSE above. If CH.NET.HINT is bound to a network number, that network will be tried first, followed by the others in the routing table. If the local Clearinghouse server is not on the directly connected network, setting CH.NET.HINT to the proper network number in the local INIT file will speed up START.CLEARINGHOUSE considerably. (SHOW.CLEARINGHOUSE) This function displays the structure of the cached Clearinghouse information in a window. Once created, it will be redisplayed whenever the cache is updated. The structure is shown using GRAPHER". (SHOW.ENTIRE.CLEARINGHOUSE) This function attempts to cache information about all the Clearinghouse domains, so that the Clearinghouse structure window will show the entire database. CH.DEFAULT.DOMAIN This is a string specifying the default Clearinghouse domain. If it is NIL, it will be set automatically by START.CLEARINGHOUSE. Otherwise, it should be set in an INIT file. CH.DEFAULT.ORGANIZATION This is a string specifying the default Clearinghouse organization. If it is NIL, it will be set automatically by START.CLEARINGHOUSE. Otherwise, it should be set in an INIT file. (CH.ORGANIZATIONS ORGANIZATIONPATTERN) This function returns the list of organization names in the Clearinghouse database matching ORGANIZATIONPATTERN. The default pattern is "*", which matches anything. (CH.DOMAINS DOMAINPATTERN) This function returns the list of domain names in the Clearinghouse database matching DOMAINPATTERN. The default pattern is "*", which matches anything. (CH.ENUMERATE OBJECTPATTERN PROPERTY) This function returns the list of object names matching OBJECTPATTERN and having the property PROPERTY. Currently, PROPERTY must be one of USER, PRINTSERVER, FILESERVER, and ALL. For example, (CH.ENUMERATE "*:PARC:Xerox" (QUOTE USER)) will return a list of the names of users at Xerox PARC. (CH.LOOKUP.USER NAME) This function returns the user information for the first user whose name matches NAME. (LOOKUP.NS.SERVER NAME TYPE) This function returns the NSADDRESS for the first server whose name matches NAME and has the property TYPE, which must be PRINTSERVER or FILESERVER. 1.5 NS Filing This section describes functions that may be used to access NS fileservers. 1.5.1 Pathnames and NS Fileservers The NS Filing protocol does not support conventional file system pathnames directly. However, the Interlisp-D software that supports access to NS fileservers uses IFS-style pathnames and does the appropriate mapping in software. One important difference, however, is that fileserver, directory, and file names may have spaces in them, each of which must be preceded by a percent sign. The name of an NS fileserver is required to have a colon in it. Thus, even if the fileserver is in the local Clearinghouse domain, a trailing colon should be appended to the name. Case is not significant. For example, {LISPFILE:}<LISPDRAWER>XYZ;3 is a valid name for a file on the NS fileserver "LispFile:Parc Place:Xerox". (NSDIRECTORY PATTERN) This function returns a list of file names in PATTERN, which must be the NS pathname for a directory. (Any wildcards in the name field of the pathname are ignored.) (NSCREATEDIRECTORY HOST/DIR) This function creates a new directory with pathname HOST/DIR. Top level directories ("file drawers") cannot be created in this way. (CLOSE.NSFILING.CONNECTIONS) This function closes any open connections to NS fileservers.