       
                                        Ref:    DXS/PLAT/L1
                                        Date:   06-Dec-91
                                        Author: Paul Sanders
            
       
               CD-ROM Data Exchange Standard (DXS)
            Platform Dependent Implementation Details
                           Version 1.0
       
       
            Paul Sanders
            SilverPlatter Information Ltd.
            10 Barley Mow Passage
            Chiswick
            London W4 4PH
            England
       
            Tel: +44 (0) 81-995 8242
            Fax: +44 (0) 81-995 5159
       
            This document is available in Microsoft Word 5.5
            format from the above address.


































                                   1

                        Table of Contents
       
       .Begin Table C.

1.     Introduction                                        4
  1.1    Change History                                    5
  1.2    References                                        5
  1.3    Trademarks                                        5

2.     Local and Network Database Servers                  5

3.     Client-Server Transfer Syntax                       6

4.     Database Server Access Protocol                     6

5.     Local Database Installation and Selection           6

P1.    Implementation Details - MSDOS                      8
  P1.1   Overview                                          8
  P1.2   Memory Requirements                               9
  P1.3   Loading the Server                                9
  P1.4   Stopping the Server                              10
  P1.5   Passing a Request from the Client to the Server  10
  P1.6   Passing a Response from the Server to the Client 10

P2.    Implementation Details - Microsoft Windows 3.x     11
  P2.1   Overview                                         11
  P2.2   Loading the Server                               11
  P2.3   Stopping the Server                              13
  P2.4   Passing a Request from the Client to the Server  13
  P2.5   Passing a Response from the Server to the Client 14

P3.    Implementation Details - Apple Macintosh           14
  P3.1   Overview                                         14
  P3.2   Loading the Server                               15
  P3.3   Stopping the Server                              15
  P3.4   Passing a Request from the Client to the Server  15
  P3.5   Passing a Response from the Server to the Client 16

P4.    Implementation Details - POSIX                     16
  P4.1   Overview                                         16
  P4.2   Loading the Server                               17
  P4.3   Stopping the Server                              17
  P4.4   Passing a Request from the Client to the Server  18
  P4.5   Passing a Response from the Server to the Client 18

N1.    Implementation Details - TCP/IP                    19
  N1.1   Overview                                         19
  N1.2   Locating Database Servers                        20
  N1.3   Establishing a Connection with a Database Server 21
  N1.4   Sending a Request from the Client to the Server  21
  N1.5   Sending a Response from the Server to the Client 21

N2.    Implementation Details - Novell IPX/SPX            22



                                   2

  N2.1   Overview                                         22
  N2.2   Locating Database Servers                        22
  N2.3   Establishing a Connection with a Database Server 23
  N2.4   Sending a Request from the Client to the Server  24
  N2.5   Sending a Response from the Server to the Client 24

N3.    Implementation Details - NetBios                   24
  N3.1   Overview                                         24
  N3.2   Locating Database Servers                        25
  N3.3   Establishing a Connection with a Database Server 25
  N3.4   Sending a Request from the Client to the Server  26
  N3.5   Sending a Response from the Server to the Client 26
       .End Table C.












































                                   3



1.     Introduction

       This document describes platform and network-protocol
       dependent implementation details for database servers and
       clients conforming to the CD-ROM Data Exchange Standard
       (DXS).
       
       A working knowledge of the following related documents is
       assumed:
          - 'CD-ROM Data Exchange Standard Specification'
            (DXS/SPEC)
          - 'CD-ROM Data Exchange Standard Client-Server Transfer
            Syntax' (DXS/CSTS)
          - 'CD-ROM Data Exchange Standard Database Server Access
            Protocol' (DXS/DSAP)
       
       This document defines implementation details for the
       following platforms where the client and the server are
       running in the same computer (a so-called 'local' server,
       see section 2):
          - MS-DOS
          - Microsoft Windows
          - Apple Macintosh
          - POSIX compliant implementations of UNIX and other
            similar operating systems
       
       This document also defines implementation details for the
       client-server communication using the following network
       protocols:
          - TCP/IP
          - Novell IPX/SPX (NetWare)
          - NetBIOS
       
       Interoperability is possible between the following clients
       and servers:
          - MS-DOS client and local MS-DOS server
          - Microsoft Windows client and local Windows server
          - Apple Macintosh client and local Macintosh server
          - POSIX compliant client and a local POSIX server
            (implemented on the same platform)
       
          - a TCP/IP based client on any platform and a TCP/IP
            based server on any platform
          - an IPX/SPX based client on any platform and an
            IPX/SPX based server on any platform
          - a NetBIOS based client on any platform and a NetBIOS
            based server on any platform, provided that
            compatible NetBIOS implementations are used on both
            (this generally means buying all NetBIOS
            implementations from the same vendor)
       




                                   4

       The following items have been omitted from this draft of
       the specification; they should, however, be considered for
       inclusion in later versions:
          - how to access a local server under OS/2
          - how to access a network server over Apple's Localtalk
            protocols
          - how to access a network server over the 'PinkBook'
            protocols (as used by Janet, and thus in many UK
            Universities)


1.1    Change History

       This is the first live version of this document.


1.2    References

       'Internetworking with TCP/IP', Douglas Comer, Prentice
       Hall, 1988, (ISBN 0-13-470188-7).
       
       From the Novell Professional Development Series (Novell
       Inc, PO Box 9502, Austin, Texas 78766-9947):
          - NetWare System Interface Technical Overview
          - NetWare System Calls - DOS
          - NetWare C Interface - DOS
       
       Microsoft Windows 3.0 Software Development Kit Reference
       (Microsoft reference: SY0302a-300-R00-1089 (part 1),
       SY0302b-300-R00-1089 (part 2)).


1.3    Trademarks

       Apple and Macintosh are registered trademarks of Apple
       Computer Inc.
       
       MS-DOS and Microsoft Windows are registered trademarks of
       Microsoft Corporation.
       
       Novell and Netware are registered trademarks, and IPX and
       SPX are trademarks of Novell Inc.
       
       OS/2 is a registered trademark of International Business
       Machines Inc.


2.     Local and Network Database Servers

       A local server runs on an end-user's personal machine; the
       client software is also running on this machine.  The user
       selects from a list of databases which he has previously
       installed (unless, perhaps, there is only one); the client
       then loads the appropriate server into memory.  The user



                                   5

       is prompted (by the server) to load CD's into his drive(s)
       as necessary.
       
       A network server is a 'black box' accessed over a
       communications network.  The user selects from a list of
       databases mounted on the available server(s) (mounting and
       unmounting databases on a network server is a supervisory
       activity which is outside the scope of the Data Exchange
       Standard).  The mechanism by which the client software
       obtains a list databases mounted on a network server is
       described in section 5.
       
       It is, of course, possible to build client software that
       accesses both network and local servers.


3.     Client-Server Transfer Syntax

       Please refer to document 'Client-Server Transfer Syntax'
       (DXS/CSTS).  This describes a flexible message format for
       conveying requests from the client to the server, and for
       returning the server's responses.
       
       It also describes basic BYTE, WORD and DWORD data types
       used for communicating between machines with different
       native byte orders.
       
       Note that the above document allows the client to send a
       message to the server at any time, and vice-versa.  It
       follows that both the server and the client should check
       regularly for incoming messages.  The server should queue
       a request that it is unable to execute immediately.


4.     Database Server Access Protocol

       Please refer to document 'Database Server Access Protocol'
       (DXS/DSAP).  This details the requests that a DXS-
       compliant Database Server must be able to accept and the
       responses that it should generate.


5.     Local Database Installation and Selection

       When a database is installed on a local server, an entry
       is made in a file of installed databases.  This file
       allows clients to display a list of installed databases to
       choose from and to load the relevant server when the user
       wants to search one.
       
       The client needs to know the name and location of this
       file - this should be configurable.  Recommended names are
       given for each platform in the 'implementation details'
       sections.



                                   6

       
       The file is an ASCII text file, in the native format of
       the platform in question.  There is a section in the file
       for each installed database, in the following format (one
       line per item):
       
            $$DATABASE
            DBID=<Database ID>
                      (vendor prefix (see notes below), followed
                      by upto 8 characters, A-Z, 0-9, underscore)
            DBNAME=<Database name>
                      (upto 36 characters)
            IPNAME=<Information Provider>
                      (upto 36 characters)
            PUBLISHER=<Publisher>
                      (upto 36 characters)
            DETAILS=<Database details>
                      (upto 160 characters)
            SVDIR=<Server executable directory>
                      (upto 64 characters)
            SVEXE=<Server executable filename>
                      (upto 15 characters)
            MEMREQ=<Conventional memory required> (KB)
                      (1KB = 1024 bytes)
            MEMDES=<Conventional memory desired> (KB)
            XMSREQ=<Extended memory required> (KB)
            XMSDES=<Extended memory desired> (KB)
            EMSREQ=<Expanded memory required> (KB)
            EMSDES=<Expanded memory desired> (KB)
       
       Notes:
          - Blank lines and lines starting with a semi-colon are
            ignored.
          - Within an item, \n is interpreted as a line break,
            and \\ as a backslash.  Line breaks are only
            permitted in the 'Database details' item.
          - The database ID starts with a vendor prefix of up to
            4 characters, including a terminating '$' symbol.
            Vendor prefixes must be centrally administered.
          - References to extended and expanded memory apply to
            MS-DOS only.
          - The items do not need to be in the order shown (but
            $$DATABASE must come first)
       
       Example database entry:
            $$DATABASE
            ;
            ; British Library General Catalog of Printed Books
            ;
            DBID=SZ$CPB1975
            DBNAME=Catalog of Printed Books
            IPNAME=The British Library
            PUBLISHER=Saztec Europe Ltd.
            DETAILS=British Library Catalog\nof Books and Serials



                                   7

            SVDIR=C:\\BLGCDIR
            SVEXE=BLGC.EXE
            MEMREQ=100
            MEMDES=256
            XMSREQ=0
            XMSDES=0
            EMSREQ=512
            EMSDES=9999
       
       It is the server vendor's responsibility to provide a
       suitable installation program which updates this file.
       
       It is the client program's responsibility to display a
       suitable database selection screen for the end-user, and
       to load the appropriate local server when a local database
       is selected.
       
       The mechanism by which the server is loaded is platform
       specific - see the 'Implementation Details' section for
       the platform in question.


P1.    Implementation Details - MSDOS



P1.1   Overview

       This section describes how a local server is loaded and
       accessed by a client running under MS-DOS.  Only one local
       server can be loaded at any one time.
       
       It is recommended that fully qualified pathname of the
       file of installed databases is placed in an environment
       variable called DXSDBFILE.  If this is not set, assume
       C:\DXSDBLST.CFG
       
       The server is loaded by the client application (as
       described below) when the user selects a database.  This
       allows the end-user to switch between databases quickly
       and easily.
       
       There are three major problems implementing the client-
       server model under MS-DOS:
         a) shortage of addressable memory
         b) loading different servers on demand
         c) the client and the server need to run (or appear to
            run) as two separate, asynchronous processes
       
       The following sections describe mechanisms to tackle these
       problems.






                                   8

P1.2   Memory Requirements

       Before loading the server, the client should do its best
       to ensure that the amount of conventional, extended and
       expanded memory required by the server is available (i.e.
       it should release some of these resources if it has
       allocated them all).  If possible, it should free up the
       amount of memory desired in each category.
       
       It is strongly recommended that a server should not
       require more than 150k of conventional memory.  The best
       (perhaps the only) way to achieve this is to implement the
       server using a commercially available DOS extender such as
       Rational Systems DOS 16M.  This solution may not be
       commercially viable, however, and there may be
       compatibility problems with clients which use a DOS
       extender.


P1.3   Loading the Server

       To load the server, the client uses the MS-DOS EXEC
       function (AH = 0x4B) to 'spawn' the server program,
       passing the following arguments in the command line:
       
            /C:<callback address>
            /D:<server executable directory>
            /Q:<request buffer address>
            /R:<response buffer address>
       
       Addresses are passed as an 8 digit hex-ascii string, e.g.
       3A142D11 (representing segment 3A14, offset 2D11).  If the
       client is using a DOS extender, all addresses must be real
       mode addresses.
       
       When it is loaded, the server performs its initialisation
       and then calls the callback address supplied in the
       command line.  Parameters are passed to this routine as
       follows:
            AX    - error code
            ES:BX - pointer to error message
            CX:DX - entry point
       Again, all addresses must be real mode addresses, and the
       server must switch to real mode before calling the client.
       
       The client regains control at this point and can issue a
       request to the server as described below.  The client can
       give control to the server at any time by switching to
       real mode and calling the server's entry point with AX =
       0.
       
       If server initialisation fails, AX will be non-zero and
       ES:BX will point to a null-terminated English language




                                   9

       error message.  The client must then stop the server as
       described below.


P1.4   Stopping the Server

       To stop the server, the client calls the server's entry
       point passing AX = 1.  The server does not return from
       this call.  Instead, it terminates, thus returning to the
       client immediately after the original EXEC call.  The
       client then (presumably) prompts the user to select a
       different database and then loads the appropriate server.


P1.5   Passing a Request from the Client to the Server

       The request buffer is 1026 bytes long and is allocated by
       the client.  It can hold a single request at a time.  If
       there is a request in the buffer, the first two bytes
       contain the length of the request in Intel (LS bytes
       first) format.  If the buffer is empty, these two bytes
       are zero.  The remainder of the buffer holds a request of
       up to 1024 bytes.
       
       To pass a request to the server, the client first checks
       that the request buffer is empty.  If it is, the client
       copies the request to the buffer and sets the length
       appropriately.  If not, the client must wait until it is
       (during which time it should loop calling the server's
       entry point and checking for a response from the server).
       
       Whenever the server's entry point is called, it checks for
       incoming requests.  When it sees one, it reads it, zeroes
       the first two bytes of the request buffer, and acts on it.
       
       If the server is unable to complete the request within 1/2
       second or so, it returns to the client, maintaining its
       current context such that it can continue processing the
       request when its entry point is next called (probably by
       switching stacks).
       
       The client can cancel the current request by sending a
       'Cancel request' request.


P1.6   Passing a Response from the Server to the Client

       The response buffer uses the same structure as the request
       buffer.
       
       To pass a response to the client, the server first checks
       that the response buffer is empty.  If it is, the server
       copies the response to the buffer and sets the length




                                   10

       appropriately.  If not, the server returns to the client
       and tries again when its entry point is next called.
       
       The client checks for incoming messages in the same manner
       as the server does.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.


P2.    Implementation Details - Microsoft Windows 3.x



P2.1   Overview

       This section describes how a local server is loaded and
       accessed by a client running under Microsoft Windows.
       Several local servers (or several copies of the same
       server) can be loaded at any one time.
       
       It is recommended that fully qualified pathname of the
       file of installed databases is placed in an environment
       variable called DXSDBFILE.  If this is not set, assume
       C:\DXSDBLST.CFG
       
       A server is loaded by the client application (as described
       below) when the user selects a database.  This allows the
       end-user to switch between databases quickly and easily.
       
       Communication is via a variant of Windows Dynamic Data
       Exchange (DDE) protocol.  DDE is documented in chapter 15
       of the Microsoft Windows 3.0 Software Development Kit
       Reference.  Note that the way in which DDE is used here is
       not compatible with the way it is used by programs like
       Excel.  This is because DDE is designed to pass
       information in a similar way to the Windows Clipboard, and
       this is not appropriate to the problem at hand.
       
       Since Windows supports multi-tasking, no special tricks
       are necessary.  Both clients and servers should yield
       control regularly (by calling PeekMessage) however, in
       order for Windows co-operative multi-tasking mechanism to
       operate smoothly.


P2.2   Loading the Server

       The client first checks whether the required server is
       already loaded by using the Windows SendMessage function
       to broadcast a WM_DDE_INITIATE message with:
          - hWnd = 0xFFFF (send to all top-level windows)
          - wMsg = WM_DDE_INITIATE




                                   11

          - wParam = window that will handle the client's end of
            the DDE connection
          - low word of lParam (the 'application') = a global
            atom containing the filename of the server
            application (no extension)
          - high word of lParam (the 'topic') = a global atom
            containing the nul-terminated string "_DXS_DBSRVR"
            (note the leading underscore)
       
       The client creates and deletes the atoms.
       
       The server should respond to the WM_DDE_INITIATE message
       if:
          - the application specified is NULL or matches the
            server's application name
          - the topic specified is NULL or "_DXS_DBSRVR"
       
       It does so by calling SendMessage to return a WM_DDE_ACK
       message to the client with:
          - hWnd = window handling the client's end of the DDE
            connection
          - wMsg = WM_DDE_ACK
          - wParam = handle of a newly created (hidden) window
            that will handle the server's end of the DDE
            connection
          - low word of lParam (the 'application') = a global
            atom (created by the server) containing the filename
            of the server application (no extension)
          - high word of lParam (the 'topic') = a global atom
            (created by the server) containing the nul-terminated
            string "_DXS_DBSRVR"
       
       If the server cannot handle any more connections, it
       should return a WM_DDE_ACK message as above, but with
       wParam set to 0.  This is not an uncommon circumstance; it
       is easier to write a server that can only handle one
       connection than several.
       
       If the server is not loaded, no WM_DDE_ACK message will be
       received.  The client can count on receiving all
       WM_DDE_ACK messages before the SendMessage call to send
       the WM_DDE_INITIATE message returns.
       
       If the client needs to load the server (or another copy of
       the server), it does so by calling WinExec, passing the
       following arguments in the command line:
            /D:<server executable directory>
       
       The client should then re-issue the WM_DDE_INITIATE
       message.







                                   12

P2.3   Stopping the Server

       To stop the server, the client sends a WM_DDE_TERMINATE
       message by calling PostMessage with:
          - hWnd = window handling the server's end of the DDE
            connection
          - wMsg = WM_DDE_TERMINATE
          - wParam = window handling the client's end of the DDE
            connection
          - lParam = 0
       
       The server responds by sending back a WM_DDE_TERMINATE
       message and shutting down the connection.  If there are
       now no connections open, the server terminates.  The
       message is returned by calling PostMessage with:
          - hWnd = window handling the client's end of the DDE
            connection
          - wMsg = WM_DDE_TERMINATE
          - wParam = window handling the server's end of the DDE
            connection
          - lParam = 0
       
       The server may also terminate a connection by sending a
       WM_DDE_TERMINATE message to the client.  The client must
       send a WM_DDE_TERMINATE message back and consider the
       connection closed.


P2.4   Passing a Request from the Client to the Server

       To pass a request to the server, the client sends a
       WM_DDE_DATA message by calling PostMessage with:
          - hWnd = window handling the server's end of the DDE
            connection
          - wMsg = WM_DDE_DATA
          - wParam = window handling the client's end of the DDE
            connection
          - low word of lParam = a Global handle pointing to the
            request (NOT a Windows DDEDATA structure)
          - high word of lParam = 0
       
       The client must allocate the request handle with the
       GMEM_DDESHARE attribute.  The server will free the handle
       when it receives the message.  If PostMessage returns
       FALSE, the client must free the handle.
       
       When the server is idle, it calls WaitMessage.  This
       minimises the load imposed on the CPU.  When the server is
       executing a request, it calls PeekMessage periodically to
       check for a 'cancel request' request from the client.
       
       If the server receives a WM_DDE_REQUEST, WM_DDE_ADVISE,
       WM_DDE_UNADVISE, WM_DDE_POKE or WM_DDE_EXECUTE message, it
       rejects it by calling PostMessage with:



                                   13

          - hWnd = window from which the message was received
          - wMsg = WM_DDE_ACK
          - wParam = window handling the server's end of the DDE
            connection
          - low word of lParam = return status:
               - bit 15 (fAck) = 0
               - bit 14 (fBusy) = 0
               - bits 8..13 (reserved) = 0
               - bits 0..7 (error code) = 255
          - high word of lParam = 0


P2.5   Passing a Response from the Server to the Client

       To pass a response to the client, the server sends a
       WM_DDE_DATA message by calling PostMessage with:
          - hWnd = window handling the client's end of the DDE
            connection
          - wMsg = WM_DDE_DATA
          - wParam = window handling the server's end of the DDE
            connection
          - low word of lParam = a Global handle pointing to the
            request (NOT a Windows DDEDATA structure)
          - high word of lParam = 0
       
       The server must allocate the request handle with the
       GMEM_DDESHARE attribute.  The client will free the handle
       when it receives the message.  If PostMessage returns
       FALSE, the server must free the handle.
       
       The client checks for incoming messages in the same manner
       as the server does.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.


P3.    Implementation Details - Apple Macintosh



P3.1   Overview

       This section describes how a local server is loaded and
       accessed by a Macintosh client.  System 7.0 or later is
       assumed.  Several local servers (or several copies of the
       same server) can be loaded at any one time.
       
       It is recommended that the file of installed databases be
       called DXSDBLST.CFG, and that it be placed in a folder
       called DXSFOLDR inside the system folder.
       





                                   14

       A server is loaded by the client application (as described
       below) when the user selects a database.  This allows the
       end-user to switch between databases quickly and easily.
       
       Each client loads its own copy of the server (s) that it
       wants to use.  Communication between the client and each
       of its servers is via the system 7 Event manager
       extensions supporting PPC (Program to Program
       Communication) using the new 'high-level' events.
       
       A well-known value for msgClass will be applied for and
       used in all events.


P3.2   Loading the Server

       To load the server, the client uses the LaunchApplication
       function, specifying dontBringToFront and (probably)
       returnLaunch.
       
       This call returns a process ID which can be used to
       communicate with the server.


P3.3   Stopping the Server

       To stop a server, the client issues a call to
       PostHighLevelEvent, passing the server's process ID in
       receiverID, 0 in EventRecord.what, and NULL in msgbuf.
       The client should then call MFWakeUp in case the server is
       sleeping.
       
       When the server receives this event, it should terminate.
       
       The server must call AcceptHighLevelEvent when it is
       informed (by WaitNextEvent) that a high level event is
       available.


P3.4   Passing a Request from the Client to the Server

       The client passes a request to the server by issuing a
       call to PostHighLevelEvent, passing the server's process
       ID in receiverID, 1 in EventRecord.what, and a pointer to
       the request in msgbuf.  The client should then call
       MFWakeUp in case the server is sleeping.  While the client
       is awaiting the response, it may call MFSleep if it so
       chooses.
       
       The server must call AcceptHighLevelEvent when it is
       informed (by WaitNextEvent) that a high level event is
       available.
       
       When the server is idle, it calls MFSleep.



                                   15

       
       When the server is executing a request, it needs to check
       periodically for a 'cancel request' request from the
       client.  It does this by calling WaitNextEvent passing
       app4Mask in mask and 0 in sleep.  If a high level event is
       waiting, AcceptHighLevelEvent must be called.


P3.5   Passing a Response from the Server to the Client

       The server passes a response to the client by issuing a
       call to PostHighLevelEvent, passing the client's process
       ID in receiverID, 1 in EventRecord.what, and a pointer to
       the response in msgbuf.  The server should then call
       MFWakeUp in case the client is sleeping.
       
       The client checks for incoming messages in the same manner
       as the server does.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.


P4.    Implementation Details - POSIX



P4.1   Overview

       This section describes how a local server is loaded and
       accessed by a client running under a POSIX-compliant
       version of UNIX or other operating system.  POSIX
       describes a number of Operating System services available
       to applications, and the ANSI C programming interface to
       access them.  Several local servers (or several copies of
       the same server) can be loaded at any one time.
       
       It is recommended that fully qualified pathname of the
       file of installed databases is placed in an environment
       variable called DXSDBFILE.  If this is not set, assume
       /etc/dxsdblst.cfg
       
       A server is loaded by the client application (as described
       below) when the user selects a database.  This allows the
       end-user to switch between databases quickly and easily.
       
       Each client loads its own copy of the server (s) that it
       wants to use (most modern UNIX systems share code between
       multiple invocations of the same program).  Communication
       between the client and each of its servers is via an un-
       named pipe.






                                   16

P4.2   Loading the Server

       To load the server, the client uses the POSIX EXEC
       function to run the server program from a child process,
       passing the following arguments in the command line:
       
            /D:<server executable directory>
       
       The code sequence to do this is as follows:
       
            int       mypipe [2];
            pid_t     child_pid;
       
            pipe (fildes);              /* make the pipe */
            switch (child_pid = fork()) /* spawn child process */
            {
                 case -1:               /* error spawning child*/
                      panic!
                 case 0:                /* this is the child: */
                                        /*   attach pipe to   */
                                        /*   stdin and stdout */
                                        /*   and exec server  */
                      close (STDIN_FILENO);
                      if (dup (mypipe [0]) != STDIN_FILENO)
                           panic!
                      close (mypipe [0]);
                      close (STDOUT_FILENO);
                      if (dup (mypipe [1]) != STDOUT_FILENO)
                           panic!
                      close (mypipe [1]);
                      execle (server_executable_file_pathname,
                              server_executable_file_pathname,
                              cmd_line_arg_1,
                              cmd_line_arg_2,
                              ... ,
                              NULL);
                      panic!            /* error in exec */
            }
            
            .                           /* this is the parent */
            .                           /* read from pipe [0] */
            .                           /* write to  pipe [1] */


P4.3   Stopping the Server

       To stop a server, the client closes both halves of the
       pipe and waits for the server to terminate.  When the
       server detects end-of-file on stdin, it terminates.
       
       Client:
            close (mypipe [0]);
            close (mypipe [1]);
            waitpid (child_pid, &status, 0);



                                   17

       
       Server:
            if (read (STDIN_FILENO, buf, bufsize) == 0)
                 exit (0);


P4.4   Passing a Request from the Client to the Server

       The client passes a request to the server by writing the
       request to mypipe [1].  Depending on the way that the
       operating system buffers data written to pipes, the client
       may be blocked until the server reads the pipe.
       
       When the server is idle, it performs a blocking read on
       stdin to minimise CPU overhead.
       
       When the server is executing a request, it needs to check
       periodically for a 'cancel request' request from the
       client.  It needs to use a non-blocking read for this:
            flags = fcntl (STDIN_FILENO, F_GETFD);
            fcntl (STDIN_FILENO, F_SETFD, flags | O_NONBLOCK);
            if (read (STDIN_FILENO, buf, bufsize) > 0)
                 we have a request - act on it
            fcntl (STDIN_FILENO, F_SETFD, flags);
       
       The server should allow for the fact that a single read
       call may return part of a request or more than one
       request.


P4.5   Passing a Response from the Server to the Client

       The server passes a response to the client by writing the
       request to stdout.  Depending on the way that the
       operating system buffers data written to pipes, the server
       may be blocked until the client reads the pipe.
       
       The client checks for incoming messages in the same manner
       as the server does.
       
       The client should allow for the fact that a single read
       call may return part of a response or more than one
       response.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.











                                   18

N1.    Implementation Details - TCP/IP



N1.1   Overview

       This section describes how a network database server is
       located and accessed over TCP/IP.  A working knowledge of
       the TCP/IP protocol suite is assumed.  For more details on
       TCP/IP, refer to: 'Internetworking with TCP/IP' by Douglas
       Comer, Prentice Hall, 1988.
       
       Commercial TCP/IP implementations are available for MS-DOS
       based PC's, Apple Macintosh and most if not all UNIX
       variants.
       
       This section assumes that the following services are
       available to both the client and the server:
          - TCP (Transmission Control Protocol)
          - some form of mapping from a 4 byte internet address
            to a physical network address (MAC address)
       
       The following services are optional, but recommended:
          - ARP (Address Resolution Protocol)
          - DNS (Domain Name Service)
       
       The following services are optional:
          - UDP (Unreliable Datagram Protocol) with broadcast
            capability
       
       UDP provides unreliable datagram delivery on an internet
       of networks and sub-nets.  Datagrams are routed between
       networks and sub-nets by a variety of means.  Each network
       is identified by a unique network number assigned by the
       administrator of the internetwork, or by a central
       authority.  Within each network, each sub-net has a unique
       number assigned by the administrator of that network.
       
       TCP provides a reliable byte-stream oriented service on a
       previously established connection.
       
       Port numbers are used to route incoming packets to the
       correct process within a multi-tasking machine.  Database
       servers use a well-known port number (which implies that
       two database servers cannot be run on the same machine).
       Clients use dynamically allocated port numbers.
       
       Well-known UDP and TCP port numbers for database servers
       will be applied for.








                                   19

N1.2   Locating Database Servers

       To communicate with a database server, it is necessary for
       the client to discover the server's 4 byte internet
       address and physical network address (MAC address).
       
       Database servers may be located in one of three ways:
         a) via a file of internet addresses stored on the client
         b) via a file of internet names stored on the client (if
            Domain Name Service is available)
         c) via a UDP broadcast (if broadcasts are supported on
            the underlying network)
       
       (a) requires only that the internet address be mapped to
       the appropriate MAC address.  This will be handled by the
       TCP/IP implementation in the client.  It may require a
       file of internet address to MAC address mappings stored on
       the client, or an ARP (Address Resolution Protocol) server
       may be present on the network.  On some networks,
       broadcasts are used.
       
       (b) requires that the internet name be mapped to the
       corresponding internet address.  This will also be handled
       by the TCP/IP implementation on the client.  It may imply
       a file of internet name to internet address mappings
       stored on the client, or a Domain Name server may be
       present on the network.
       
       (c) can only be used on networks that support broadcasts.
       To locate database servers on the same network and sub-net
       as itself, the client broadcasts a UDP Datagram to the
       server's well-known UDP port with destination address as
       follows:
            net address = 0
            sub-net address = 0
            host address = all 1's
       And with the following contents:
            WORD      message type (value 1)
            DWORD     client internet address
            WORD      client UDP port number
            BYTE[16]  client MAC address
       
       The client sends this broadcast a total of four times at
       two second intervals, and collates and de-duplicates the
       replies.
       
       When a database server receives such a UDP datagram, it
       waits for a random period of time between 0 and 0.5
       seconds, and then returns a UDP datagram to the client
       with the following contents:
            WORD      message type (value 1)
            DWORD     server internet address
            WORD      server TCP port number
            BYTE[16]  server MAC address



                                   20

       
       To locate database servers on other networks and sub-nets,
       the client can broadcast a UDP datagram to each network
       and sub-net that it knows about in turn.  This of course
       requires that a list of known networks and sub-nets be
       stored on the client.


N1.3   Establishing a Connection with a Database Server

       Before it can communicate with a database server, the
       client must establish a TCP connection with it.
       
       The client opens a dynamic TCP port and then issues a
       connect request, supplying the database server's internet
       address and TCP port number.  The TCP/IP implementation in
       the client takes care of the rest.  The client should
       never open more than one connection on the same port.
       
       The server needs to listen for connect requests on its
       well-known TCP port number.  The TCP/IP implementation in
       the server will inform the server application when a new
       connection is established.  A single TCP port can handle
       connections with several clients (and/or several
       connections with the same client) simultaneously.


N1.4   Sending a Request from the Client to the Server

       The client sends a request to the database server over an
       established TCP connection.  If the server has several
       connections open on the same port, the TCP/IP
       implementation in the server will route the packet to the
       process that owns the server's end of the connection.
       
       TCP is a stream-oriented protocol.  The Client-Server
       Transfer Syntax described in section 4 does not require
       message boundaries to be preserved.
       
       TCP's 'push' mechanism should be used to ensure that the
       request is delivered promptly (otherwise the sending end
       may keep part or all of it in a holding buffer).


N1.5   Sending a Response from the Server to the Client

       The database server sends a response to the client over an
       established TCP connection.
       
       TCP's 'push' mechanism should be used to ensure that the
       request is delivered promptly (otherwise the sending end
       may keep part or all of it in a holding buffer).
       




                                   21

       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.


N2.    Implementation Details - Novell IPX/SPX



N2.1   Overview

       This section describes how a network database server is
       located and accessed over Novell's IPX/SPX protocols.  A
       working knowledge of these protocols is assumed.  These
       are documented in the following manuals, which form part
       of Novell's Professional Development Series:
          - NetWare System Interface Technical Overview
          - NetWare System Calls - DOS
          - NetWare C Interface - DOS
       
       IPX provides unreliable datagram delivery over an
       internetwork of LAN's.  Datagrams are routed between LAN's
       by Novell file servers or bridges.  Each LAN is identified
       by a unique network number assigned by the administrator
       of the internetwork.
       
       SPX provides reliable, sequenced packet delivery on a
       previously established connection.
       
       Socket numbers are used to route incoming packets to the
       correct process within a multi-tasking machine.  Database
       servers use a well-known socket number (which implies that
       two database servers cannot be run on the same machine).
       Clients use dynamically allocated socket numbers.
       
       Well-known IPX and SPX socket numbers for database servers
       will be applied for.


N2.2   Locating Database Servers

       To communicate with a database server, it is necessary for
       the client to discover the server's IPX address.  This is
       made up of a 4 byte network number,  a 6 byte node number
       and a 2 byte socket number.  The network number is used by
       Novell file servers and bridges to route packets through
       the internet; the node number corresponds to the physical
       network address (MAC address); the socket number is the
       database server's well-known SPX socket number.
       
       Database servers may be located in one of two ways:
         a) via a file of SPX addresses stored on the client
         b) via an IPX broadcast
       
       (a) requires no action on the part of the client.



                                   22

       
       (b) can be used to find database servers on the same LAN
       as the client, and also on other LANS accessible via
       Novell bridges and Novell file servers acting as bridges.
       
       To locate database servers on the same LAN as itself, the
       client broadcasts an IPX datagram to the server's well-
       known IPX socket with destination address as follows:
            network number = 0
            node           = 0xFFFFFFFFFFFF
       And with the following contents:
            WORD      message type (value 1)
       
       The client sends this broadcast a total of four times at
       two second intervals, and collates and de-duplicates the
       replies.
       
       When a database server receives such a datagram, it waits
       for a random period of time between 0 and 0.5 seconds, and
       then returns an IPX datagram to the client with the
       following contents:
            WORD      message type (value 1)
            WORD      server SPX socket number
       
       To locate database servers on other LAN's, the client has
       to ask its nearest Novell file server or bridge for a list
       of all known network numbers (Novell file servers
       communicate with each other to propagate this
       information), and send an IPX broadcast to each network
       number in turn.  The mechanisms to locate the nearest file
       server and to request a list of known network numbers are
       described in Novell's 'NetWare System Interface Technical
       Overview' and 'NetWare C Interface' manuals.


N2.3   Establishing a Connection with a Database Server

       Before it can communicate with a database server, the
       client must establish an SPX connection with it.
       
       The client opens a dynamic SPX socket and then issues an
       SPXEstablishConnection request, supplying the database
       server's IPX address and SPX socket number.  The client
       should never open more than one connection on the same
       socket.
       
       The server needs to leave an SPXListenForConnection call
       active on its well-known SPX socket number.  It will then
       be informed when a new connection is established.  A
       single SPX socket can handle connections with several
       clients (and/or several connections with the same client)
       simultaneously.





                                   23

N2.4   Sending a Request from the Client to the Server

       The client sends a request to the database server over an
       established SPX connection.  If the server has several
       connections open on the same socket, it must examine the
       connection ID in incoming packets and route the packet to
       the process which owns the server's end of the connection.
       
       SPX can transmit a maximum packet size of 534 data bytes.
       If a request is longer than this, SPX's data stream type
       should be set to 1 in all packets except the last, in
       which it should be set to 0.


N2.5   Sending a Response from the Server to the Client

       The database server sends a response to the client over an
       established SPX connection.
       
       SPX can transmit a maximum packet size of 534 data bytes.
       If a response is longer than this, SPX's data stream type
       should be set to 1 in all packets except the last, in
       which it should be set to 0.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.


N3.    Implementation Details - NetBios



N3.1   Overview

       This section describes how a network database server is
       located and accessed over NetBIOS.  A working knowledge of
       NetBIOS is assumed.  This is documented in IBM's 'NetBIOS
       Application Development Guide'.
       
       NetBIOS is an Application Programming Interface rather
       than a network protocol.  For two computers to communicate
       across NetBIOS, the same vendor's NetBIOS implementation
       must be used on both machines.  NetBIOS is generally
       restricted to IBM PC's running MS-DOS, although there are
       a few implementations in other environments.
       
       NetBIOS provides both unreliable datagram delivery and
       reliable, sequenced message delivery on a previously
       established connection.
       
       NetBIOS requires that communicating entities use a 16 byte
       name, which they must dynamically 'register' on the
       network to check that it is unique.  Several names can be
       registered in the same machine.  NetBIOS also supports



                                   24

       'group names' - several machines can register the same
       group name and a datagram sent to this name will be
       received by all these machines.
       
       NetBIOS is in general restricted to communicating on a
       LAN, although Novell's NetBIOS implementation (for
       example) operates transparently across an IPX
       internetwork.


N3.2   Locating Database Servers

       Each server has a unique name which is assigned by the
       network administrator.  To communicate with a database
       server, it is necessary for the client to discover the
       server's NetBIOS name.
       
       Database servers may be located in one of two ways:
         a) via a file of NetBIOS names stored on the client
         b) by sending a NetBIOS datagram to the group name
            _DXS_DBSRVR padded to 16 bytes with trailing nul's
            (note the leading underscore)
       
       (a) requires no action on the part of the client.
       
       (b) requires all database servers to register the
       specified group name.  The client sends a datagram to this
       name with the following contents:
            WORD      message type (value 1)
       
       The client sends this datagram a total of four times at
       two second intervals, and collates and de-duplicates the
       replies.
       
       When a database server receives such a datagram, it waits
       for a random period of time between 0 and 0.5 seconds, and
       then returns a datagram to the client's unique name with
       the following contents:
            WORD      message type (value 1)
            BYTE[16]  server's unique NetBIOS name


N3.3   Establishing a Connection with a Database Server

       Before it can communicate with a database server, the
       client must establish a NetBIOS session with it.
       
       The client does this by issuing a NetBIOS CALL to the
       server's unique name.
       
       The server needs to leave a LISTEN outstanding on its
       unique name.  It will then be informed when a new session
       is established.  A single name can handle sessions with




                                   25

       several clients (and/or several sessions with the same
       client) simultaneously.


N3.4   Sending a Request from the Client to the Server

       The client sends a request to the database server over an
       established NetBIOS session.  If the server has several
       sessions open on the same name, NetBIOS will route
       incoming messages to the correct receiver.
       
       NetBIOS can accomodate a 1024 byte request in a single
       message.


N3.5   Sending a Response from the Server to the Client

       The database server sends a response to the client over an
       established NetBIOS session.
       
       This mechanism can also be used to send a request (e.g. an
       Error/Warning Request) from the server to the client.
       
       
       
                            oooOOOooo































                                   26
