'\"!  pic | mmdoc
.if n .pH port.xport @(#)xport	40.4
.\" Copyright 1989 AT&T
.ds xW X\s-2WIN\s+2
.ig
.S 11 13
.nr N 4
.ds HF 3 3 3 3 2 2 2
.ds HP 12 12 11 11 11 11
.ce 3
.ps 14
.vs 16
.ft B
..
.BK "Porting the XWIN Server" "X\s-2WIN\s+2 Release 3.0"
.CH "An Overview of the \*(xW\(tm 3.0 Server Port and Network Interface" 1
.H 1 "Introduction"
The \*(xW\(tm 3.0 server is based on the X Window System
Version 11 Release 3 Sample
Server as distributed by MIT.  Although the server maintains much of
the original source, it has been extensively modified to work in
the UNIX\v'-.5v'\s-4\(rg\s+4\v'.5v'
System V/386 Release 3.2.x and Release 4.0 environments with the display
controllers supported on the 6386 WGS family of computers.  The allowed
display controllers are the VDC-750 (extended EGA card), VDC-600
(extended VGA card) and generic EGA and VGA class display controllers.
.P
This guide provides an overview of the modifications made to
the MIT sample server to implement the \*(xW server.  The guide
does not cover every change made to the server, but it does address
all of the major changes.  As the guide is only an overview of the
port, details of the modifications are omitted in favor of references
to the source code where the changes were made.  Readers are expected
to be familiar with the MIT sample server, UNIX System V, and both EGA
and VGA architectures.
.P
Generally speaking, the \f4server/dix\f1 (i.e., device independent)
portion of the server was not extensively changed.  However, the
\f4server/ddx\f1 (device dependent) and \f(CWserver/os\fP (operating
system specific) portions of the server contain sizable modifications.
These modifications pertain to device initialization and handling,
graphics drawing, and operating system dependencies.  The following
sections provide an overview of the relevant changes.
.AB N
Please see these documents for more information on graphics
adapters:
.sp 0.25
Angebranndt, \fIet al\f1.,
\fIDefinition of the Porting Layer for the X v11 Sample Server\f1.
.sp 0.25
Angebranndt, \fIet al\f1.,
\fIStrategies for Porting the X v11 Sample Server\f1, March 1, 1988.
.sp 0.25
\fIIBM Enhanced Graphics Adapter,\f1 IBM, Aug. 2, 1984.
.sp 0.25
\fIIBM Personal System/2 Displays and Adapters,\f1 IBM,.
.AC
.H 1 "Keyboard/Mouse I/O"
To avoid the overhead of numerous system calls, keyboard and mouse
I/O uses a shared queue to record events.  The queue is initialized
by an \fIioctl()\f1 to the
KD (Keyboard/Display) driver.  Once the shared queue mode is set up,
both the KD driver and the mouse driver will write events in the shared
queue.  The server process has a pointer to this queue, so instead
of getting events via the normal \fIread()\f1 mechanism, the server
simply removes the event from the queue.  When the event queue is
empty and a driver adds a new event to the queue, the driver can
optionally send a signal to the server process.  Whether this signal
is generated by the driver is controlled by a flag in the queue structure.
The server sets this flag whenever it has processed all events/requests
requests and is about to block waiting for something to do.
When the server receives the signal from the driver, it does a
\fIlongjmp(3)\f1 to the top of the dispatch loop, where the event is
processed normally.  Look in \f4server/ddx/i386/i386_io.c\f1 for code that
manipulates the shared keyboard/mouse queue.
.H 1 "Virtual Terminal Support"
The KD driver supports multiple virtual terminals (VTs) running
simultaneously on the console.  The physical display and keyboard
are connected to only one virtual terminal at a time, but users may
switch between VTs by typing a key sequence on the keyboard.  Character
applications are completely unaware of this switching; they continue
to run normally, and the KD driver will keep track of the data displayed
on their virtual screen.  When the user switches back to an application,
the KD driver will automatically update the screen to reflect the contents
of the virtual screen.
.P
Graphics applications such as the \*(xW server, however, must cooperate
with the KD driver to work in the virtual terminal environment.  Unlike
character applications, the KD driver does not retain the data from
a graphics application; the application is responsible for saving itself.
When the user enters the sequence to change the virtual terminal, the KD
driver sends a signal to the \*(xW server.  The server catches the signal
and simply sets a flag.  Before actually switching VTs, the server waits
until any protocol request which is being serviced has been completed.  The
server then saves the current contents of the screen and releases the screen.
It pauses until the user enters the key sequence to switch
the active virtual terminal back
to the server, at which time the KD driver will send another signal.  The
server catches this signal, reclaims the screen, and restores it to its
original contents.  It then continues to process protocol requests normally.
.P
The procedure \fIopenvt()\f1 in \f4server/ddx/i386/i386_io.c\fP
opens an unused
virtual terminal for use by the server and sets up the signals used to
relinquish and reclaim the screen.  The signal handlers are in
\f4server/ddx/i386/display.c\f1, and the code to save and restore the screen
is in \f4server/ddx/vga/vgadisplay.c\f1 for VGA type devices, and
\f4server/ddx/ega/egadisplay.c\f1 for EGA type display devices.  The file
\f4dix/dispatch.c\f1 has been modified to look for the flag set when the
user initiates a VT switch.
.H 1 "Display Initialization"
The display is initialized according to the type of display controller and
the command line options.  The server determines the type of controller as 
well as (the UNIX kernel's best guess of) the monitor type via an ioctl().
Once the display controller type has been determined, the
server will enter the best graphics mode available on that card unless
the user has included command line options to modify the mode.  The
server then maps the frame buffer into the addressing space of the server
process and allocates memory for saving the frame buffer during virtual
terminal switches.  Display initialization completes by loading the
screen structure with the appropriate values based on the display type.
.P
The visuals available to clients also depends on the display controller
and monitor installed.  If a color monitor is used, then for EGA cards,
the server provides a StaticColor visual by default and a PsuedoColor
visual if the monitor is capable of 64 colors.
For VGA cards, the server also provides a StaticColor visual by default
as well as a PseudoColor visual.  If a monochrome monitor is used, then
for both EGA or VGA cards, the server provides a StaticGray visual by
default and a PseudoGray visual if available.
.P
Look in \f4server/ddx/6386/6386_io.c\f1 for the code that parses
additional command line arguments and \f4server/ddx/i386/display.c\f1
for the code that determines the display type.  This code is executed via 
calls from \fIInitOutput()\f1 located in \f4server/ddx/i386/init.c\fP.
Initialization of display devices continues in the function
\fIi386ScreenInit()\f1 which is found in \f4server/ddx/i386/i386_io.c\fP.
This function is responsible for dispatching the appropriate device-specific
initialization functions.
For both the VDC-750 and EGA specific controllers, the device-specific
functions are located in \f4server/ddx/ega/egadisplay.c\f1 and
\f4server/ddx/ega/egascrinit.c\f1.  For both the VDC-600 and VGA
controllers, the device specific functions are located in
\f4server/ddx/vga/vgadisplay.c\f1 and \f(CWserver/ddx/vga/vgascrinit.c\fP.
.H 1 "Graphics Functions"
The graphics functions comprise the majority of code in the directory
\f4server/ddx\f1.
Routines in the directories \f4server/ddx/mi\f1 and \f(CWserver/ddx/att\fP
implement the (high-level) graphics functions documented in the
\fI``Definition of the Porting Layer for the X v11 Sample Server.''\f1
Included are procedures to draw wide lines, arcs, polygons, and text.
These directories also include the span routines, image manipulation, pixmap
and window manipulation, area copying and filling routines.
.P
It is important to note that the code in both the \f4mi\fR and \f4att\fR
sub-directories are not device specific; they simply performs the high-level
operations and dispatch device-specific graphics primitives to actually
do the drawing.
The device-specific routines for both the EGA and VGA class display
controllers can be found under \f4server/ddx/ega\f1.
These low-level graphics primitives are dispatched indirectly through
function tables that are initialized in \f4server/ddx/ega/egascrinit.c\fR
for EGA class devices and \f4server/ddx/vga/vgascrinit.c\fR for VGA
class devices.
.P
The principle graphics primitive is \fIrasterop()\f1.  This function
combines two drawables according to one of the 16 boolean functions,
optionally through a mask bitmap.  This function is the only device
dependent routine required to implement an X server, though other
device specific functions are also used to optimize performance sensitive
areas of the server.  In addition to implementing protocol
requests such as \fIXCopyArea()\f1, \fIrasterop()\fP is also used
when another function optimized for the specific hardware is not available.
\fIrasterop\f1 works by dynamically generating appropriate machine code
for the required case on the stack and then calling that code as a function.
The file \f4server/ddx/ega/egarasterop.c\f1 contains the implementation.
.P
Several functions have been optimized to take advantage of hardware on
EGA/VGA class cards or to remove unnecessary software overhead.  These
functions include solid text drawing (see \f(CWegaglyphblt.c\fP in
\f4server/ddx/ega\f1); narrow line drawing (see \f(CWegaline.c\fP in
\f4server/ddx/ega\f1); solid area filling (see \f(CWegafilla.c\fP in
\f4server/ddx/ega\f1); poly point drawing (see \f(CWegapolypnt.c\fP
in \f4server/ddx/ega\f1); and cursor drawing (see \f4egacursor.c\f1
in \f4server/ddx/ega\f1).
Note that cursors are drawn by first converting the cursor bitmaps to
glyphs and then using the glyph code to actually display them.
.P
For EGA and VGA type display controllers, the server uses additional
optimizations.  First, the server will use EGA/VGA hardware to speed tiling
when the tile is a multiple of 8 bits (see \f4server/ddx/ega/egatilea.c\f1).
Secondly, the server will use the EGA/VGA controller to speed stippling
if the stipple is a multiple of, or an even divisible of, 8 bits
(see \f4server/ddx/ega/egastippa.c\f1).
Finally, the server will store the bits covered by the cursor on the
EGA/VGA card if possible (see \f4server/ddx/ega/egacursor.c\f1).
.P
Both the MIT sample server and the \*(xW 3.0 server provide two (related)
features, namely backing-store and save-unders, to help mimimize the
number of expose events sent to client applications.
With the backing-store facility, graphics operations that are directed
at selected windows will be mirrored in (backing) pixmaps.  When the
obstructed portions of these windows become exposed, the server will
use the contents of the backing pixmaps to restore the screen.
With save-unders, the server will save/restore the contents of
the screen that are obscured by selected (save-under) windows.
Note that the word "selected" is used because both features 
are accessible via per-window attributes that are not set by default. 
Though the sample server uses the backing-store facility to
implement save-unders, the \*(xW 3.0 server provides its own
save-under implementation.  For implementation details see
\f(CWattsave.c\fP and \f(CWattsave.h\fP in \f4server/ddx/att\f1. 
.H 1 "Colors"
Unlike in the sample server from MIT, the \*(xW server does not use the
\fIdbm\f1 tool (a tool that is unique to the BSD UNIX environment) to manage
the color database.  Instead, it uses a simple binary search algorithm to scan
the database for the red, green, and blue intensities that correspond to a
particular color name.  The database file is opened in
\f4server/os/sysV/osinit.c\f1 and scanned in \f(CWserver/os/sysV/oscolor.c\fP.
.P
For EGA or VGA devices, once the server has the intensities of a color, it
converts them to the closest 2-bit value supported by the current visual for
each primary.  These 2-bit values are loaded into the color lookup registers
on the display controller.  The color conversions and register manipulating
code is located in \f4server/ddx/ega/egacmap.c\f1 for EGA type devices,
and \f4server/ddx/vga/vgacmap.c\f1 for VGA type devices.
.P
Note that the "screen-saver" is implemented by simply setting all the color
registers on the device to black.  When an event awakens the server, the
screen is ``redrawn'' by reloading the proper color values into the hardware
registers from the current colormap.
.H 1 "BSD Functions"
The MIT sample server was written for systems using the BSD UNIX operating
system; as such, it calls several functions that are not a part of UNIX
System V.  Rather than changing all occurrences of these functions to
System V versions, BSD compatibility functions are included in the Xlib
shared library.  Only those BSD functions that are required for the
\*(xW product have been written, and these functions do not provide
complete compatibility with their BSD versions.  The BSD compatibility
functions include \fIselect()\f1 (written in terms of \fIpoll()\fP),
\fIreadv()\fR, \fIwritev()\f1, \fIffs()\fP, \fIbzero()\fP, \fIbcopy()\fP,
as well as additional functions located in \f4BSD/lib\f1.
The corresponding header files are located in \f4BSD/include\f1.
Note that in an SVR 4.0 environment, the X\s-2WIN\s+2 versions of
\fIreadv()\fR and \fIwritev()\fR are prefixed with an underscore
(e.g.,\fI_readv()\fR), so as not to "hide" the definitions of these
functions located in \f4/usr/lib/libc.so\fR.
.H 1 "Client/Server Communication"
.H 2 "Overview"
.P
To enable the server and clients to communicate with one another, the network
interface must provide the following capabilities:
.P
.AL
.LI
The server should be able to open at least one well known channel for 
listening and accepting new client connections.
.LI
The server should be able to block listening for events on all connections 
including the listening channels.
.LI
The client should be able to open a private connection to the server via one
of the well known channels set up by the server for transmitting data back and 
forth.
.LE
.H 3 "Sockets"
.P
The X Window System was initially developed at MIT for BSD UNIX\u\s-3\(rg\s+3\d
Systems.
The network interface was implemented by using the socket facility provided by
BSD machines.  In the MIT implementation, the server uses the system calls
\f4socket()\f1, and \f(CWbind()\fP to open the "well known channel" to a
given network.
It also uses the system calls \f4listen()\f1 and \f(CWaccept()\fP to accept
new connections to a network.  The client, on the other hand, calls
\f4socket(), bind()\f1 and \f(CWconnect()\fP to connect to the server.
Once the connection is established, the server calls \f4select()\f1 to block,
waiting for events on any of the channels.  Note that the same interface is
used for both local and remote clients.
.H 3 "Transport Layer Interface (TLI)"
.P
UNIX System V provides a Network Interface similar to the BSD socket interface.
The Transport Layer Interface package (TLI) is based on the STREAMS
subsystem provided by SVR3.0+.  TLI offers similar functionality as the
BSD socket facility, independent of the Transport Provider.  Because TLI
is implemented as a user library, applications that use TLI do not run without
the Transport Provider Driver installed.
.H 2 "The Local Client/Server Connection"
.P
Clients can be connected to the server in one of two ways: locally via
"streams pipes" (which are pseudo-tty's with no line discipline processing
modules) or remotely, using TLI.  The procedure for local clients
is as follows.  At initialization, the server opens the streams
pipe clone device \f4/dev/ptmx\f1.  The clone device returns a pseudo tty
master, \f4ptm\f1\&\fIxxx\fP, which has associated with it a corresponding
slave, \f4pts\f1\&\fIxxx\fP.  After determining the corresponding
slave name, it links the slave pts device to \f4/dev/X/server.0\f1, which
is the ``well-known address'' used by local clients.  A client will
open this file to initially connect to the server.  It will also open
the clone device to obtain a second master/slave pair.  After obtaining
the slave name of the new psuedo tty and sending it to the server, the client
then closes the initial connection to the
server.  The server reads the client's slave name and opens that device;
this action gives the client a private connection to the server that
is used for all further communication.
.P
.H 2 "The Remote Client/Server Connection in a UNIX SVR 3.2.x Environment" 
.H 3 "The xdaemon and the Nameservers"
.R
\f4xdaemon\fR is a program that starts at boot time and runs indefinitely.
It accepts name/address messages (in a pre-defined format) from both client
applications and the server, and forks an executable known as the "nameserver".
The \fInameserver\fR takes information passed to it via the \fIxdaemon\fR,
performs the specified network address translation, and sends back the result.
Note that one \fInameserver\fR must exist for each network that
is supported by the X\s-2WIN\s+2.  All nameserver executables are located
under \f4/usr/X/lib/net/\fIxnet\f1/nameserver\fR, where \fIxnet\fR maps to
the name of the network device found under \f4/dev\fR.  For example,
the nameserver for the AT&T WIN/386 TCP/IP package is located in
\f4/usr/X/lib/net/tcp/nameserver\fR.  The device associated the WIN/386
network is \f4/dev/tcp\fR.
Appendix B of this document contains the design requirements common to
all \fInameservers\fR.
.P
In order for a remote client application to establish a connection with a
local server, both the client and the server machine must have
an \fIxdaemon\fR installed and running.  In addition to \fIxdaemon\fR,
both the client and server machine must have a copy of the \fInameserver\fR
for the appropriate network.
In essence, the \fIxdaemon\fR serves as an "intermediary" between the
client/server and the \fInameserver\fR.  With the implementation of a
\fInameserver\fR, all network-specific address translations can be isolated
from both the client and server.  As a result, support for new networks that
support a TLI interface, can be added to X\s-2WIN\s+2 without the need for
modifications to the client/server software.
Figure 1 of Appendix A illustrates the details supplied in this section.
It shows the interrelationship amount the various components used 
to establish a remote client/server connection in an SVR 3.2.x environment.
.P
.H 3 "Establishing the Connection: The Server Side"
.P
As stated in the previous section, network-specific names/address formats
are not hard-coded in the client or server.  For each entry in the directory
\f4/usr/X/lib/net\f1 (i.e., for each network supported by X\s-2WIN\s+2),
the server will open a private connection to \fIxdaemon\fR, and send
a message requesting the X address of the local machine in the appropriate
network format.  \f4xdaemon\fR will then fork the \fInameserver\fR for
the corresponding network to obtain the TLI structure, \f4t_bind\f1\*F.
.AB N
For more information about TLI calls and the data structures associated with
these calls refer to AT&T UNIX System V Network Programmer's Guide.
.AC
This structure, which is sent back to the server, contains a "well known
address" for the server to bind itself to.
Assuming that there exists a matching entry under \f4/dev\f1, the X server
will try to open a listener for the network associated with the entry.
As a result, the server will have connected to a well known channel
for each of the supported networks, patiently waiting for clients to
establish a connection. 
.H 3 "Establishing the Connection: The Client Side"
.P
When an X client wishes to connect to a remote server, it first looks in
in \f4/usr/X/lib/Xconnections\fR for the name of the remote machine
and the type of network associated with the "display name".
The "display name" is the name used by the user, either through a command line
option to the client application or through the environment variable DISPLAY,
to specify which server (either remote or local) that the client should be
run on.
Secondly, the client then opens the device for the specified network
(e.g., /dev/mynet).
Finally, the client establishes a private connection to \f4xdaemon\fR,
requesting the "well known address" for the X server on the remote machine
in the appropriate network format.
The daemon extracts the name of the required network type from the request
message, and forks the \fInameserver\fR for the network associated with the
specified network type.
The nameserver will then send back a \f4t_call\fR structure that can
be used by the client to connect to the remote server using the TLI call
\f4t_connect()\fR.  All of these operations are incorporated into \fIXlib\fR
and will be executed when the client calls \f4XOpenDisplay()\f1.
Appendix C contains a description of the protocol used for communicating
between the client (server) and a \fInameserver\fR via \fIxdaemon\fR.
.P
.H 3 "Opening a Private Connection"
.P
Previously, when describing the server side of a remote connection, this
document stated that a "well-known address" is established for each
supported network.  Since more than one remote client can communicate with a
given server, each client must establish a private network connection to the
server.  To elaborate, the server opens the network clone device (for example
\f4/dev/mynet\f1) and binds to the address \fInodename\fP\f(CW.0\fP,
where \fInodename\f1 is the name of the local machine.  This becomes
the "well-known address" for remote connections.
The client then opens the appropriate network device and connects to the
server's well-known address.  The server, which is listening on this address,
will open the network device again to obtain a new (private) connection.
The client and the server now have a private connection to use
for \fIall\fR further communication.
The code implementing these connection mechanisms is located in Xlib.
For further details, look in the file \f4lib/X/Xstreams.c\f1.
.H 3 "Host Access Checking"
.P
When the X\s-2WIN\s+2 server detects the new call through the system call
\f4poll()\f1, it will retrieve information pertaining to the call through
\f4t_listen()\f1.  If the host access checking is disabled, the server
will simply accept the call.  If host access checking is not disabled, the
server will send a message (containing the TLI structure received from
\f4t_listen()\f1), to the nameserver via the \fIxdaemon\fR.  The message
will request the name of the machine from which the call had originated.
If the name of the machine passed back from the \fInameserver\fR
is not in the current server host list, the server will reject the call.
.H 3 "Creating a New Nameserver."
.R
Two essential routines are needed to build a nameserver for a particular
network type.  The first routine takes a name for a host on that network
and returns its corresponding address. The second routine does the inverse.
It takes an address in the particular network format and returns the name
of the host on that network associated with address.
.P
For example, one of the nameservers that is bundled with the X\s-2WIN\s+2 3.0 
package handles address translations for the Wollongong-based TCP/IP Ethernet
package.  This nameserver handles address translation by calling the routines
\f4gethostbyname()\f1 and \f(CWgethostbyaddress()\fP, found in the
library "libnet.a" included with the Wollongong package. To port this program
to a different Ethernet environment, the Wollongong header files must be
replaced with the appropriate header files included with the new package.
In addition, the functions described above must be replaced with their
equivalents in the new package.
.sp
.H 2 "The Remote Client/Server Connection in a UNIX SVR 4.0 Environment" 
.H 3 "A Dynamic Shared Version of Xlib - libnsl.so"
.P
In an SVR 4.0 environment, the dynamic shared library \f4libnsl.so\f1
subsumes the functionality provided by the executable \fIxdaemon\fR
described previously.
It accepts name/address translation requests, via the functions
\f4netdir_getbyaddr()\fR and \f(CWnetdir_getbyname()\fR, from both the
client and server, and calls the appropriate "nameserver" functions. 
These "nameserver" functions are not part of \f4libnsl.so\fR,
but included in separate dynamic shared libraries corresponding to the
various supported networks.  The reader should understand that the same
"network independent" network interface is achieved without the need 
for a daemon process, nor the overhead of forking/execing \fInameservers\fR.
With dynamic shared libraries, new "nameserver" libraries can be written, and
updates to \f4libnsl.so\fR can be made, without forcing a recompilation
of the client software.
The UNIX SVR 4.0 package includes the "nameserver" shared libraries
for both the \s-1STARLAN\s+1 and \s-1TCP/IP\s+1 networks, namely
\f4straddr.so\fR and \f(CWtcpip.so\fR respectively.
.P
It is important to note that the basic structure for establishing a connection
between the client and server is the same as that described in the SVR 3.2.x
section of this document.  In a 4.0 environment the \f4libnsl.so\fR dynamic
shared library acts as the "intermediary" rather than \fIxdaemon\fR.
.P
As a final comment, rather than establishing connections for each of the
entries found in \f4/usr/X/lib/net\fR, the code in \f(CWlibnsl.so\fR
will establish a network connection for each of the supported networks listed
in \f4/etc/netconfig\fR.  As an alternative, the user can specify a 
subset of the supported networks by setting the UNIX environment variable
\s-1NETPATH\s+1. 
.P
Figure 2 of Appendix A illustrates how a connection is established between
a client on an SVR 3.2.x machine and a remote server on an SVR 4.0 machine.
Figure 3 of Appendix A illustrates how a connection is established between
a 4.0-based client on an SVR 4.0 machine and a remote server on an
SVR 4.0 machine.
.H 3 "Backwards Compatibility for 3.2.x-Based Clients"
.H 4 "A Revised Static Shared Version of Xlib - libX11_s"
.P
The reader may wonder how clients built in an SVR 3.2.x environment, and
run on an SVR 4.0 machine, can take advantage of the dynamic shared library
networking scheme.
Fortunately, since Xlib is built as a static shared library in an SVR 3.2
environment (\f4libX11_s\fR), updates can be made without forcing a
recompilation of the 3.2.x-based clients.
However, before proceeding, the reader should understand that while static
shared libraries are recognized by UNIX SVR 4.0, they can not be generated
on an SVR 4.0 machine.
A static shared version of Xlib must first be built in an SVR 3.2.x environment
and then shipped to the appropriate 4.0 machine.
.P
In X\s-2WIN\s+2 3.0, the static shared version of Xlib has been modified
to first identify which UNIX system environment the client is running in,
and then execute the appropriate code with respect to that environment.
If the client is running on an SVR 3.2.x machine, the server will send
name/address translation requests to \fIxdaemon\fR.  If the (3.2.2-based)
client is running on an SVR 4.0 machine, the server will connect to a
the 4.0-based daemon, \fIxntad\fR, described below. 
.H 4 "The SVR 4.0 Network Daemon - xntad"
.P
One limitation of static shared libraries is that external symbol references
can not be made from them.  In the case of Xlib, the code in \f4libX11_s\fR
cannot access the appropriate name/address translations functions in the
dynamic shared library \f4libnsl.so\fR.  For this reason,
3.2.x-based clients are forced to rely on a daemon process (similar to
\fIxdaemon\fR) to handle requests for name/address translations.
Rather than forking/execing a nameserver, the 4.0 network daemon,
\fIxntad\fR (X Name To Address Daemon), will simply reference the
appropriate functions in the dynamic shared library \f4libnsl.so\fR.
The functions in \f4libnsl.so\fR will, in turn, make calls to the
appropriate dynamic shared library to handle network-specific translations.
Figure 4 of Appendix A illustrates how a connection is established between
a 3.2.x-based client on an SVR 4.0 machine and a remote server on an
SVR 4.0 machine.
.H 2 "Remote Client/Server Communication"
.P
After a connection has been established, both the clients and the server
use the lowest level routines to read and write over their connection.
Writes are straightforward; the system call \fIwrite()\f1 is used for both
local and remote (TLI) connections\*F.
.AB N
The server is able to use \fIread()\fR and \fIwrite()\fR for remote
connections by pushing the TLI streams module "tirdwr".
.AC
Reads, however, are buffered to avoid the system call overhead with many
reads of small buffers.  For small reads, the code first tries to satisfy
the request out of the buffer.  If the read fails, the buffer is filled
using \fIread()\f1 for both local and remote (TLI) connections.
.P
The server will also potentially buffer writes.  When the server writes
to a client, it first uses the low level routine described above.  If
no streams buffers are available, or a client has not read data
written previously by the server, the write may fail.  In this case, the
server buffers the data to be written and temporarily suspends processing
of input events.\*F
.AB N
Input events often cause many writes which are destined to fail.  As a
result, it is better to let them be buffered automatically in the
mouse/keyboard queue and process them later.
.AC
In the meantime, the server also allows other processes to run.  Hopefully,
these processes will read data or otherwise free resources that caused the
write to fail.  When the server resumes, it periodically tries to write the
data to the client.  If the write is successful, then the server will resume
input event processing.  Otherwise, it will continue to buffer output to the
failed client until writes succeed, or until the buffer fills.  At this time,
the server closes the client connection.
.P
The file \f4server/os/sysV/io.c\f1 includes the code to buffer failed writes.
The file \f4server/os/sysV/WaitFor.c\f1 contains modifications
to attempt to write data that was buffered due to a previous write failure.
The processing of input events is disabled in \fIProcessInputEvents()\f1 in
the file \f4server/ddx/i386/i386_io.c\f1.
.H 1 "Appendix A: Client/Server Relationships Under UNIX"
.FG "Client and Server Machines Both Running SVR 3.2x"
.PS
scale=150
define t109 |
[ box invis ht 32 wid 94 with .sw at 0,0
"\fR\s8\&Nameserver\f1\s0" at 47,24
"\fR\s8\&for Network 2\f1\s0" at 47,8
] |

define t128 |
[ box invis ht 32 wid 98 with .sw at 0,0
"\fR\s8\&Nameserver\f1\s0" at 49,24
"\fR\s8\&for Network N\f1\s0" at 49,8
] |

define t125 |
[ box invis ht 32 wid 94 with .sw at 0,0
"\fR\s8\&Nameserver\f1\s0" at 47,24
"\fR\s8\&for Network 2\f1\s0" at 47,8
] |

define t122 |
[ box invis ht 32 wid 94 with .sw at 0,0
"\fR\s8\&Nameserver\f1\s0" at 47,24
"\fR\s8\&for Network 1\f1\s0" at 47,8
] |

define m0 |
[ box invis ht 40 wid 84 with .sw at 0,0
ellipse ht 40 wid 84 at 42,20
] |

define m1 |
[ box invis ht 128 wid 128 with .sw at 0,0
"\fR\s10\&libX11_s\f1\s0" at 66,22
m0 with .nw at 22,46
circle rad 64 at 64,64
"\fR\s10\&SERVER\f1\s0" at 66,88
] |

define m2 |
[ box invis ht 56 wid 128 with .sw at 0,0
"\fR\s12\&xdaemon\f1\s0" at 64,24
box ht 56 wid 128 with .nw at 0,56 
] |

define m3 |
[ box invis ht 192 wid 160 with .sw at 0,0
m2 with .nw at 32,192
box ht 40 wid 120 with .nw at 0,40 
t109 with .nw at 17,34
line <-> from 104,136 to 104,40 
] |

define m4 |
[ box invis ht 40 wid 104 with .sw at 0,0
"\fR\s10\&Network 2\f1\s0" at 52,18
box ht 40 wid 104 with .nw at 0,40 
] |

box invis ht 720 wid 602 with .sw at 0,0
"\fR\s10\&Network 1\f1\s0" at 234,578
box ht 40 wid 104 with .nw at 182,600 
m4 with .nw at 158,648
m3 with .nw at 442,360
line <-> from 536,398 to 536,360 
"\fR\s10\&TLI Interface\f1\s0" at 78,600
"\fR\s10\&TLI Interface\f1\s0" at 528,582
box ht 56 wid 128 with .nw at 56,368 
"\fR\s12\&Machine A (SVR 3.2.x)\f1\s0" at 122,60
m1 with .nw at 56,538
circle rad 64 at 534,464
m0 with .nw at 492,446
"\fR\s10\&libX11_s\f1\s0" at 536,422
"\fR\s10\&CLIENT\f1\s0" at 536,488
line <-> from 168,312 to 168,136 
line <-> from 128,312 to 128,216 
line <-> from 96,312 to 96,264 
t128 with .nw at 79,130
box ht 40 wid 112 with .nw at 72,136 
t125 with .nw at 41,210
box ht 40 wid 120 with .nw at 24,216 
box ht 40 wid 112 with .nw at 0,264 
t122 with .nw at 9,258
"\fR\s18\&...\f1\s0" at 120,161
"\fR\s12\&xdaemon\f1\s0" at 120,336
line <-> from 118,410 to 118,368 
"\fR\s12\&Machine B (SVR 3.2.x)\f1\s0" at 546,64
"\fR\s10\&Network 2\f1\s0" at 450,626
box ht 40 wid 104 with .nw at 398,648 
line  from 332,716 to 332,48 dashed
line <-> from 454,608 to 534,528 
line <-> from 182,570 to 152,532 
line <-> from 166,608 to 134,536 
line <-> from 150,680 to 118,536 
"\fR\s18\&...\f1\s0" at 174,667
line <-> from 262,624 to 398,624 dotted
"\fR\s10\&Network N\f1\s0" at 170,698
box ht 40 wid 104 with .nw at 118,720 
.PE
.SK
.FG "Server Machine Running SVR4.0; Client Machine Running SVR3.2.x"
.PS
scale=150
define t133 |
[ box invis ht 32 wid 94 with .sw at 0,0
"\fR\s8\&Nameserver\f1\s0" at 47,24
"\fR\s8\&for Network 2\f1\s0" at 47,8
] |

define m0 |
[ box invis ht 56 wid 128 with .sw at 0,0
"\fR\s12\&xdaemon\f1\s0" at 64,26
box ht 56 wid 128 with .nw at 0,56 
] |

define m1 |
[ box invis ht 250 wid 160 with .sw at 0,0
m0 with .nw at 32,194
box ht 40 wid 120 with .nw at 0,42 
t133 with .nw at 17,36
line <-> from 104,138 to 104,42 
line <-> from 96,250 to 96,194 
] |

define m2 |
[ box invis ht 64 wid 128 with .sw at 0,0
ellipse ht 64 wid 128 at 64,32
] |

define m3 |
[ box invis ht 36 wid 68 with .sw at 0,0
ellipse ht 36 wid 68 at 34,18
] |

define m4 |
[ box invis ht 40 wid 104 with .sw at 0,0
"\fR\s10\&Network 2\f1\s0" at 52,18
box ht 40 wid 104 with .nw at 0,40 
] |

box invis ht 716 wid 638 with .sw at 0,0
"\fR\s10\&Network 1\f1\s0" at 248,574
box ht 40 wid 104 with .nw at 196,596 
m4 with .nw at 172,644
"\fR\s10\&libX11.so\f1\s0" at 138,456
circle rad 138 at 138,394
"\fR\s8\&libnsl.so\f1\s0" at 142,376
line  from 164,360 to 180,348 
"\fR\s10\&netN.so\f1\s0" at 200,332
"\fR\s10\&net1.so\f1\s0" at 72,336
"\fR\s10\&net2.so\f1\s0" at 136,296
line  from 138,350 to 138,318 
line  from 136,426 to 136,406 
line  from 100,350 to 118,362 
circle rad 28 at 140,378
m3 with .nw at 166,352
m3 with .nw at 102,318
m3 with .nw at 38,358
m2 with .nw at 68,490
"\fR\s10\&SERVER\f1\s0" at 136,506
"\fR\s10\&CLIENT\f1\s0" at 572,498
circle rad 60 at 572,468
ellipse ht 40 wid 84 at 572,436
"\fR\s10\&libX11_s\f1\s0" at 576,436
"\fR\s10\&TLI Interface\f1\s0" at 92,596
"\fR\s10\&TLI Interface\f1\s0" at 542,578
"\fR\s12\&Machine B (SVR 3.2.x)\f1\s0" at 550,84
"\fR\s12\&Machine A (SVR 4.0)\f1\s0" at 136,84
"\fR\s10\&Network 2\f1\s0" at 464,622
box ht 40 wid 104 with .nw at 412,644 
line  from 346,712 to 346,44 dashed
line <-> from 468,604 to 548,524 
line <-> from 196,566 to 166,528 
line <-> from 180,604 to 148,532 
line <-> from 164,676 to 132,532 
"\fR\s18\&...\f1\s0" at 188,663
line <-> from 276,620 to 412,620 dotted
"\fR\s10\&Network N\f1\s0" at 184,694
box ht 40 wid 104 with .nw at 132,716 
m1 with .nw at 478,406
.PE
.SK
.FG "Both Client and Server Machine Running SVR 4.0 (Client Built in 4.0 Environment)"
.PS
scale=150
define m0 |
[ box invis ht 36 wid 68 with .sw at 0,0
ellipse ht 36 wid 68 at 34,18
] |

define m1 |
[ box invis ht 64 wid 128 with .sw at 0,0
ellipse ht 64 wid 128 at 64,32
] |

define m2 |
[ box invis ht 40 wid 104 with .sw at 0,0
box ht 40 wid 104 with .nw at 0,40 
"\fR\s10\&Network 2\f1\s0" at 52,18
] |

box invis ht 718 wid 690 with .sw at 0,0
"\fR\s10\&libX11.so\f1\s0" at 138,458
"\fR\s10\&SERVER\f1\s0" at 136,508
m1 with .nw at 68,492
m0 with .nw at 38,360
m0 with .nw at 102,320
m0 with .nw at 166,354
circle rad 28 at 138,382
line  from 100,352 to 118,364 
line  from 136,428 to 136,408 
line  from 138,352 to 138,320 
"\fR\s10\&net2.so\f1\s0" at 136,298
"\fR\s10\&net1.so\f1\s0" at 72,338
"\fR\s10\&netN.so\f1\s0" at 200,334
line  from 160,364 to 180,350 
"\fR\s8\&libnsl.so\f1\s0" at 140,382
circle rad 138 at 138,396
m1 with .nw at 482,484
m0 with .nw at 516,312
line  from 550,420 to 550,400 
line  from 552,344 to 552,312 
"\fR\s10\&net2.so\f1\s0" at 550,290
circle rad 138 at 552,388
"\fR\s8\&libnsl.so\f1\s0" at 554,372
circle rad 28 at 552,372
"\fR\s10\&libX11.so\f1\s0" at 552,450
"\fR\s10\&4.0 CLIENT\f1\s0" at 550,500
box ht 40 wid 104 with .nw at 132,718 
"\fR\s10\&Network N\f1\s0" at 184,696
line <-> from 276,622 to 412,622 dotted
"\fR\s18\&...\f1\s0" at 188,665
line <-> from 164,678 to 132,534 
line <-> from 180,606 to 148,534 
line <-> from 196,568 to 166,530 
line <-> from 468,606 to 548,526 
line  from 346,714 to 346,46 dashed
box ht 40 wid 104 with .nw at 412,646 
"\fR\s10\&Network 2\f1\s0" at 464,624
"\fR\s12\&Machine A (SVR 4.0)\f1\s0" at 136,84
"\fR\s12\&Machine B (SVR 4.0)\f1\s0" at 550,84
"\fR\s10\&TLI Interface\f1\s0" at 542,580
"\fR\s10\&TLI Interface\f1\s0" at 92,598
m2 with .nw at 172,646
box ht 40 wid 104 with .nw at 196,598 
"\fR\s10\&Network 1\f1\s0" at 248,576
.PE
.SK
.FG"Both Client and Server Machine Running SVR4.0 (Client Built in 3.2.x Environment)"
.PS
scale=150
define m0 |
[ box invis ht 36 wid 68 with .sw at 0,0
ellipse ht 36 wid 68 at 34,18
] |

define m1 |
[ box invis ht 40 wid 104 with .sw at 0,0
"\fR\s10\&libX11_s\f1\s0" at 52,18
ellipse ht 40 wid 104 at 52,20
] |

define m2 |
[ box invis ht 64 wid 128 with .sw at 0,0
ellipse ht 64 wid 128 at 64,32
] |

define m3 |
[ box invis ht 40 wid 104 with .sw at 0,0
box ht 40 wid 104 with .nw at 0,40 
"\fR\s10\&Network 2\f1\s0" at 52,18
] |

box invis ht 716 wid 636 with .sw at 0,0
"\fR\s14\&xntad\f1\s0" at 552,292
circle rad 28 at 550,248
line  from 548,220 to 548,188 
"\fR\s10\&net2.so\f1\s0" at 546,166
m0 with .nw at 514,190
circle rad 88 at 548,232
box ht 40 wid 104 with .nw at 414,644 
"\fR\s10\&Network 2\f1\s0" at 466,622
"\fR\s12\&Machine A (SVR 4.0)\f1\s0" at 138,84
"\fR\s12\&Machine B (SVR 4.0)\f1\s0" at 552,84
"\fR\s10\&TLI Interface\f1\s0" at 544,578
"\fR\s10\&TLI Interface\f1\s0" at 94,596
m3 with .nw at 174,644
box ht 40 wid 104 with .nw at 198,596 
"\fR\s10\&Network 1\f1\s0" at 250,574
"\fR\s10\&libX11.so\f1\s0" at 140,456
"\fR\s10\&SERVER\f1\s0" at 138,506
m2 with .nw at 70,490
m0 with .nw at 40,358
m0 with .nw at 104,318
m0 with .nw at 168,352
circle rad 28 at 142,378
line  from 102,350 to 120,362 
line  from 138,426 to 138,406 
line  from 140,350 to 140,318 
"\fR\s10\&net2.so\f1\s0" at 138,296
"\fR\s10\&net1.so\f1\s0" at 74,336
"\fR\s10\&netN.so\f1\s0" at 202,332
line  from 166,360 to 182,348 
"\fR\s8\&libnsl.so\f1\s0" at 144,378
circle rad 138 at 140,394
"\fR\s8\&3.2.x CLIENT\f1\s0" at 550,488
circle rad 68 at 550,448
line <-> from 550,380 to 550,322 
box ht 40 wid 104 with .nw at 134,716 
"\fR\s10\&Network N\f1\s0" at 186,694
line <-> from 278,620 to 414,620 dotted
"\fR\s18\&...\f1\s0" at 190,663
line <-> from 166,676 to 134,532 
line <-> from 182,604 to 150,532 
line <-> from 198,566 to 168,528 
line <-> from 470,604 to 544,518 
m1 with .nw at 500,438
line  from 348,712 to 348,44 dashed
"\fR\s8\&libnsl.so\f1\s0" at 550,250
.PE
.fi
.H 1 "Appendix B:  Nameserver Requirements (SVR 3.2.x only)"
.H 2 "Service Types"
.P
Service types that are requested by the X\s-2WIN\s+2 server and clients,
are identified
by the \fItype\fR of the message (\f4INTEGER3\fR in the HEADER above).
The following types
are defined in the header file \f4BSD/include/Xstreams.h\f1 and must be
provided by each nameserver:
.DS
\f4
		ConvertNetAddrToName
		ConvertNameToNetAddr
		ConvertNameToTliCall
		ConvertTliCallToName
		ConvertNameToTliBind
\f1
.DE
.P
\fBConvertNetAddrToName:\fR  Each \f4HOSTINFO\fR entry contains a host
address in \f4NET_TYPE\fR format that needs to be converted to the
associated host name.  If the network family is equal to \f4FamilyUname\fR\*F
then no conversion is needed and the same address will be sent back as the
host name. 
.AB N
\f4FamilyUname\fR is defined in the header file
\f4BSD/include/Xstreams.h\fR.
.AC
.P
\fBConvertNameToNetAddr:\fR  Each \f4HOSTINFO\fR entry contains a host
name that needs to be converted to its associated address in the
\f4NET_TYPE\fR format.
If the nameserver fails to obtain that address for some reason,
then the name will be sent back as the address and the network family is set
to \f4FamilyUname\fR instead of the family of \f(CWNET_TYPE\fR.
\f4ConvertNameToNetAddr\fR and \f(CWConvertNetAddrToName\fR
are requested by the X\s-2WIN\s+2 server and xhost to Add, Delete or List 
the hosts access list. For example, if the user wants to add host "foo"
to a remote server that can be accessed over network "A", xhost will send
a \f4ConvertNameToNetAddr\fR call to the
nameserver associated with network "A"
which sends back the address of "foo" in network "A" format. Xhost then
calls \f4XRemoveHost()\f1 which will send an X request containing that
address to the remote server. When the server receives that request, it will
send a \f4ConvertNetAddrToName\fR to the
"A" nameserver which returns the "foo"
back to it. The server then deletes that name if it is found in its 
current hosts access list.
.P
\fBConvertNameToTliCall:\fR  Usually, this type of messages contains one
\f4HOSTINFO\fR that contains the name of a machine the client wishes to
\f4t_connect()\f1 to and expects the address in the TLI \f(CWt_call\fP
format. 
.P
\fBConvertTliCallToName:\fR  This message type is the reverse of the
previous type. A TLI \f4t_call\f1 address is sent and the name of the
caller is needed.
.P
\fBConvertNameToTliBind:\fR  A machine name and a port is sent in this type
of message and the corresponding address in TLI \f4t_bind\f1 format is
expected. 
.H 1 "Appendix C:  Communication Protocol"
Communications between the X\s-2WIN\s+2 System and  the nameservers
use a defined protocol that new nameservers must follow.
Messages  sent by either the X\s-2WIN\s+2 server or its clients
to \f4xdaemon\fR have the following format:
.DS
\f4
	-----------------
	| HEADER | DATA |
	-----------------
\f1
.DE
where the HEADER format looks like the following:
.DS
\f4
------------------------------------------------------------------
| INTEGER1 | INTEGER2 | INTEGER3 | INTEGER4 | INTEGER5 | NET_TYPE |
------------------------------------------------------------------

.ft R
	Where:
	
	\f4INTEGER1\fR is the size of the entire message
	\f4INTEGER2\fR is the size of this header
	\f4INTEGER3\fR is the type of the message and may have
              one the following values that are defined in
	      the header file \f4BSD/include/Xstreams.h\fR:

			\f4ConvertNetAddrToName\fR
			\f4ConvertNameToNetAddr\fR
			\f4ConvertNameToTliCall\fR
			\f4ConvertTliCallToName\fR
			\f4ConvertNameToTliBind\fR

	\f4INTEGER4\fR is the display/port number
	\f4INTEGER5\fR is the length of the NET_TYPE string
	\f4NET_TYPE\fR is an ASCII string of characters that identifies the network type
.DE
.sp
.DS
and the DATA format looks as follows:
\f4
	----------------------------------------------------
	| INTEGER1 | INTEGER2 | HOSTINFO1 | ... | HOSTINFOn|
	----------------------------------------------------
.DE
.DS
.ft R
	Where:

	\f4INTEGER1\fR is the size of the DATA area
	\f4INTEGER2\fR is the number of HOSTINFO entries
	\f4HOSTINFOi\fR for i = [1:n]  has the following format:
\f4
	--------------------------------------------
	| xHostEntry structure | host name/address |
	--------------------------------------------
	
.ft R
.ta 4n 8n 12n 16n
	Where: \f4xHostEntry\fR is an X defined data structure type that contains information
			about the network family of the host name/address and its length. Each
			\f4HOSTINFO\fR must be padded so that its size is divisible by 4.
.DE
.ta
.P
\f4Xdaemon\fR will read the type of the network from the above messages
and after forking the required \f4nameserver\fR, \f(CWxdaemon\fR will send
the same message to that \f4nameserver\fR intact.
.P
Reply messages sent back by the nameserver have the same format as the
DATA section described above. The only difference is that
\f4INTEGER1\fR here
is the size of the \f4HOSTINFO\fR entries rather than the size of the entire
DATA area.
