Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide

Page created by Kent Porter
 
CONTINUE READING
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 Raima Database Manager 11.0
 TFS Configuration and Extension API
 Guide

                                            1
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 Trademarks
 Raima Database Manager® (RDM®), RDM Embedded® and RDM Server® are trademarks of Raima Inc. and
 may be registered in the United States of America and/or other countries. All other names may be trademarks of
 their respective owners.
 This guide may contain links to third-party Web sites that are not under the control of Raima Inc. and Raima Inc.
 is not responsible for the content on any linked site. If you access a third-party Web site mentioned in this guide,
 you do so at your own risk. Inclusion of any links does not imply Raima Inc. endorsement or acceptance of the
 content of those third-party sites.

                                                                                                                        2
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 Contents
    Contents                                 3

    Introduction                             5

    TFS Server Configurations                6

      Introduction                           6

      Direct-Link Configuration              6

        Direct-Link Configuration (TFST):    9

        Client-Server Configuration (TFSR)   10

        Standalone Configuration (TFSS)      10

      Standard Client/Server Configuration   11

      Standalone Configuration               12

    TFS Configuration Settings               14

    TFS Server Extension API                 18

      Introduction                           18

      Step 1: Set Up Hybrid Environment      18

      Step 2: Add XAPI Functions             18

      Step 3: Querying the Database          22

    Enhanced HTTP Monitor                    27

    HTTP Extension API Functions             36

      http_freeURLArgs                       37

      http_getURLArgValue                    38

      http_initURLArgs                       39

        Return Codes                         39

      http_printf                            41

      http_URLDecode                         43

    Summary Listing of TFS API Functions     44

      d_tfsdisconnect                        45

      d_tfsinit, d_tfsinitEx                 48

Contents                                     3
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

      d_tfsIterateConnectedUsers            52

      d_tfsrun                              55

      d_tfsstop                             57

      d_tfsterm                             59

      d_tfsversion                          61

      d_tfsxapiparams                       63

    Glossary                                67

    Index                                   78

Contents                                    4
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 Introduction
 RDM's Transactional File Server (TFS), in addition to controlling database access from runtime libraries, is also
 a simple HTTP server. This means that the TFS is prepared to service the RPCs from runtimes, and also GET
 and POST messages sent from a HTTP client.
 The first implication of this capability is that the TFS can serve HTML pages, contained in files, to HTTP clients.
 This can be a convenient way to share information from the TFS host computer without needing to run a full
 HTTP server.
 The RDM TFS may also be extended such that a programmer can create functions that are linked into the TFS
 and are accessible from HTTP clients through standard URLs. These functions may do anything within the TFS
 environment, including accessing databases.
 This means that an RDM developer has the ability to customize the TFS, adding functionality that can be
 accessed through programs or through standard HTTP clients. Unmodified, the TFS services runtime RPCs
 and HTML file requests. Modified by a programmer, the TFS can recognize additional URLs with parameter
 strings that are passed to Extension API functions.
 An additional ability to select a configuration will be described in this section. Application systems can be con-
 structed that have a client/server architecture or an in-process architecture. Hybrids can be constructed to suite
 specific needs. The following section describes the configuration options.

Introduction                                                                                                           5
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 TFS Server Configurations
 Introduction
 The TFS functionality is accessed through an API. This API is reentrant, so that its functions may be accessed by
 multiple threads concurrently. Anything that can be done with a database is done through the TFS API.
 The runtime library is linked into an application's program space, and performs caching of database pages and
 manipulations of those page contents in order to implement database queries and updates. The application uses
 the runtime's API, sometimes referred to as the "d_" API. To obtain a page from a database, the runtime must
 call a TFS API function. To lock a record or set type, a TFS API function is called. To perform an update to the
 database (transaction), a series of TFS API's are called.
 The location and invocation of TFS functions is configurable. The normal configuration is to have the
 TFS API directly linked into the application program. However, the TFS can be available through a multi-
 threaded TFS Server. This is what the tfserver utility is, where applications linked with runtimes remotely
 access TFS functions through a server, running in a different process.
 A third configuration, discussed below, is a single-process, single-thread application. This special situation does-
 n't require much of the TFS functionality, and a special compact TFS is available for this situation.
 The TFS Configuration types listed below are enumerated types used by d_tfsinitEx and rsqlTFSIn-
 itEx.
 TFS Configuration Types
 TFS_TYPE_DEFAULT                      Factory default TFS type is TFS_TYPE_TFS.
 TFS_TYPE_TFS                          See Direct-Link Configuration
 TFS_TYPE_RPC                          See Standard Client/Server Configuration
 TFS_TYPE_STANDALONE                   See Standalone Configuration

 If a TFS type is not specified, the default TFS type will be used by functions d_tfsinit, rsqlTFSinit and
 d_opentask. Installations with source code can change this default.

 Direct-Link Configuration
 If an application does not require a separate server, it is possible to link the TFS API with the application to make
 it run in-process. Because the TFS functions are reentrant, this application may be multi-threaded. Figure 14-2
 shows this configuration.

TFS Server Configurations                                                                                            6
Raima Database Manager 11.0 - TFS Configuration and Extension API Guide TFS Configuration and Extension API Guide
TFS Configuration and Extension API Guide

 Fig. 14-2. Direct-Link Configuration

 An obvious benefit of this configuration is that the calls from the runtime to the TFS have no intermediate mar-
 shalling/demarshalling or TCP/IP send and receive, so this application should perform better than the same appli-
 cation in the client/server configuration.
 Note that since the RPC mechanism in the client/server configuration makes the TFS functions look local, there
 are no changes required to the application or runtime library to make them work in either configuration.

TFS Server Configurations                                                                                         7
TFS Configuration and Extension API Guide

 Now note the similarity between the TFS Server Process in Figure 14-1 and the Application Program in Figure
 14-2. The only difference between the Server Program and Application Program is that the Server Program
 starts up threads that exist to service connections with other runtimes and call TFS stub functions. The Appli-
 cation Program threads can exist side-by-side with the server connection threads, and an Application Program
 has the ability to start them up if it chooses. If it starts up connection threads, then it is acting as a TFS to other
 applications that are configured to run in the client/server configuration. Figure 14-3 attempts to illustrate this con-
 figuration, which is a combination of direct-link and client/server.

 Fig. 14-3. Hybrid Direct-Link, Client/Server Configuration

TFS Server Configurations                                                                                              8
TFS Configuration and Extension API Guide

 By starting up the server connection threads, the application is allowing other applications to have access to the
 databases that are under the control of this TFS (application). The code below shows the necessary code to start
 up the server connection threads.

    TFS_HANDLE hTFS;    /* handle to control TFS server connection threads */
    char *docroot = "c:/RDM/databases"; /* should be command-line option */
    int32_t rc;
    ...

    if ((rc = d_tfsinit(docroot, NULL, &hTFS)) != S_OKAY)
        error_exit(rc);

    if ((rc = d_tfsrun(hTFS, TRUE, NULL)) != S_OKAY)
        error_exit(rc);

    /* begin Application code */

    ...

    /* Application termination */

    if ((rc = d_tfsstop(hTFS)) == S_OKAY)                 /* stop the server threads */
        d_tfsterm(hTFS);                                  /* free resources */

 It is possible to set the configuration programmatically through the use of the d_tfsinitex(..) function with one of
 the following three parameters: TFS_TYPE_TFS, TFS_TYPE_STANDALONE, or TFS_TYPE_RPC as follows:

 Direct-Link Configuration (TFST):
 This configuration runs the TFS engine within your application, and the database is stored there. The TFST con-
 figuration is ACID compliant. Optionally, the ability to accept remote connections (set in those applications as
 clients using TFS_TYPE_RPC) can also be enabled, allowing your application to act as a server to other users.

    TFS_HANDLE hTFS;
    TFS_PARAMS tparams;
    tparams.port= 21553;
    tparams.rd_only= FALSE;
    tparams.no_disk= FALSE;
    tparams.verbose= FALSE;
    tparams.logfile= NULL;
    tparams.stdout_file= NULL;

    /* start Direct-Link TFS configuration */

    sStatus= d_tfsinitEx ("/my/directory", &tparams, &hTFS, TFS_TYPE_TFS);
    if (sStatus == S_OKAY) {
        DB_TASK *task;
        d_opentask (&task);
        ...
        d_closetask (task);

TFS Server Configurations                                                                                               9
TFS Configuration and Extension API Guide

         d_tfsterm (hTFS);
    }

 Client-Server Configuration (TFSR)
 This configuration does not run any TFS engine in your application, requiring it to connect to a TFS (either
 tfserver or another application in TFST configuration) hosting the database over TCP/IP. This configuration is
 also ACID compliant.

    TFS_HANDLE hTFS;
    TFS_PARAMS tparams;
    tparams.port= 21553;
    tparams.rd_only= FALSE;
    tparams.no_disk= FALSE;
    tparams.verbose= FALSE;
    tparams.logfile= NULL;
    tparams.stdout_file= NULL;

    /* start Direct-Link TFS configuration */

    sStatus= d_tfsinitEx (NULL, &tparams, &hTFS, TFS_TYPE_RPC);
    if (sStatus == S_OKAY) {
        DB_TASK *task;
        d_opentask (&task);
        ...
        d_closetask (task);
        d_tfsterm (hTFS);
    }

 Standalone Configuration (TFSS)
 This configuration runs a TFS engine within your application, however it is not multi-user capable (and therefore
 cannot accept incoming connections), and is not ACID compliant. It is very fast however, and is useful for sit-
 uations where complete safety is not required.

    TFS_HANDLE hTFS;
    TFS_PARAMS tparams;
    tparams.port= 21553;
    tparams.rd_only= FALSE;
    tparams.no_disk= FALSE;
    tparams.verbose= FALSE;
    tparams.logfile= NULL;
    tparams.stdout_file= NULL;

    /* start Direct-Link TFS configuration */

TFS Server Configurations                                                                                         10
TFS Configuration and Extension API Guide

    sStatus= d_tfsinitEx ("/my/directory", &tparams, &hTFS, TFS_TYPE_STANDALONE);
    if (sStatus == S_OKAY) {
        DB_TASK *task;
        d_opentask (&task);
        ...
        d_closetask (task);
        d_tfsterm (hTFS);
    }

 This hybrid configuration may involve application programs that are all identical (i.e. there is one designated to be
 the server, and others are clients), or the server program may be unique while client programs are different. An
 additional function exists to inform a program of the configuration in which it is running, in case there is different
 program logic involved, or if it is an error condition. This is shown by example below.

    uint16_t major;    /* RDM major version number */
    uint16_t minor;    /* RDM minor version number */
    TFS_LIB_TYPE type; /* TFS Library type */
    ...

    d_tfsversion(&major, &minor, &type);
    switch (type) {
        case TFS_LIB_TYPE_TFS:
            /* this program is direct-linked to the TFS library */
            ...
            break;
        case TFS_LIB_TYPE_RPC:
            /* this program is linked as a client to the server, using RPCs */
            ...
            break;
        case TFS_LIB_TYPE_STANDALONE:
            /* this program is linked to the standalone TFS library */
            /* only one thread may access the database functions */
            ...
            break;
    }

 Note that there are two library types where starting up server connection threads does not make sense (TYPE_
 RPC and TYPE_STANDALONE), but in these libraries, the d_tfsinit, d_tfsrun, d_tfsstop and d_
 tfsterm functions simply return successfully, so there is no need to build an application in two ways if it is
 intended for two configurations. In fact, the TYPE_STANDALONE configuration requires the use of the d_
 tfsinit function to establish a root directory for the databases (if not always the current directory).

 Standard Client/Server Configuration
 The runtimes and TFS are running within different processes. The runtimes invoke the TFS functions through a
 Remote Procedure Call (RPC) mechanism, as shown in Figure 14-1 below.

TFS Server Configurations                                                                                           11
TFS Configuration and Extension API Guide

 Fig. 14-1. Standard Client/Server Configuration

 In the client/server configuration, any number of runtimes can be connected to the TFS process. If an application
 program is multi-threaded, each thread can establish a connection with the server. For each runtime connection,
 the server will spawn a thread to service the RPCs from that thread for the duration of the thread's activity.
 In this client/server configuration, the application process may be on the same computer as the server process,
 or a different one.
 The TFS proxies that are linked into the application process "act like" the actual TFS API functions. The proxies
 will marshal the input parameters and send them in a packet to the server. The server will determine, from the
 contents of the packet, which function is being called, and will call the corresponding stub function. The stub func-
 tion will interpret the marshaled parameter values and then call the real TFS function with those parameter
 values. Upon return from the function, there may be output parameters and a return code. These are all mar-
 shaled into a packet that is returned to the client, where the values are demarshaled and returned to the appli-
 cation. Again, the application, calling a TFS API function, does not know that the actual function was not local.

 Standalone Configuration
 The standalone configuration uses a version of the TFS API that assumes that only one thread within one proc-
 ess will be calling the functions. With this assumption, a number of simplifications can be made:

TFS Server Configurations                                                                                          12
TFS Configuration and Extension API Guide

     l   The program has exclusive access to all databases, even when opening them in shared mode. So all lock-
         ing functions are accepted, but have no effect.
     l   No changes are ever made by other runtimes, so the cache need not be flushed, and the TFS need not
         keep a store of the modified pages.
     l   Read-only-transactions don't require any cache versioning because no other runtimes are making
         changes.

      NOTE: The implementation of transactions in the standalone configuration leaves a database vul-
      nerable to corruption if there is an interruption of the program's processing during the commit of a trans-
      action, or if the computer or operating system crash before the database files are closed. It is not
      recommended that this configuration be used in unstable environments.

 All of the above differences amount to an extremely high-performing configuration. If this configuration satisfies
 an application's requirements, it is preferable to the others.
 The figure below illustrates the standalone configuration.

 Fig. 14-4. Standalone Configuration

TFS Server Configurations                                                                                           13
TFS Configuration and Extension API Guide

 TFS Configuration Settings
 Aspects of the runtime environment of RDM can be configured using a configuration file, or programmatically
 through the API. The TFS environment can be configured using configuration files, through environment var-
 iables, or on utility command-lines. Variables set in the environment take precedence over variables set in the
 configuration file variables set programmatically, or on a command-line will take the highest precedence.
 The TFS configuration affects the behavior of the TFS (tfserver) and the other utilities that have direct access to
 the files in the document root. There is a global configuration file, tfs.ini, kept in the document root of the
 TFS, that applies to all databases stored within the document root. Each database may also have its own con-
 figuration file for database specific settings related to mirroring and replication.
 These parameters affect the databases regardless of the property name settings of the runtimes, since
 TFS configuration properties must apply to all users of the databases.
 The tfs.ini and dbname.ini files may contain the same property name/value pairs, and the database-spe-
 cific file has priority. The priority of the property name values are as follows:
    l   If the dbname/dbname.ini exists, and if the property name is specified, use this value,
    l   Else if tfs.ini exists, and if the property name is specified, use this value,
    l   Else use the default value (shown below).
 The following example shows the potential placement of configuration files:

    c:\RDM\databases
        tfs.ini
        phlist\
             phlist.ini
             ... (other database files)
        tfs.corporate.com-21553\
             phlist\
             ... (other database files)
        mkt\
             ... (other database files)
        tims\
             tims.ini
             ... (other database files)

 This example shows two databases that have their own configuration files, phlist and tims. Two databases
 have none, tfs.corporate.com-21553/phlist and mkt. Since there is a tfs.ini file in the document
 root, any property names that do not exist in the database directories will be obtained from this file.

 Environment Variables
 Variable Name          Description
 RDM_DOCROOT            In the absence of a command-line specification of the document root (-d option), tell
                        tfserver, dbmirror, dbrep or dbrepsql to use this directory instead of the current
                        directory for the document root.

TFS Configuration Settings                                                                                         14
TFS Configuration and Extension API Guide

 Variable Name           Description
 RDM_TFSERVER            In the absence of a command-line specification of the host name and port number the run-
                         time can locate the TFS to connect to using the contents of this variable:

                         RDM_TFSERVER=localhost:21553

 Configuration File (tfs.ini, dbname.ini)
 The RDM TFS configuration file follows the standard formatting for INI text files (See Wikipedia). An
 INI file can hold a number of sections, each section consist of a section name enclosed in bracket
 followed by a number of properties. Each property consists of a name followed by an equal sign
 and a value. A semicolon marks the beginning of a comment that continues to the end of the line.
 Section names and variable names will be case insensitive.
 Unrecognized section names and properties as well as properties appearing in the wrong sections will be
 ignored by the system. Only two sections, [configuration] and [LogCleanup], are used by the TFS.
 The function d_dbsetini has been provided to set the database-specific values when a database is open in exclu-
 sive mode. To programmatically set the tfs.ini values, you must use the psp_iniSet function.
 Since the configuration files are simple text files, it is possible to create and edit them with common text editors.
 Update access to the document root is required.
 The currently supported properties and associated section names are located in the table below.

    [configuration]

         ; The following settings are only read from tfs.ini and apply to all databases

        ; Maximum number of users connected to the TFS, between 16 and 1000, defaults
    to 256
        maxusers=256

         ; Maximum number of files per database, between 16 and 65535, defaults to 4096
         maxfiles=4096

         ; The following settings can appear in either tfs.ini or dbname.ini

         ; Set to 1 (on) to enable sorting based on system locale, default is 0 (off).
         use_string_locale=0

        ; Set to 0 (off) to disable file syncing to disk.                      This will improve per-
    formance
        ; but at a risk of data loss. Default is 1 (on).
        synclogfiles=1

         ; Specify the type of compression to be used for log files.
         ; Compression types:
         ;    none : No compression

TFS Configuration Settings                                                                                           15
TFS Configuration and Extension API Guide

         ;    zero : Compress zeros (default)
         logfile_compression=zero

         ; Enable replication. 0=off (default) and 1=on. Enabling this property
         ; will cause the runtime to generate replication log files for use
         ; in a replicated environment.
         replication=0

         ; Enable mirroring. 0=off (default) and 1=on. Enabling this property
         ; will cause the TFS to generate mirroring log files for use
         ; in a mirrored environment.
         mirroring=0

         ; The number of milliseconds delay between checkpoint operations for a
         ; database (default is 1000 ms for disk based databases and 100 ms for
         ; in memory databases).
         checkpoint_frequency=1000

        ; Set to 0 to disable single slave mode, when you have more than one
        ; slave connected to a single master. Single slave mode optimizes
        ; log file cleanup when there is only one slave. This option is enabled by
    default
        ; and will automatically be disabled if a second slave is detected.
        SingleSlaveMode=1

    [LogCleanup]
         ; LogCleanup settings are used to specify when log files can be removed to
         ; prevent the disk from filling up during the mirroring or replication activ-
    ity.

        ; LogFileAge specifies when a log file can be removed base on file date and
    time.
        ; If the log file's age is greater than the specified value, it will be
    removed.
        ; Values can be specified as s (seconds), m (minutes), h (hours), d (days).
        ; Care should be used when specifying a value in seconds as a value too small
        ; may cause log files to be cleaned up before they have a chance to mirror to
    the slave.
        ; (examples: 30s | 10m | 2h | 1d).
        ; If no unit character is specified, minutes will be assumed.
        ; Default is 10 minutes.
        LogFileAge=10m

        ; LogFileSpace specifies the amount of disk space that can be used by log
    files.
        ; Space is calculated per database. If the total size of all log files is
        ; greater than this value, they will be removed (oldest first). Values can be
        ; specified as k (kilobytes), m (megabytes), g (gigabytes).
        ; (ex: 500k | 100m | 1g). If no unit character is specified, kilobytes will
        ; be assumed.

TFS Configuration Settings                                                               16
TFS Configuration and Extension API Guide

         LogFileSpace=0

TFS Configuration Settings                  17
TFS Configuration and Extension API Guide

 TFS Server Extension API
 Introduction
 By default, the RDM TFS program called tfserver will serve static HTML files to HTTP clients. However, addi-
 tional customized functions may be added to your own custom-built HTTP server.
 In this section, we will create a simple hybrid direct-link configuration (as defined in the Direct-Link Configuration
 section) that has customized extensions available for use by HTTP clients. In this example, we will generate
 HTML so that the HTTP client can be any web browser. The starting point will be the Market example. It is
 already coded to detect whether it is supposed to run as a TFS or not (using the passed in parameter).

 Step 1: Set Up Hybrid Environment
 The hybrid environment requires the program that is designated as the server to initialize using the TFST library.
 Only one program that wants to use databases hosted by this TFS instance may run this way.
 On Windows, it could look like this:

    marketExample –tfs TFST –d c:\RDM\databases

 This instance of marketExample will be acting as a market application and as a TFS to other market appli-
 cations. All other market application instances should be run using the TFSR library. On Windows it could look
 like this:

    marketExample -tfs TFSR

 At this point you can verify that the market application is working correctly. Please examine the function star-
 tAsTFS in the example code GettingStarted/examples/market/marketExample_main.c.

 Step 2: Add XAPI Functions
 The Market example has no extension functions. In this step, we will add two functions. The first one will be used
 to produce an HTML file that lists all investors with their current totals. In that HTML file will be links to the second
 extension function which lists the details of a particular investor. The first function we will call investorList,
 and the second investorDetail. The first function requires no parameters. The second function requires an
 investor ID.
 The d_tfsxapiparams function is called to set the XAPI parameters.
 Here is code that correctly sets up two functions to be called when named by an HTTP client:

TFS Server Extension API                                                                                               18
TFS Configuration and Extension API Guide

    /* marketExample_main.c */
    #include "rdmhttp.h"

    int32_t investorList(RHS_HANDLE, PSP_OUTPUTBUFF, const char*, const char*, const
    char*);
    int32_t investorDetail(RHS_HANDLE, PSP_OUTPUTBUFF, const char*, const char*, const
    char*);

    static const TFS_XAPI_FCNMAP mktfcnmap[] = {
        { "/investorList",   (TFS_XAPI_FCN *)investorList   },
        { "/investorDetail", (TFS_XAPI_FCN *)investorDetail }
    };
    #define NUM_MKTFCNS RLEN(mktfcnmap)
    ...

    /* In the startAsTFS function */
        TFS_XAPI_PARAMS xapi_params;
    ...
        xapi_params.xapifcnmap = mktfcnmap;
        xapi_params.fcnmapsize = NUM_MKTFCNS;
        xapi_params.subdocroot = "/mkt";

        rc = d_tfsinitEx(full_docroot, &tparams, hTFS, cmd_status->tfs_type);

        if(rc == S_OKAY)
        {
             /* We check using d_tfsversion so that we can determine what
               * TFS_TYPE_DEFAULT resolves to
               */
             rc = d_tfsversion(&major, &minor, &tfs_type);
             {
                  if (rc == S_OKAY)
                  {
                      /* Direct linked TFS library, start server */
                      if (tfs_type == TFS_TYPE_TFS)
                      {
                          rc = d_tfsxapiparams(hTFS, &xapi_params);
                          if(rc == S_OKAY)
                          {
                              rc = d_tfsrun(*hTFS, TRUE, &tfs_done);
                              if(rc != S_OKAY)
                              {
                                  printf("Error starting TFS threads - %s (%d): %s\n",
                                     d_errorname(rc), rc, d_errorstr(rc));
                              }
                          }
                      }
                  }
             }
        }
        else
        {

TFS Server Extension API                                                                 19
TFS Configuration and Extension API Guide

              printf("Error initialzing TFS - %s (%d): %s\n", d_errorname(rc), rc, d_
      errorstr(rc));
          }
      ...

 When the TFS (your own application which starts up the TFS threads) is built and run, you can access these func-
 tions from a web browser. The address for these functions is formed by identifying the domain under which the
 TFS is running, the correct port, then the function name as identified in the first element if the TFS_XAPI_
 FCNMAP structure. For these two functions, the full address may look like the following:

      http://localhost:21553/investorList

 or

      http://localhost:21553/investorDetail?invID=3&

 Note that the first function, investorList, is shown with no parameters. This is because the function itself will
 not be affected by parameters, but simply produces the current list of investors.
 The second function, investorDetail, has one parameter, invID. In the example, the value is 3.
 The definition of these functions follows their intended use. The investorList function is an entry point that
 produces a list of investors together with links to the investor details. Thus, the investorDetail function is
 intended to be used from within hyperlinks in an HTML page, with the parameter value matching the name of an
 investor.
 The functions have the following prototype:

      int32_t fcnName(RHS_HANDLE hRHS, PSP_OUTPUTBUFFoutbuff, const char *args,
          const char *raw_args, const char *content);

 While the function is active, it can perform any function available to it, especially access to an RDM database.
 The PSP_OUTPUTBUFF parameter must be used as input to the http_printf function, as this is the reply
 that will be sent back to the HTTP client. The first character (args) points to a string representing the param-
 eters that were sent in the URL. . The string in args is URL decoded. The second string (raw_args) points to a
 string containing the raw (URL encoded) argument list. The third string (context), if not NULL, points to the
 content portion of the HTTP message, which will be present with a POST method.
 Below is an example of how the upper level of these two functions may be coded.

      static void EXTERNAL_FCN HttpErr(int32_t, const char*, void*, DB_TASK*);
      ...

      /* investor list XAPI function */
      int32_t investorList(
          RHS_HANDLE      hRHS,

TFS Server Extension API                                                                                       20
TFS Configuration and Extension API Guide

        PSP_OUTPUTBUFF outbuf,
        const char     *args,
        const char     *raw_args,
        const char     *content)
    {
        int32_t status;
        DB_TASK *task;

        /* prepare to use the database */
        d_opentask(&task);
        d_set_dberr_ex(HttpErr, (void *)outbuf, task);

        if ((status=d_open("mkt", "s", task)) != S_OKAY) {
            http_printf(outbuf, "Error %d opening mkt database", status);
            return S_OKAY;
        }

        /* bare-bones HTML to surround the output */
        http_printf(outbuf, "\n");
        http_printf(outbuf, "List of Investors\n");
        investor_list_html(outbuf, task);
        http_printf(outbuf, "\n");

        d_close(task);
        d_closetask(task);

        return S_OKAY;
    }

    /* investor detail XAPI function */
    int32_t investorDetail(
        RHS_HANDLE       hRHS,
        PSP_OUTPUTBUFF outbuf,
        const char      *args,
        const char      *raw_args,
        const char      *content)
    {
        int32_t status;
        DB_TASK *task;

        /* prepare to use the database */
        d_opentask(&task);
        d_set_dberr_ex(HttpErr, (void *)outbuf, task);

        if ((status=d_open("mkt", "s", task)) != S_OKAY) {
            http_printf(outbuf, "Error %d opening mkt database", status);

             return S_OKAY;
        }

        /* bare-bones HTML to surround the output */
        http_printf(outbuf, "\n");

TFS Server Extension API                                                    21
TFS Configuration and Extension API Guide

          http_printf(outbuf, "Investor Detail\n");
          investor_detail_html(hRHS, outbuf, args, task);
          http_printf(outbuf, "\n");

          d_close(task);
          d_closetask(task);

          return S_OKAY;
    }

 Any XAPI function may not print to stdout or stderr, because it may appear in the program that is running
 the TFS. All output is to be generated for the client through the http_printf function.
 The d_set_dberr_ex function is used to prevent the standard dberr function from printing to stderr. It is
 optional whether HTML is generated by the HttpErr function, but an example of it is shown below.

    static void EXTERNAL_FCN HttpErr(
        int32_t err,
        const char *errmsg,
        void *ob,
        DB_TASK *task)
    {
        /* avoid printing to stdout */
        http_printf((PSP_OUTPUTBUFF)ob, "Database error %d: %s\n", err,
    errmsg);
    }

 Step 3: Querying the Database
 In this example, the functions doing the database work are named investor_list_html and investor_
 detail_html. They will be fetching information from the database and producing HTML output.
 First, we will have investor_list_html produce a table row for each investor record that is read. The fol-
 lowing code produces a row containing the investor ID, investor name, and the liquid funds. The investor ID field
 will have a hyperlink added that references the second function, so that the correct reference is generated when
 the ID is clicked.

    static int32_t investor_list_html(PSP_OUTPUTBUFF, DB_TASK*);

    ...

    static int32_t investor_list_html(
        PSP_OUTPUTBUFF outbuf,
        DB_TASK        *task)
    {
        int32_t         rc;
        struct investor investorRec;

TFS Server Extension API                                                                                        22
TFS Configuration and Extension API Guide

          /* Lock the FUND and INVESTOR records for read access see mktfcns.c */
          if ((rc = d_lock(investor_fund_r_sz, investor_fund_r, task, 0)) != S_OKAY)
              return -1;

          http_printf(outbuf, "");
          for (rc = d_keyfrst(INVESTOR_INVID, task, 0); rc == S_OKAY;
                  rc = d_keynext(INVESTOR_INVID, task, 0))
          {
              if ((rc = d_recread(&investorRec, task, 0)) != S_OKAY)
                  return -1;

            /* the ID hyperlink, and the ID */
            http_printf(outbuf, "%d",
                    investorRec.invID, investorRec.invID);

              /* the investor name and liquid funds */
              http_printf(outbuf, "%s$%.2f\n", investorRec.name,
                      investorRec.money_mkt);
              http_printf(outbuf, "\n");
          }
          http_printf(outbuf, "");

          if (rc == S_NOTFOUND)
              rc = S_OKAY;

          d_freeall(task);

          return rc;
    }

 The second function, investor_detail_html, must parse the argument string to obtain the investor ID, look
 up the investor from the ID, then generate HTML output containing that investor's data. In the code snippet
 below, the function obtains the ID using http_getURLArgValue from RDM's HTTP support library functions.
 First, args is parsed into the urlargs structure. Then this structure is searched for the value matching the
 invID key. Since this key/value pair is generated by our own investorList function, it should be valid.

    int32_t investor_detail_html(RHS_HANDLE, PSP_OUTPUTBUFF, const char*, DB_TASK*);

    ...

    int32_t investor_detail_html(
        RHS_HANDLE     hRHS,
        PSP_OUTPUTBUFF outbuf,
        const char    *args,
        DB_TASK       *task)
    {
        int32_t         rc;

TFS Server Extension API                                                                                  23
TFS Configuration and Extension API Guide

        const URLARGS *urlargs;
        int16_t         invIDVal;
        const char     *invIDptr;
        double          total_funds;
        double          assetsValue;
        struct investor investorRec;
        struct fund     fundRec;
        struct asset    assetRec;
        struct trans    transRec;
        struct stock    stockRec;
        double          current_value;

        /* locate this investor based on ID */
        if ((rc = http_initURLArgs(hRHS, args, &urlargs)) != S_OKAY)
            return rc;
        invIDptr = http_getURLArgValue("invID", urlargs);
        if (invIDptr == NULL) {
            http_printf(outbuf, "Invalid parameters\n");
            http_freeURLArgs(urlargs);
            return rc;
        }
        invIDVal = atoi(invIDptr);
        http_freeURLArgs(urlargs);

        /* look up investor and generate HTML */
        rc = d_lock(investor_fund_asset_trans_stock_r_sz,
                investor_fund_asset_trans_stock_r, task, 0);
        if (rc != S_OKAY)
            return -1;

        if((rc = d_keyfind(INVESTOR_INVID, &invIDVal, task, 0)) != S_OKAY)
        {
            d_freeall(task);
            if(rc != S_NOTFOUND)
            {
                 http_printf(outbuf, "Error %d looking up investor with ID of
    %d", rc, invIDVal);
            }
            else
            {
                 http_printf(outbuf, "Unable to find investor with ID of %d",
    invIDVal);
            }
            return -1;
        }

        if ((rc = d_setor(FUNDING, task, 0)) != S_OKAY)
            return -1;

        if ((rc = d_setor(INV_TRANS, task, 0)) != S_OKAY)
            return -1;

TFS Server Extension API                                                               24
TFS Configuration and Extension API Guide

        if ((rc = d_recread(&investorRec, task, 0)) != S_OKAY)
            return -1;

        http_printf(outbuf, "\nInvestor (%d) %s\n", investorRec.invID, invest-
    orRec.name);

        total_funds = 0;
        http_printf(outbuf, "");
        http_printf(outbuf, "Funding");
        for (rc = d_findfm(FUNDING, task, 0); rc == S_OKAY;
                rc = d_findnm(FUNDING, task, 0))
        {
            if ((rc = d_recread(&fundRec, task, 0)) != S_OKAY)
                return -1;

             http_printf(outbuf, "$%-7.2f", fundRec.amount);
             total_funds += fundRec.amount;
        }
        http_printf(outbuf, "");

        if (rc != S_EOS) /*lint !e850 */
            return -1;

        assetsValue = 0;

        /* prerequisite: current owner of INV_TRANS */
        for (rc = d_findfm(INV_TRANS, task, 0); rc == S_OKAY;
                rc = d_findnm(INV_TRANS, task, 0))
        {
            if ((rc = d_setor(HISTORY, task, 0)) != S_OKAY)
                return -1;

             if ((rc = d_recread(&assetRec, task, 0)) != S_OKAY)
                 return -1;

             if ((rc = d_findco(STOCK_TRANS, task, 0)) != S_OKAY)
                 return -1;

             if ((rc = d_recread(&stockRec, task, 0)) != S_OKAY)
                 return -1;

            http_printf(outbuf, "");
            http_printf(outbuf, "ASSET: (%d) %s, currently $%-7.2f\n",
                stockRec.stkID, stockRec.company, stockRec.share_price);
            http_printf(outbuf, "Shares owned"UINT64_
    SPEC"",
                assetRec.shares_owned);

             for (rc = d_findfm(HISTORY, task, 0); rc == S_OKAY;
                     rc = d_findnm(HISTORY, task, 0)) /*lint !e445 */
             {
                 if ((rc = d_recread(&transRec, task, 0)) != S_OKAY)

TFS Server Extension API                                                          25
TFS Configuration and Extension API Guide

                      return -1;

                http_printf(outbuf, "%s"INT64_SPEC" @ $%-
    7.2f",
                        transRec.shares > 0 ? "purchased": "sold",
                        transRec.shares > 0 ? transRec.shares : -transRec.shares,
                        transRec.value);
            }

             if (rc != S_EOS) /*lint !e850 */
                 return -9;

            current_value = (double) assetRec.shares_owned * stockRec.share_price;
            http_printf(outbuf, "Current value$%-7.2f", cur-
    rent_value);
            assetsValue += current_value;
            http_printf(outbuf, "");
        }

        http_printf(outbuf, "");
        http_printf(outbuf, "Liquid funds$%-7.2f",
            investorRec.money_mkt);
        http_printf(outbuf, "Net worth:$%-8.2f",
            investorRec.money_mkt + assetsValue);
        http_printf(outbuf, "Profit/Loss:$%-7.2f",
            investorRec.money_mkt+assetsValue-total_funds);
        http_printf(outbuf, "");
        d_freeall(task);
        return S_OKAY;
    }

TFS Server Extension API                                                              26
TFS Configuration and Extension API Guide

 Enhanced HTTP Monitor
 The Enhanced HTTP Monitor is a browser-based monitor/administrator that displays status of servers, data-
 bases, users, and Replication. It allows the starting and stopping of mirroring or replication if the appropriate
 servers are running.
 The user interface communicates to a TFS through HTTP requests. To protect security of the servers and data,
 we require that a user logs in before being able to perform any function in the Enhanced HTTP Monitor. Once
 logged in, all HTTP requests and responses are encrypted. See separate document on RDM TFS Admin Secu-
 rity. Due to the session-less nature of HTTP, encrypting every request ensures that the server only responds to
 valid (authorized) requests.
 The development build will create a default user account for user 'admin' with a password of 'secret'. The pass-
 word is encrypted and stored as a URL encoded string in the tfs.ini file in the [Accounts] section. Cus-
 tomers should create their own user accounts. This can be accomplished by running the tfsuser utility. The
 tfsuser utility will prompt for a password. The default user name is 'admin'. A different name can be specified on
 the command line. Run 'tfsuser –h' to see a complete list of command line options.
 It is important to know that all TFS servers that are to be access through a browser must have the same user-
 name and password. You must either run tfsuser with a -th option for each TFS running, or you must copy the
 [Accounts] entry from one tfs.ini file to all other server tfs.ini files.
 The same password is required on all servers because the main TFS, the one the user logs into, is used as a
 proxy server to all other servers. It is impractical to force the user to login separately to every server to which they
 might connect. Using the main TFS as a proxy server is required due to browser security restrictions. We cannot
 connect from a browser via AJAX to any other server. We can only connect to the server and port that sent the
 page currently active in the browser.
 HTTP request flow

Enhanced HTTP Monitor                                                                                                 27
TFS Configuration and Extension API Guide

 Once logged in, every page contains one or more HTTP requests to a server. Internally, the username is used on
 every HTTP request and the password is used to encrypt the request sent to the server. The password is also
 used to decrypt the content of responses from the server. The password is never sent to the server. The content
 of a message is encrypted using the password. The server, which has a copy of the password, decrypts the mes-
 sage using the password. If the server is unable to decrypt the message, that means the user is not logged in,
 and an error is returned. If the server is able to perform the requested action, the response is encrypted using the
 password already stored on the server. The response is decrypted in the browser and the results are displayed.
 Users can logout from any page.
 The user's session can timeout. The default timeout value is 10 minutes. This value can be configured manually
 by adding a Timeout=xxx (in seconds) property to the [Accounts] section of the tfs.ini file. On a time-
 out or login error, the main login page is displayed.

Enhanced HTTP Monitor                                                                                             28
TFS Configuration and Extension API Guide

 After login, the main TFS page is displayed. This page shows all databases on this server, all users logged in to
 this server, any databases that are mirrored or replicated from or to this server, and the Replication settings for
 this server. Each box is expandable by clicking on the arrow to the left of each box's heading.
 The Databases box shows all databases that exist on this TFS. Clicking a database name will open a new tab
 with information about that database. The tab shows the name of the database and the server and port where
 the database exists (i.e.: test@EDH-Win7:21553). If the tab is already opened, it will be activated.

Enhanced HTTP Monitor                                                                                              29
TFS Configuration and Extension API Guide

 The database info page shows information about file locks, users with this database open, files used by this data-
 base and their allocation sizes.
 Also from the database page, the user can configure the Replication settings specific to this database. This
 allows the user to override the default settings from the TFS. For example, the user can enable mirroring log file
 generation for a specific database without the overhead of creating log files for all other databases controlled by
 this TFS. The user will make their changes and click the Apply button. To change this database to use the global
 TFS settings for Replication, click the Default button.
 If you want to open a connection to another TFS, click the '+' tab.

Enhanced HTTP Monitor                                                                                            30
TFS Configuration and Extension API Guide

 This creates a New tab that will ask for the host name and port of the requested TFS. When the Connect button
 is clicked, a connection will be made to this server. This tab will be renamed to the server's name and, if the
 server is available, the main TFS information page will be displayed for this server. If the connection already
 exists, that tab will be activated.

Enhanced HTTP Monitor                                                                                         31
TFS Configuration and Extension API Guide

 In the Users box on a TFS tab, all users that are connected to this server will display. You can disconnect a user
 by clicking on the X next to a user's login name. You cannot disconnect a user from a database tab, as a user
 may have more than one database opened.
 Care should be taken when disconnecting a user this way. You have no way to know if the user is in the middle of
 a transaction.
 If there are too many tabs to be displayed on the screen at one time, a drop down box is available from the down
 arrow on the right side of the tab row. From here you can go directly to any tab. Tabs can be closed by clicking on
 the red x next to their name. You cannot close the first tab to the main TFS. Tab names that are too long will be
 truncated and end with '...'.

Enhanced HTTP Monitor                                                                                            32
TFS Configuration and Extension API Guide

 There are three refresh settings, Off, 2 and 5. The default is to refresh the page every 2 seconds. The selected
 refresh rate will be underlined. Only the visible tab refreshes. Since each TFS controls its own session, each tab
 could timeout if they are in the background for too long. Therefore, tabs that are in the background are kept alive
 during each refresh interval internally without any action by the user. If the refresh setting is Off, the session will
 timeout if the session becomes idle. With refresh enabled, sessions with tabs will not timeout.
 If you want to start mirroring or replication, open a new tab connection to a slave TFS. In the Replication box,
 there are three sections; databases that this server is sending as a master, databases that this server is receiving
 as a slave, and a way to start a new database mirror or replication.

Enhanced HTTP Monitor                                                                                                 33
TFS Configuration and Extension API Guide

 The title of the Replication box will change depending on the type of server associated with the TFS. The Rep-
 lication server type will be 'Mirroring Server', 'Replication Server' or 'SQL Replication Server'. The options
 (checkboxes) below the drop downs will change depending on the type of server. A mirroring server will have an
 option for 'synchronous' mirroring. A SQL replication server will have options for the type of destination SQL
 server (RDM Server, MySQL, MSSQL, or Oracle). It will also have a field to enter the DSN if necessary. The
 DSN will not be needed if the user set the RDSLOGIN environment variable before starting dbrepsql. All server
 types will have 'override in-memory' to allow a master in-memory database to be an on-disk database on a slave.
 The ability to start mirroring or replication will only appear if there are two or more TFS tabs open. From the slave
 TFS tab, the user will select a master TFS server from the 'Connected Masters' drop down. The 'Databases'

Enhanced HTTP Monitor                                                                                              34
TFS Configuration and Extension API Guide

 drop down will automatically update with the list of databases available from that master. When the 'Start' button
 is clicked, this TFS tab becomes a slave of the selected database from the selected master.
 If the user starts mirroring or replication, but the master is not configured to create log files for the appropriate
 type, an error message will be displayed.

 To stop mirroring or replication, simply click the Stop button from either the master's TFS tab or the slave's TFS
 tab.

Enhanced HTTP Monitor                                                                                                    35
TFS Configuration and Extension API Guide

 HTTP Extension API Functions
 From within XAPI (HTTP extension API), these functions may be used to parse the incoming data and generate
 the outgoing data.
 These functions require the header file "rdmhttp.h" included in source files. To link these functions, the library
 name 'http' must be included (see Library Naming Conventions for library naming conventions).
 The following table lists alphabetically all the HTTP support functions, along with brief descriptions.
 Function            Description
 http_freeURLArgs    Frees structure allocated by http_initURLArgs
 http_getURLArgValue Retrieves a value given a key
 http_initURLArgs    Parses arguments received through HTTP into key/value pairs
 http_printf         Prints content for HTTP response
 http_URLDecode      Decode incoming HTTP URL encoded string

HTTP Extension API Functions                                                                                     36
TFS Configuration and Extension API Guide

 http_freeURLArgs
 Free structure allocated for URL arguments

 Prototype

    void http_freeURLArgs(
        const URLARGS *urlargs);

 Parameters
 urlargs               (input)      Pointer to an allocated structure created by http_initURLArgs.

 Description
 This function is required to clean up memory allocated by the http_initURLArgs function.

 Required Headers

    #include "rdmhttp.h"

 Libraries
 Library Name                    Description
 rdmhttp11                       RDM HTTP Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

 Return Codes
 None.

 See Also
 http_initURLArgs
 http_getURLArgValue
 http_printf
 http_URLDecode

HTTP Extension API Functions                                                                         37
TFS Configuration and Extension API Guide

 http_getURLArgValue
 Retrieve the value associated with a key

 Prototype

    const char *http_getURLArgValue(
        const char    *key,
        const URLARGS *urlargs);

 Parameters
 key                    (input)      A string identifying the key associated with the requested value.
 urlargs                (input)      Pointer to an allocated structure created by http_initURLArgs.

 Description
 This function searches through the key/value pairs represented in urlargs (must have been created by http_ini-
 tURLArgs) for the key. If found, a pointer to the value associated with key is returned. If the key is not found,
 NULL is returned.
 See the http_initURLArgs for more description and an example.

 Required Headers

    #include "rdmhttp.h"

 Libraries
 Library Name                     Description
 rdmhttp11                        RDM HTTP Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

 See Also
 http_initURLArgs
 http_freeURLArgs
 http_printf
 http_URLDecode

HTTP Extension API Functions                                                                                     38
TFS Configuration and Extension API Guide

 http_initURLArgs
 Parse HTTP arguments for access within functions

 Prototype

    void http_initURLArgs(
        RHS_HANDLE      hRHS,
        const char     *args,
        const URLARGS **urlargs);

 Parameters
 hRHS                  (input)      HTTP Stream handle.
 args                  (input)      Character string containing the URL arguments.
 urlargs               (output)     Pointer to an allocated structure created by http_initURLArgs.

 Description
 This function accepts the arguments string that appears after the '?' character on a URL, and parses them into
 key/value pairs that can be searched with the http_getURLArgValue function.
 When running in the XAPI environment (see d_tfsinit), the input to http_initURLArgs is the args parameter
 to the TFS_XAPI_FCN functions.

 Required Headers

    #include "rdmhttp.h"

 Libraries
 Library Name                    Description
 rdmhttp11                       RDM HTTP Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

 Return Codes
 Value           Name                           Description
 0               S_OKAY                         normal return, okay
 -82             S_INVURLARGFMT                 Invalid URL argument format
 -904            S_NOMEMORY                     out of memory

HTTP Extension API Functions                                                                                      39
TFS Configuration and Extension API Guide

 -924              S_INVNULL                invalid NULL parameter

 See Also
 http_freeURLArgs
 http_getURLArgValue
 d_tfsinit
 http_printf
 http_URLDecode

 Example

    int32_t navigate_handler(
        RHS_HANDLE      hRHS,
        PSP_OUTPUTBUFF outbuff,
        const char     *args,
        const char     *raw_args,
        const char     *content
    {
        int32_t          stat;
        const URLARGS   *urlargs;

             /* 'args' is a string containing everything after the '?', for example, if
                the reference is 'http://localhost:21553/navigate.rdm?action=d_recfrst&'
    then
                 args will be 'action=d_recfrst'.
             */
             ...
             if ((stat=http_initURLArgs(hRHS, argc, &urlargs)) != S_OKAY)
                  return stat;

             name = http_getURLArgValue("action", urlargs);

        if (strcmp(name, "d_recfrst") == 0) {
            ...
            /* produce output for browser */
            http_printf(outbuff, "id_code=%s&info_title=%s&stat=%d&", code, title,
    stat);
        }
        else {
            http_printf(outbuff, "stat=%d&", stat);
        }

             http_freeURLArgs(urlargs);

             return stat;
    }

HTTP Extension API Functions                                                               40
TFS Configuration and Extension API Guide

 http_printf
 Print reply to HTTP request

 Prototype

    int32_t http_printf(
        PSP_OUTPUTBUFF outbuf,
        const char    *fmt,
        ...);

 Parameters
 outbuff                  (input)       Output stream that will be returned to the requestor.
 fmt                      (input)       Pointer to printf style format string.

 Description
 This function acts like fprintf, except that the resulting string is put into outbuf, which will be sent to the
 HTTP client making the request that is currently being serviced.
 This function may only be used from within an XAPI function. See d_tfsinit for more description and example.
 The outbuf is passed to the TFS_XAPI_FCN.

 Required Headers

    #include "rdmhttp.h"

 Libraries
 Library Name                       Description
 rdmhttp11                          RDM HTTP Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

 Return Codes
 Value             Name                             Description
 0                 S_OKAY                           normal return, okay
 -49               S_INVPTR                         invalid pointer
 -203              S_TX_NETWRITE                    failure to write data to network

HTTP Extension API Functions                                                                                       41
TFS Configuration and Extension API Guide

 See Also
 http_freeURLArgs
 http_getURLArgValue
 http_initURLArgs
 http_URLDecode

HTTP Extension API Functions                42
TFS Configuration and Extension API Guide

 http_URLDecode
 Decode a URL encoded string

 Prototype

    void http_URLDecode(
        char       *args,
        uunt32_t   *result_len);

 Parameters
 args                  (in/output) URL encoded argument string.
 result_len            (output)    Length of decoded data.

 Description
 This function accepts a null-terminated string and decodes any URL encoding in the string. It is important to
 make sure that the string is encoded before using this function. If result_len is NULL, no length is returned.
 The decoding is done in-place. This is possible because decoded strings are always smaller than the encoded
 strings. Ex: %40 = '@'

 Required Headers

    #include "rdmhttp.h"

 Libraries
 Library Name                    Description
 rdmhttp11                       RDM HTTP Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

 See Also
 http_freeURLArgs
 http_getURLArgValue
 http_initURLArgs
 http_printf

HTTP Extension API Functions                                                                                   43
TFS Configuration and Extension API Guide

 Summary Listing of TFS API Functions
 The following table lists alphabetically the functions used to initialize the TFS in various configurations.

 Function                             Description
 d_tfsinit                            Provide TFS with parameters to start up as a server
 d_tfsinitEx
 d_tfsrun                             Begin running connections from other runtimes
 d_tfsstop                            Stop running connections from other runtimes
 d_tfsterm                            Terminate the use of the TFS, releasing resources
 d_tfsversion                         Obtain version and type of TFS library
 d_tfsxapiparams                      Provide TFS with parameters to start up as a HTTP server
 d_tfsIt-                             Query names of all users currently connected to a TFS
 erateConnectedUsers

Summary Listing of TFS API Functions                                                                            44
TFS Configuration and Extension API Guide

 d_tfsdisconnect
 Disconnect a user connection from a TFS.

 Prototype

    int32_t d_tfsdisconnect(
        TFS_HANDLE                       hTFS,
        const char                      *hostname,
        uint16_t                         port,
        const char                      *username)

    int32_t d_tfsdisconnectW(
        TFS_HANDLE                       hTFS,
        const wchar_t                   *hostname,
        uint16_t                         port,
        const wchar_t                   *username)

 Parameters
 hTFS                  (input)      Handle returned from a successful d_tfsinit call.
 hostname              (input)      Hostname of the TFS to query for user names.
 port                  (input)      Port number of the TFS to query for user names.
 username              (input)      Username to disconnect

 Description
 This function disconnects a specific user from a TFS.

 Required Headers

    #include "rdm.h"

 Libraries
 Library Name                    Description
 rdmrdm11                        RDM Runtime Library

 See Library Naming Conventions section for full library name and a list of library dependencies.

Summary Listing of TFS API Functions                                                                45
TFS Configuration and Extension API Guide

 Return Codes
 Value          Name                        Description
 0              S_OKAY                      normal return, okay
 -200           S_TX_ERROR                  generic tx_ error
 -202           S_TX_NETREAD                failure to read data from network
 -203           S_TX_NETWRITE               failure to write data to network
 -214           S_TX_CONNECT                failed to connect to TFS
 -215           S_TX_HOSTNAME               TFS host name not found
 -904           S_NOMEMORY                  out of memory

 See Also
 d_tfsIterateConnectedUsers

 Example

    int32_t EXTERNAL_FCN UserName_handler(
        const char     *username)
    {
        TFS_HANDLE    hTFS = NULL;

          /* This function is called once for each connected user to a TFS.
             Return S_OKAY to continue receiving user names.
             Return any other error to stop receiving user names.
             Ignore internal RDM connections.
          */

          if (strncmp(username, "RDM.", 5) == 0)
              return S_OKAY;    /* ignore internal connections */

          printf("Username: %s\n", username);

          if (strcmp(username, "my_user") == 0)
          {
              if (d_tfsdisconnect(hTFS, "localhost", 21553, username) == S_OKAY)
              {
                   printf("Disconnected user %s\n", username);
                   return S_EOS; /* Return error to stop getting new user names */
              }
              else
                   printf("Error disconnecting user\n");
          }

          return S_OKAY;
    }
    ...

Summary Listing of TFS API Functions                                                 46
TFS Configuration and Extension API Guide

    main()
    {
        TFS_HANDLE       hTFS = NULL;
        int32_t          rc;
        const char      *docroot = "\data";
        ...

        rc = d_tfsIterateConnectedUsers(hTFS, "localhost", 21553, UserName_handler);
        if (rc == S_OKAY)
        {
            ...
        }
        ...
    }

Summary Listing of TFS API Functions                                                   47
TFS Configuration and Extension API Guide

 d_tfsinit, d_tfsinitEx
 Provide TFS with parameters to start up as a server

 Prototype

    int32_t d_tfsinit(
        const char       *docroot,
        const TFS_PARAMS *tparams,
        TFS_HANDLE       *hTFS)

    int32_t d_tfsinitW(
        const wchar_t     *docroot,
        const TFS_PARAMSW *tparams,
        TFS_HANDLE        *hTFS)

    int32_t d_tfsinitEx(
        const char       *docroot,
        const TFS_PARAMS *tparams,
        TFS_HANDLE       *hTFS,
        TFS_TYPE          tfs_type)

    int32_t d_tfsinitExW(
        const wchar_t     *docroot,
        const TFS_PARAMSW *tparams,
        TFS_HANDLE        *hTFS,
        TFS_TYPE           tfs_type)

 Parameters
 docroot               (input)      The directory under which all databases controlled by this TFS are stored.
                                    If "" or NULL is used, the environment variable RDM_DOCROOT is used, other-
                                    wise the current working directory is used.
 tparams               (input)      Parameters required for TFS operation. If NULL, defaults are used.
 hTFS                  (output)     Handle used for running, stopping or terminating this TFS.
 tfs_type              (input)      Set type of TFS configuration.

 Description
 Call d_tfsinit to set up the TFS with non-default parameters. The d_tfsinit function should be called
 before any tasks are created. Any successful call to d_tfsinit requires a corresponding call to d_tfsterm.

Summary Listing of TFS API Functions                                                                              48
TFS Configuration and Extension API Guide

 d_tfsinit and d_tfsterm are implemented using reference counting so they can be nested. Only the initial
 call to d_tfsinit and the final call to d_tfsterm will actually perform any useful work.
 This function does not have any effect when the RPC configuration is used. The current implementation always
 returns the handle as NULL. The d_opentask function call will automatically initialize the TFS with the default
 values if your application does not explicitly call this function prior to a call to d_opentask.
 TFS Configuration Types
 TFS_TYPE_DEFAULT                    Factory default TFS type is TFS_TYPE_TFS.
 TFS_TYPE_TFS                        See Direct-Link Configuration
 TFS_TYPE_RPC                        See Standard Client/Server Configuration
 TFS_TYPE_STANDALONE                 See Standalone Configuration

     Note: The TFS Configuration Type can only be changed after the d_tfsterm has been called.

 TFS_PARAMS(W) prototypes

    typedef struct {
                uint16_t                     port;
                uint32_t                     rd_only;
                uint32_t                     no_disk;
                uint16_t                     verbose;
                const char                  *logfile;
                const char                  *stdout_file;
        } TFS_PARAMS;

    typedef struct _tfs_paramsw {
                uint16_t                     port;
                uint32_t                     rd_only;
                uint32_t                     no_disk;
                uint16_t                     verbose;
                const wchar_t               *logfile;
                const wchar_t               *stdout_file;
        } TFS_PARAMSW;

 TFS_PARAMS struct members
 Element             Declaration            Description
 port                uint16_t               Server listen port
 rd_only             uint32_t               Read-only device, TRUE or FALSE.
 no_disk             uint32_t               Diskless mode, TRUE or FALSE.
 verbose             uint16_t               Verbose mode, TRUE or FALSE.
 logfile             const char *           File name to open for logging. Can be NULL.
 stdout_file         const char *           The name of a file to wirte informational messages instead of displaying
                                            them to stdout. If the value is NULL or "stdout" the messages will be sent
                                            to stdout. If the value is an empty string ("") no messages will be displayed.

Summary Listing of TFS API Functions                                                                                   49
You can also read