BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Programming   |   Topic List   |   Previous   |   Next   |   Contents

   Programming a BEA Tuxedo Application Using C

System-supplied Server and Services

The main() routine provides one system-supplied server, AUTHSVR, and two subroutines, tpsvrinit() and tpsvrdone(). The default versions of all three, which are described in the following sections, can be modified to suit your application.

Notes: If you want to write your own versions of tpsvrinit() and tpsvrdone(), remember that the default versions of these two routines call tx_open() and tx_close(), respectively. If you write a new version of tpsvrinit() that calls tpopen() rather than tx_open(), you should also write a new version of tpsvrdone() that calls tpclose(). In other words, both functions in an open/close pair must belong to the same set.

In addition to the subroutines described in this topic, the system provides two subroutines called tpsvrthrinit(3c) and tpsvrthrdone(3c). For more information, refer to Programming a Multithreaded and Multicontexted Application.

System-supplied Server: AUTHSVR( )

You can use the AUTHSVR(5) server to provide individual client authentication for an application. The tpinit() function calls this server when the level of security for the application is TPAPPAUTH.

The service in AUTHSVR looks in the data field of the TPINIT buffer for a user password (not to be confused with the application password specified in the passwd field of the TPINIT buffer). By default, the system takes the string in data and searches for a matching string in the /etc/passwd file.

When called by a native-site client, tpinit() forwards the data field as it is received. This means that if the application requires the password to be encrypted, the client program must be coded accordingly.

When called by a workstation client, tpinit() encrypts the data before sending it across the network.

System-supplied Services: tpsvrinit( ) Function

When a server is booted, the BEA Tuxedo system main() calls tpsvrinit(3c) during its initialization phase, before handling any service requests.

If an application does not provide a custom version of this function within the server, the system uses the default function provided by main(), which opens the resource manager and logs an entry in the central event log indicating that the server has successfully started. The central user log is an automatically generated file to which processes can write messages by calling the userlog(3c) function. Refer to Managing Errors for more information on the central event log.

You can use the tpsvrinit() function for any initialization processes that might be required by an application, such as the following:

The following sections provide code samples showing how these initialization tasks are performed through calls to tpsvrinit(). Although it is not illustrated in the following examples, message exchanges can also be performed within this routine. However, tpsvrinit() fails if it returns with asynchronous replies pending. In this case, the replies are ignored by the BEA Tuxedo system, and the server exits gracefully.

You can also use the tpsvrinit() function to start and complete transactions, as described in Managing Errors.

Use the following signature to call the tpsvrinit() function.

int
tpsvrinit(int argc, char **argv)

Receiving Command-line Options

When a server is booted, its first task is to read the server options specified in the configuration file up to the point that it receives an EOF indication. To do so, the server calls the getopt(3) UNIX function. The presence of a double dash (--) on the command line causes the getopt() function to return an EOF. The getopt function places the argv index of the next argument to be processed in the external variable optind. The predefined main() then calls tpsvrinit().

The following code example shows how the tpsvrinit() function is used to receive command-line options.

Receiving Command-line Options in tpsvrinit( )


tpsvrinit(argc, argv)
int argc;
char **argv;
{
int c;
extern char *optarg;
extern int optind;
.
.
.
while((c = getopt(argc, argv, "f:x:")) != EOF)
switch(c){
.
.
.
}
.
.
.
}


When main() calls tpsvrinit(), it picks up any arguments that follow the double dash (--) on the command line. In the example above, options f and x each takes an argument, as indicated by the colon. optarg points to the beginning of the option argument. The switch statement logic is omitted.

Opening a Resource Manager

The following example illustrates another common use of tpsvrinit(): opening a resource manager. The BEA Tuxedo system provides functions to open a resource manager, tpopen(3c) and tx_open(3c). It also provides the complementary functions, tpclose(3c) and tx_close(3c). Applications that use these functions to open and close their resource managers are portable in this respect. They work by accessing the resource manager instance-specific information that is available in the configuration file.

Note: If writing a multithreaded server, you must use the tpsvrthrinit() function to open a resource manager, as described in Programming a Multithreaded and Multicontexted Application.

These function calls are optional and can be used in place of the resource manager specific calls that are sometimes part of the Data Manipulation Language (DML) if the resource manager is a database. Note the use of the userlog(3c) function to write to the central event log.

Note: To create an initialization function that both receives command-line options and opens a database, combine the following example with the previous example.

Opening a Resource Manager in tpsvrinit( )


tpsvrinit()
{

/* Open database */

if (tpopen() == -1) {
(void)userlog("tpsvrinit: failed to open database: ");
switch (tperrno) {
case TPESYSTEM:
(void)userlog("System error\n");
break;
case TPEOS:
(void)userlog("Unix error %d\n",Uunixerr);
break;
case TPEPROTO:
(void)userlog("Called in improper context\n");
break;
case TPERMERR:
(void)userlog("RM failure\n");
break;
}
return(-1); /* causes the server to exit */
}
return(0);
}


To guard against errors that may occur during initialization, tpsvrinit() can be coded to allow the server to exit gracefully before starting to process service requests.

System-supplied Services: tpsvrdone( ) Function

The tpsvrdone() function calls tpclose() to close the resource manager, similarly to the way tpsvrinit() calls tpopen() to open it.

Note: If writing a multithreaded server, you must use tpsvrthrdone() command to open a resource manager, as described in Programming a Multithreaded and Multicontexted Application.

Use the following signature to call the tpsvrdone() function.

void
tpsvrdone() /* Server termination routine */

The tpsvrdone() function requires no arguments.

If an application does not define a closing routine for tpsvrdone(), the BEA Tuxedo system calls the default routine supplied by main(). This routine calls tx_close() and userlog() to close the resource manager and write to the central event log, respectively. The message sent to the log indicates that the server is about to exit.

tpsvrdone() is called after the server has finished processing service requests but before it exits. Because the server is still part of the system, further communication and transactions can take place within the routine, as long as certain rules are followed. These rules are covered in Managing Errors.

The following example illustrates how to use the tpsvrdone() function to close a resource manager and exit gracefully.

Closing a Resource Manager with tpsvrdone( )


void
tpsvrdone()
{

/* Close the database */
if(tpclose() == -1)
(void)userlog("tpsvrdone: failed to close database: ");
switch (tperrno) {
case TPESYSTEM:
(void)userlog("BEA TUXEDO error\n");
break;
case TPEOS:
(void)userlog("Unix error %d\n",Uunixerr);
break;
case TPEPROTO:
(void)userlog("Called in improper context\n");
break;
case TPERMERR:
(void)userlog("RM failure\n");
break;
}
return;
}
return;
}