{Begin SubSec Higher-level NS Protocol Functions}
{Title Higher-level NS Protocol Functions}
{Text

The following is a description of the Interlisp-D facilities for using Xerox SPP and Courier protocols and the services based on them.

{begin subsec Name and Address Conventions}
{title Name and Address Conventions}
{text

Addresses of hosts in the NS world consist of three parts, a network number, a machine number, and a socket number.  These three parts are embodied in the Interlisp-D datatype {term {Lisp NSADDRESS}}.  Objects of type {Lisp NSADDRESS} print as "net#h1.h2.h3#socket", where all the numbers are printed in octal radix, and the 48-bit host number is broken into 3 16-bit fields.  Most functions that accept an address argument will accept either an {Lisp NSADDRESS} object, or a string that is the printed representation of the address.

Higher-level functions accept host arguments in the form of a symbolic name for the host.  The NS world has a hierarchical name space.  Each object name is in three parts: the {it Organization}, the {it Domain}, and the {it Object} parts.  There can be many domains in a single organization, and many objects in a single domain.  The name space is maintained by the {it Clearinghouse}{index Clearinghouse *primary*}, a distributed network database service.

A Clearinghouse name is standardly notated as {it object}:{it domain}:{it organization}.  The parts {it organization} or {it domain}:{it organization} may be omitted if they are the default (see below).  Alphabetic case is not significant.  Internally, names are represented as objects of datatype {term {lisp NSNAME}}, but most functions accept the textual representation as well, either as a litatom or a string.  Objects of type {lisp NSNAME} print as {it object}:{it domain}:{it organization}, with fields omitted when they are equal to the default.  A {it Domain} is standardly represented as an {lisp NSNAME} in which the object part is null.  If frequent use is to be made of an NS name, it is generally preferable to convert it to an {lisp NSNAME} once, by calling {fn PARSE.NSNAME}, then passing the resultant object to all functions desiring it.

{vardef {name CH.DEFAULT.ORGANIZATION}
{text
This is a string specifying the default Clearinghouse organization.
}}

{vardef {name CH.DEFAULT.DOMAIN}
{text
This is a string specifying the default Clearinghouse domain. If it or {var CH.DEFAULT.ORGANIZATION} is {lisp NIL}, they are set by Lisp system code (when they are needed) to be the first domain served by the nearest Clearinghouse server.
}}

In small organizations with just one domain, it is reasonable to just leave these variables {lisp NIL} and have the system set them appropriately.  In organizations with more than one domain, it is wise to set them in your site initialization file, so as not to be dependent on exactly which Clearinghouse servers are up at any time.

{fnDef {name PARSE.NSNAME}{args NAME #PARTS DEFAULTDOMAIN}
{text
When {arg #PARTS} is 3 (or {lisp NIL}), parses {arg NAME}, a litatom or string, into its three parts, returning an object of type {lisp NSNAME}.  If the domain or organization is omitted, defaults are supplied, either from {arg DEFAULTDOMAIN} (an {lisp NSNAME} whose domain and organization fields only are used) or from the variables {var CH.DEFAULT.DOMAIN} and {var CH.DEFAULT.ORGANIZATION}.

If {arg #PARTS} is 2, {arg NAME} is interpreted as a domain name, and an {lisp NSNAME} with null object is returned.  In this case, if {arg NAME} is a full 3-part name, the object part is stripped off.

If {arg #PARTS} is 1, {arg NAME} is interpreted as an organization name, and a simple string is returned.  In this case, if {arg NAME} is a 2- or 3-part name, the organization is extracted from it.

If {arg NAME} is already an object of type {lisp NSNAME}, then it is returned as is (if {arg #PARTS} is 3), or its domain and/or organization parts are extracted (if {arg #PARTS} is 1 or 2).
}}

{fndef {name NSNAME.TO.STRING} {args NSNAME FULLNAMEFLG}
{text
Converts {arg NSNAME}, an object of type {lisp NSNAME}, to its string representation.  If {arg FULLNAMEFLG} is true, the full printed name is returned; otherwise, fields that are equal to the default are omitted.
}}

Programmers who wish to manipulate {lisp NSADDRESS} and {lisp NSNAME} objects directly should load the Library package {lisp ETHERRECORDS}.

}{end subsec Name and Address Conventions}

{begin subsec SPP Stream Interface}
{title SPP Stream Interface}
{text
This section describes the stream interface to the Sequenced Packet Protocol.

{fndef {name SPP.OPEN} {args HOST SOCKET PROBEP NAME WHENCLOSEDFN}
{text
This function is used to open a bidirectional SPP stream.  There are two cases: user and server.

User:  If {arg HOST} is specified, an SPP connection is initiated to {arg HOST}, an {lisp NSADDRESS} or string representing an NS address.  If the socket part of the address is null (zero), it is defaulted to {arg SOCKET}. If both {arg HOST} and {arg PROBEP} are specified, then the connection is probed for a response before returning the stream; {lisp NIL} is returned if {arg HOST} doesn't respond.

Server: If {arg HOST} is {lisp NIL}, a passive connection is created which listens for
an incoming connection to local socket {arg SOCKET}.

{fn SPP.OPEN} returns the input side of the bidirectional stream; the function {fn SPPOUTPUTSTREAM} is used to obtain the output side.  The standard stream operations {fn BIN}, {fn READP}, {fn EOFP} (on the input side), and {fn BOUT}, {fn FORCEOUTPUT} (on the output side), are defined on these streams, as is {fn CLOSEF}, which can be applied to either stream to close the connection.

{arg NAME} is a mnemonic name for the connection process, mainly useful for debugging.  {arg WHENCLOSEDFN} is an optional function or list of functions to call when the stream is closed, either by the user or the server.
}}

{fndef {name SPPOUTPUTSTREAM} {args STREAM}
{text
Applied to the input stream of an SPP connection, this function returns the corresponding output stream.
}}

{vardef {name SPP.USER.TIMEOUT}
{text
Specifies the time, in milliseconds, to wait before deciding that a host isn't responding.
}}


{fndef {name SPP.SENDEOM} {args STREAM}
{text
Transmits the data buffered so far on this output stream, if any, with the End of Message bit set.  If there is nothing buffered, a zero-length packet with End of Message bit set is sent.
}}

{fndef {name SPP.DSTYPE} {args STREAM DSTYPE}
{text
This function gets or sets the current datastream type of the connection.  If {arg DSTYPE} is specified, all subsequent packets that are sent will be of this datastream type, until the next call to {fn SPP.DSTYPE}. Since this affects the current  partially-filled packet, the stream should probably be flushed (via {fn FORCEOUTPUT}) before this function is called. If {arg DSTYPE} is not specified, this function simply returns the datastream type of the current packet being read.
}}


{fndef {name SPP.EOMP} {args STREAM}
{text
This function returns {lisp T} or {lisp 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.  By convention, {fn EOFP} is true of a stream that is at EOM.
}}

{fndef {name SPP.CLEAREOM} {args STREAM NOERRORFLG}
{text
Clears the End of Message indication on {arg STREAM}.  This is necessary in order to read beyond the EOM.  Causes an error if the stream is not currently at the End of Message, unless {arg NOERRORFLG} is true.
}}

{fndef {name SPP.SENDATTENTION} {args STREAM ATTENTIONBYTE}
{text
Sends an SPP "attention" packet, one with the Attention bit set and containing the single byte of data {arg ATTENTIONBYTE}.
}}

}{end subsec SPP Stream Interface}




{begin subsec Courier Remote Procedure Call Protocol}
{title Courier Remote Procedure Call Protocol}
{text

Courier{index Courier *Primary*} is the Xerox Network Systems Remote Procedure Call protocol.  It uses the Sequenced Packet Protocol for reliable transport.  Courier uses procedure call as a metaphor for the exchange of a request from a user process and its positive reply from a server process; exceptions or error conditions are the metaphor for a negative replay.  A family of remote procedures and the errors they can raise constitute a remote program.  A remote program generally represents a complete {it service}.  Examples of remote programs are Filing and Printing, described elsewhere in this chapter.

For more detail about the Courier protocol, the reader is referred to [4].  This section describes how to define a Courier program and use it to communicate with a remote system element that implements a server for that program.  The present Lisp implementation provides only for user access; construction of Courier servers will be possible in the future.

{begin subsec Defining Courier Programs}
{title Defining Courier Programs}
{text

A Courier program definition is a file package type and command, {filecom COURIERPROGRAMS}{index COURIERPROGRAMS *primary* FileCom}.  Thus, you can use {fn GETDEF}, {fn PUTDEF}, and {fn EDITDEF} to manipulate them, or use the file package command {lisp (COURIERPROGRAMS name1 name2 ...)} to save them.  The function {fn COURIERPROGRAM} can be used to define a Courier program initially.

{fndef {name COURIERPROGRAM} {args NAME {ellipsis}}
{type NLAMBDA NOSPREAD}
{text
This function is used to define Courier programs.  The syntax is

{lispcode (COURIERPROGRAM {arg NAME} ({arg PROGRAMNUMBER} . {arg VERSIONNUMBER})
   . {arg DEFINITIONS})}

The tail {arg DEFINITIONS} is a property list where the properties are selected from {lisp TYPES}, {lisp PROCEDURES}, {lisp ERRORS} and {lisp INHERITS}; the values are lists of pairs of the form ({arg LABEL} . {arg DEFINITION}).  These are described in more detail as follows:

The {lisp TYPES} section lists the symbolically-defined types used to represent the arguments and results of procedures and errors in this Courier program.  Each element in this section is of the form ({arg TYPENAME} {arg TYPEDEFINITION}), e.g., {lisp (PRIORITY INTEGER)}.  The {arg TYPEDEFINITION} can be a predefined type (see next section), another type defined in this {lisp TYPES} section, or an qualified typename taken from another Courier program; these latter are written as a dotted pair ({arg PROGRAMNAME} . {arg TYPENAME}).

The {lisp PROCEDURES} section lists the remote procedures defined by this Courier program.  A procedure definition is a stylized reduction of the Courier definition syntax defined in the Courier Protocol specification:

{lispcode ({arg PROCEDURENAME} {arg NUMBER} {arg ARGUMENTS}
           RETURNS {arg RESULTTYPES} REPORTS {arg ERRORNAMES})}

{arg ARGUMENTS} is a list of type names defined in the {lisp TYPES} section, one per argument to the remote procedure.  {arg RESULTTYPES} is a list of type names, one for each value to be returned.  {arg ERRORNAMES} is a list of names from the {lisp ERRORS} section of errors that can be raised by this procedure.  The atoms {lisp RETURNS} and {lisp REPORTS} are noise words to aid readability.

The {lisp ERRORS} section lists the errors that can be raised by procedures in this program.  An error definition is of the form

{lispcode ({arg ERRORNAME} {arg NUMBER} {arg ARGUMENTS})},

where {arg ARGUMENTS} is a list of type names, one for each argument, if any, reported by the error.

}{end subsec Defining Courier Programs}



{begin subsec Courier Type Definitions}
{title Courier Type Definitions}
{text

This section describes how the predefined Courier types described in the Courier Protocol document are expressed in a Lisp Courier program definition, and how values of each type are represented.

{begin subsec Primitive Types}
{title Primitive Types}
{text

Primitive types are expressed as uppercase litatoms from the following set:

{labeledlist

{name {lisp BOOLEAN}} {item Values are represented by {lisp T} and {lisp NIL}.}
{name {lisp INTEGER}} {item Values are represented as small integers in the range [-32768..32767].}
{name {lisp CARDINAL}} {item Values are represented as small integers in the range [0..65535].}
{name {lisp UNSPECIFIED}} {item Same as {lisp CARDINAL}.}
{name {lisp LONGINTEGER}} {item Values are represented as {lisp FIXP}'s.}
{name {lisp LONGCARDINAL}} {item Same as {lisp LONGINTEGER}.  Note that Interlisp-D does not (currently) have a datatype that truly represents a 32-bit {it unsigned} integer.}
{name {lisp STRING}} {item Values are represented as Lisp strings.}
}

In addition, the following types not in the document have been added for convenience:

{labeledlist

{name {lisp TIME}} {item Represents a date and time in accordance with the Network Time Standard.  The value is a {lisp FIXP} such as returned by the function {fn IDATE}, and is encoded as a {lisp LONGCARDINAL}.}

{name {lisp NSADDRESS}} {item Represents a network address.  The value is an object of type {Lisp NSADDRESS}{index NSADDRESS} ({SectionRef Term NSADDRESS}), and is encoded as six items of type {lisp UNSPECIFIED}.}

{name {lisp NSNAME}} {item Represents a three-part Clearinghouse name.  The value is an object of type {Lisp NSNAME}{index NSNAME} ({SectionRef Term NSNAME}), and is encoded as three items of type {lisp STRING}.}

{name {lisp NSNAME2}} {item Represents a two-part Clearinghouse name, i.e., a domain.  The value is an object of type {Lisp NSNAME}{index NSNAME} ({SectionRef Term NSNAME}), and is encoded as two items of type {lisp STRING}.}
}
}{end subsec Primitive Types}


{begin subsec Constructed Types}
{title Constructed Types}
{text

Constructed Types are composite objects made up of Primitive Types.  They are all expressed as a list whose {fn CAR} names the type and whose remaining elements give details.  The following are available:

{labeledlist

{name {lisp (ENUMERATION ({arg NAME VALUE}) ... ({arg NAME VALUE}))}}
{item Each {arg NAME} is an arbitrary litatom or string; the corresponding {arg VALUE} is its Courier encoding (a {lisp CARDINAL}).  Values of type {lisp ENUMERATION} are represented as a {arg NAME} from the list of choices.  For example, a value of type {lisp (ENUMERATION (UNKNOWN 0) (RED 1) (BLUE 2))} might be the litatom {lisp RED}.}

}
}{end subsec Constructed Types}

{lispcode
(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 {lisp (ARRAY 3 INTEGER)} are represented by lists of three integers, such as {lisp (10 1 59)}.

Objects of Courier type {lisp (SEQUENCE BOOLEAN)} are represented by arbitrary-length lists of {lisp T} and {lisp NIL}, such as {lisp (NIL T T NIL T)}.

Objects of Courier type
{lispcode 
(RECORD (NETWORK LONGCARDINAL) 
        (HOST (ARRAY 3 CARDINAL)) 
        (SOCKET CARDINAL))}

are represented by lists like {lisp ((NETWORK 174) (HOST (100 24 363)) (SOCKET 20))}.

Objects of Courier type
{lispcode 
(CHOICE (STATUS 0 (ENUMERATION (BUSY 0) (COMPLETE 1))) 
        (MESSAGE 1 STRING))}

are represented by lists like {lisp (STATUS COMPLETE)} or
{lisp (MESSAGE "Your request has completed.")}.

}{end subsec Courier Template Language}


{fndef {name COURIER.OPEN} {args HOSTNAME SERVERTYPE NOERRORFLG NAME}
{text
This function opens a Courier connection to the specified {arg HOST}
and returns an SPP stream.  If {arg HOST} is a {lisp LITATOM}, string, or list representation of a Clearinghouse name, {arg SERVERTYPE} should specify what type of server {arg HOST} is, so that the name may be looked up in the Clearinghouse database.  Currently, {arg SERVERTYPE} must be one of {lisp PRINTSERVER} or {lisp FILESERVER}.  Normally, this function will retry the connection {var \MAXETHERTRIES}{index \MAXETHERTRIES Var} times before generating an error.  If {arg NOERRORFLG} is specified, {lisp NIL} will be returned if the connection fails.  The Courier connection will be given {arg NAME}, if specified.
}}


{fndef {name COURIER.CALL}
{args STREAM PROGRAM PROCEDURE ARG{sub 1} {ellipsis} ARG{sub N} NOERRORFLG}
{type NOSPREAD}
{text
This function calls the remote procedure {arg PROCEDURE} of the Courier program {arg PROGRAM}.  {arg STREAM} is the SPP stream returned by {fn COURIER.OPEN}.  The arguments should  be Lisp values appropriate for the Courier types of the corresponding formal parameters of the procedure (defined under the {lisp ARGS} property for the procedure).  Returns results of the Courier types defined under the {lisp RESULTS} property.  If there is only a single result, it is returned, otherwise a list of results is returned.  The {arg NOERRORFLG} argument controls the treatment of remote errors.  If {arg NOERRORFLG} is {lisp NIL}, a Lisp error will be generated.  If {arg NOERRORFLG} is {lisp T}, {lisp NIL} will be returned as the result of the call. If {arg NOERRORFLG} is {lisp RETURNERRORS}, the result of the call will be a list consisting of the atom {lisp ERROR} followed by the Courier name of the error and any arguments.
}}

Examples:

{lispcode
(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 {lisp EXAMPLEPROGRAM} to be Courier program number 17, version number 1.  The example defines two types, {lisp PERSON.NAME} and {lisp BIRTHDAY}, and one procedure, {lisp GETBIRTHDAY}, whose procedure number is 3.  The following code could be used to call the remote {lisp GETBIRTHDAY} procedure on the host with address {lisp HOSTADDRESS}.

{lispcode
(SETQ STREAM (COURIER.OPEN HOSTADDRESS))
(COURIER.CALL STREAM 
              (QUOTE EXAMPLEPROGRAM)
              (QUOTE GETBIRTHDAY)
              (QUOTE ((FIRST.NAME "Eric")
                      (MIDDLE (INITIAL "C")) 
                      (LAST.NAME "Cooper"))))}

{fn COURIER.CALL} in this example will return a value such as

{lispcode
((YEAR 1959) (MONTH "January") (DAY 10))}



{begin subsec Manipulating Courier Representations}
{title Manipulating Courier Representations}
{text

Several Courier programs use values of type {lisp (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 {lisp UNSPECIFIED}s) and a Courier value.  The following function should be used for this purpose.

{fndef {name COURIER.READ.REP} {args LIST.OF.WORDS PROGRAM TYPE}
{text
This function returns the Lisp representation of the Courier object of type {arg TYPE} defined in the Courier program {arg PROGRAM} whose underlying Courier representation is {arg LIST.OF.WORDS}.
}}

}{end subsec Manipulating Courier Representations}

 
{begin subsec Using Bulk Data Transfer with Courier}
{title Using Bulk Data Transfer with Courier}
{text

Two Courier types are treated specially when they appear in the argument list of a procedure.  They are {lisp BULK.DATA.SINK} and {lisp BULK.DATA.SOURCE}.  A Courier procedure may have at most one such sink or source parameter.  The result of a {fn 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 {fn COPYBYTES}.  If the data is a stream of Courier objects, the following function should be used.

{fndef {name COURIER.READ.BULKDATA} {args STREAM PROGRAM TYPE}
{text
{arg STREAM} is the bulk data stream returned from {fn COURIER.CALL}. {arg TYPE} is the type of each Courier object in the stream. {arg PROGRAM} is the Courier program in which {arg TYPE} is defined. A list of objects of Courier type {arg 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 {lisp NIL}, the results, if any, will be ignored. Otherwise, the value is assumed to be a function
which to be applied to the results. 

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 {fn 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.

}{end subsec Using Bulk Data Transfer with Courier}


{Begin Note}
will not document this because of possible sensitivity:
{fndef {name COURIERTRACE} {args FLG REGION}
{text
This function controls the tracing of Courier remote procedure calls. It is similar to {fn PUPTRACE} and {fn XIPTRACE}, but operates at the call/return level rather than the packet level.
}} 
{End Note}

}{end subsec Courier Remote Procedure Call Protocol}


{Begin Note}
This section no longer needed.

{begin subsec NS Printing}
{title NS Printing}
{text
This section describes the facilities that are available for printing Interpress masters on NS printservers.

{vardef {name NS.DEFAULT.PRINTER}
{text
The value of this variable is used whenever no printserver is specified for the functions described below.
If its value is a {lisp LITATOM}, string, or Clearinghouse name, the Clearinghouse is queried to find the address of the printserver with that name. If its value is {lisp NIL}, it will be set automatically to some printserver in the local Clearinghouse domain.
In environments where there is no Clearinghouse, the value of
{var NS.DEFAULT.PRINTER} must be an appropriate {lisp NSADDRESS} record.
}}

{fndef {name OPEN.NS.PRINTING.STREAM}
{args
PRINTER DOCUMENT.NAME DOCUMENT.CREATION.DATE SENDER.NAME
RECIPIENT.NAME #COPIES MEDIUM PRIORITY STAPLE? TWO.SIDED? NOWATCHDOG?}
{text
This function returns a stream for printing an Interpress master
on {arg PRINTER} or on
{var NS.DEFAULT.PRINTER} as mentioned above.
The caller should write the Interpress data to the stream and then close it
using {fn CLOSEF}.
Printing begins after the stream is closed.

{arg DOCUMENT.NAME}
is the document name to appear on the header page (a string).

{arg 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.

{arg 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.

{arg 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.

{arg #COPIES}
is the number of copies to be printed.
The default value is 1.

{arg MEDIUM}
is the medium on which the master is to be printed.
This must be a Courier value of type {lisp MEDIUM},
which is a list of the form {lisp (PAPER (KNOWN.SIZE NAME))},
where {lisp NAME} is one of the LITATOMs {lisp US.LETTER}, {lisp US.LEGAL},
{lisp A0} through {lisp A10}, {lisp ISO.B0} through {lisp ISO.B10},
and {lisp JIS.B0} through {lisp JIS.B10}.
The default value is determined by the printer.

{arg PRIORITY}
is the priority of this print request
({lisp LOW}, {lisp NORMAL}, or {lisp HIGH}).
The default value is {lisp NORMAL}.

{arg STAPLE?}
is {lisp T} or {lisp NIL} depending on whether the document should be stapled.
The default value is {lisp NIL}.

{arg TWO.SIDED?}
is {lisp T} or {lisp NIL} depending on whether the document should be
printed on two sides.
The default value is {lisp NIL}.

{arg NOWATCHDOG?}
is non-{lisp NIL} if the client does not want a watchdog process to
monitor the status of the printing job.
}}

{fndef {name NSPRINT}
{args
PRINTER FILE.NAME DOCUMENT.NAME DOCUMENT.CREATION.DATE SENDER.NAME
RECIPIENT.NAME #COPIES MEDIUM PRIORITY STAPLE? TWO.SIDED?}
{text
This function prints an Interpress master on {arg PRINTER} or on
{var NS.DEFAULT.PRINTER} as mentioned above.
{arg FILE.NAME} should be the name of an Interpress file to be printed.
The remaining arguments are all optional, and are as described
for {fn OPEN.NS.PRINTING.STREAM} above.
{arg DOCUMENT.NAME}
defaults to the full name of the file, and
{arg DOCUMENT.CREATION.DATE}
defaults to the creation date of the file.
}}


{fndef {name NSPRINTER.STATUS}
{args PRINTER}
{text
This function returns the Courier value resulting from the
{lisp GET.PRINTER.STATUS} call.
}}


{fndef {name NSPRINTER.PROPERTIES}
{args PRINTER}
{text
This function returns the Courier value resulting from the
{lisp GET.PRINTER.PROPERTIES} call.
}}

}{end subsec NS Printing}
{End Note}


{begin subsec Clearinghouse}
{title Clearinghouse}
{text

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.

{fndef {name START.CLEARINGHOUSE} {args RESTARTFLG}
{text
This function enables Clearinghouse access.  It performs an expanding ring broadcast in order to find the first Clearinghouse server.  If {arg RESTARTFLG} is non-{lisp 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.
}}


{vardef {name CH.NET.HINT}
{text
Hint as to which network the local Clearinghouse server is on, for use by {fn START.CLEARINGHOUSE} above.
If {var 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 {var CH.NET.HINT} to the proper network number  in the local {lisp INIT} file will speed up {fn START.CLEARINGHOUSE} considerably.
}}

{fndef {name SHOW.CLEARINGHOUSE} {args}
{text
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 {lisp GRAPHER}".
}}

{fndef {name SHOW.ENTIRE.CLEARINGHOUSE} {args}
{text
This function attempts to cache information about all the Clearinghouse domains, so that the Clearinghouse structure window will show the entire database.
}}

{fndef {name CH.ORGANIZATIONS} {args ORGANIZATIONPATTERN}
{text
This function returns the list of organization names
in the Clearinghouse database matching {arg ORGANIZATIONPATTERN}.
The default pattern is {lisp "*"}, which matches anything.
}}

{fndef {name CH.DOMAINS} {args DOMAINPATTERN}
{text
This function returns the list of domain names
in the Clearinghouse database matching {arg DOMAINPATTERN}.
The default pattern is {lisp "*"}, which matches anything.
}}

{fndef {name CH.ENUMERATE} {args OBJECTPATTERN PROPERTY}
{text
This function returns the list of object names matching {arg OBJECTPATTERN}
and having the property {arg PROPERTY}.
Currently, {arg PROPERTY} must be one of
{lisp USER}, {lisp PRINTSERVER}, {lisp FILESERVER}, and {lisp ALL}.
For example,

{lisp (CH.ENUMERATE "*:PARC:Xerox" (QUOTE USER))}

will return a list of the names of users at Xerox PARC.
}}


{note: this currently returns users passwords. Will not document
{fndef {name CH.LOOKUP.USER} {args NAME}
{text
This function returns the user information for the first user whose
name matches {arg NAME}.
}}
}

{fndef {name LOOKUP.NS.SERVER} {args NAME TYPE}
{text
This function returns the {lisp NSADDRESS}
for the first server whose name matches {arg NAME}
and has the property {arg TYPE},
which must be {lisp PRINTSERVER} or {lisp FILESERVER}.
}}

}{end subsec Clearinghouse}

{begin subsec NS Filing}
{title NS Filing}
{text

This section describes functions that may be used
to access Xerox NS fileservers.

{fndef {name NSCREATEDIRECTORY} {args HOST/DIR}
{text
This function creates a new directory with pathname {arg HOST/DIR}. Top level directories ("file drawers") cannot be created in this way.
}}

{fndef {name CLOSE.NSFILING.CONNECTIONS}
{text
This function closes any open connections to NS fileservers.
}}

}{end subsec NS Filing}

}{End SubSec Higher-level NS Protocol Functions}