ibm-information-center/dist/eclipse/plugins/i5OS.ic.rzahp_5.4.0.1/rzahptopservice.htm

455 lines
14 KiB
HTML
Raw Normal View History

2024-04-02 14:02:31 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="security" content="public" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
<meta name="DC.Type" content="reference" />
<meta name="DC.Title" content="Example: TI-RPC top-level service API" />
<meta name="abstract" content="This code example illustrates a top-level service API used in developing TI-RPC services." />
<meta name="description" content="This code example illustrates a top-level service API used in developing TI-RPC services." />
<meta name="DC.Relation" scheme="URI" content="rzahpservicecode.htm" />
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="rzahptopservice" />
<meta name="DC.Language" content="en-us" />
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
<link rel="stylesheet" type="text/css" href="./ic.css" />
<title>Example: TI-RPC top-level service API</title>
</head>
<body id="rzahptopservice"><a name="rzahptopservice"><!-- --></a>
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
<h1 class="topictitle1">Example: TI-RPC top-level service API</h1>
<div><p>This code example illustrates a top-level service API used in developing
TI-RPC services.</p>
<div class="section"><p>The development of a service is more complicated at the top level,
because it requires the developer to write a dispatch routine. At this level,
when a service request comes in, a dispatch routine is called. The dispatch
routine must collect the arguments and call the correct local procedure, catch
all errors and results, and return that information to the client. After dispatch
function is written, it can be readily copied and used in other services with
only slight modifications.</p>
<p>The top, intermediate, and
expert layers can use the same dispatch function without modification. In
the following example, the dispatch function is bundled with the other local
functions in this file. Both files need to be compiled and linked together
before the service runs. The advantage of the top level over the other layers
is the ability to specify the NETTYPE as a string, instead of using the network
selection APIs. After calling the top-level API, the service
is created, bound to the dispatch function, and registered with the rpcbind
service.</p>
<div class="note"><span class="notetitle">Note:</span> By using the code examples, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</div>
<pre>#include &lt;stdio.h&gt;
#include &lt;netconfig.h&gt;
#include &lt;rpc/rpc.h&gt;
#include &lt;errno.h&gt;
#include "myapp.h"
int main(int argc, char *argv[]) {
int num_svc; /* return value for the svc_create() API */
/* unregister any existing copy of this service */
/* (void)svc_unreg(program, version) */
svc_unreg(PROGNUM, VERSNUM);
/* (int)svc_create(dispatch, prognum, versnum, nettype); */
num_svc = svc_create(myapp_dispatch, PROGNUM, VERSNUM, NETTYPE);
/* check for errors calling svc_create() */
if (num_svc == 0) {
/* print error messages and exit */
fprintf(stderr, "Error calling %s.\n", "svc_create");
fprintf(stderr, "PROG: %lu\nVERS: %lu\tNET: %s\n",
PROGNUM, VERSNUM, NETTYPE);
fprintf(stderr, "errno: %d\n", errno);
return 1;
}
/* this should loop indefinitely waiting for client connections */
svc_run();
/* if we get here, svc_run() returned */
fprintf(stderr, "svc_run() returned. ERROR has occurred.\n");
fprintf(stderr, "errno: %d\n", errno);
/* clean up by unregistering. then, exit */
svc_unreg(PROGNUM, VERSNUM);
return 1;
} /* end of main() */</pre>
<pre>/* This is an example of the dispatch function */</pre>
<pre>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;pwd.h&gt;
#include &lt;rpc/rpc.h&gt;
#include &lt;time.h&gt;
#include "myapp.h"
char * myapp_get_uid(char *in) {
u_int retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (u_int)-1;
}
else {
retval = (u_int)(sbuf.st_uid);
}
return (char *)&amp;retval;
}
char *myapp_get_uid_string(char *in) {
char *retval; /* return value for this procedure() */
struct passwd *pbuf; /* return value for getpwuid() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (char *)NULL;
}
else {
pbuf = (struct passwd *)getpwuid((uid_t)(sbuf.st_uid));
if (pbuf == NULL) {
retval = (char *)NULL;
}
else {
retval = (char *)(pbuf-&gt;pw_name);
}
}
return (char *)&amp;retval;
}
char * myapp_get_size(char *in) {
int retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (int)-1;
}
else {
retval = (int)(sbuf.st_size);
}
return (char *)&amp;retval;
}
char * myapp_get_mtime(char *in) {
long retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (long)-1;
}
else {
retval = (long)(sbuf.st_mtime);
}
return (char *)&amp;retval;
}
char *myapp_get_mtime_string(char *in) {
char *retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (char *)NULL;
}
else {
retval = (char *)ctime((time_t *)&amp;(sbuf.st_mtime));
}
return (char *)&amp;retval;
}
char * myapp_get_codepage(char *in) {
u_short retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (u_short)-1;
}
else {
retval = (u_short)(sbuf.st_codepage);
}
return (char *)&amp;retval;
}
char *myapp_get_objtype(char *in) {
char *retval; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
retval = (char *)NULL;
}
else {
retval = (char *)(sbuf.st_objtype);
}
return (char *)&amp;retval;
}
char *myapp_get_filetype(char *in) {
char *result = NULL; /* return value for this procedure() */
struct stat sbuf; /* data storage area for stat() */
int stat_ret; /* return value for stat() */
char *file = *(char **)in; /* input value for stat() */
/* (int)stat(filename, struct stat *) */
stat_ret = stat(file, &amp;sbuf);
if (stat_ret == -1) {
return (char *)NULL;
}
if (S_ISDIR(sbuf.st_mode)) {
result = "Directory";
}
if (S_ISREG(sbuf.st_mode)) {
result = "Regulare File";
}
if (S_ISLNK(sbuf.st_mode)) {
result = "Symbolic Link";
}
if (S_ISSOCK(sbuf.st_mode)) {
result = "Socket";
}
if (S_ISNATIVE(sbuf.st_mode)) {
result = "AS/400 Native Object";
}
if (S_ISFIFO(sbuf.st_mode)) {
result = "FIFO";
}
if (S_ISCHR(sbuf.st_mode)) {
result = "Character Special";
}
if (S_ISBLK(sbuf.st_mode)) {
result = "Block Special";
}
return (char *)&amp;result;
}
char * myapp_end_server(char *empty) {
/* char *empty is not used */
/* function always returns NULL */
svc_unreg(PROGNUM, VERSNUM);
return (char *)NULL;
}
void myapp_dispatch(struct svc_req *request, SVCXPRT *svc) {
union {
/* all of the procedures take a string */
/* if there were other procedures, it */
/* might look like this: */
/* int set_codepage_arg */
char * filename_arg;
} argument;
char *result; /* pointer to returned data from proc */
xdrproc_t xdr_argument; /* decodes data from client call */
xdrproc_t xdr_result; /* encodes data to return to client */
char *(*proc)(char *); /* pointer to local procedure to call */
switch (request-&gt;rq_proc) {
case NULLPROC:
/* a special case. always return void */
(void)svc_sendreply((SVCXPRT *)svc,
(xdrproc_t)xdr_void,
(char *)NULL);
return;
case GET_UID:
/* takes a string argument (filename) */
/* returns an u_int (uid of file ownder) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_u_int;
proc = (char *(*)(char *))myapp_get_uid;
break;
case GET_UID_STRING:
/* takes a string argument (filename) */
/* returns a string (owner's name in string format) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_wrapstring;
proc = (char *(*)(char *))myapp_get_uid_string;
break;
case GET_SIZE:
/* takes a string argument (filename) */
/* returns an int (size of file in bytes) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_int;
proc = (char *(*)(char *))myapp_get_size;
break;
case GET_MTIME:
/* takes a string argument (filename) */
/* returns a long (time last modified) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_long;
proc = (char *(*)(char *))myapp_get_mtime;
break;
case GET_MTIME_STRING:
/* takes a string argument (filename) */
/* returns a string (time last modified, string format) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_wrapstring;
proc = (char *(*)(char *))myapp_get_mtime_string;
break;
case GET_CODEPAGE:
/* takes a string argument (filename) */
/* returns an u_short (codepage of file) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_u_short;
proc = (char *(*)(char *))myapp_get_codepage;
break;
case GET_OBJTYPE:
/* takes a string argument (filename) */
/* returns a string (object type) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_wrapstring;
proc = (char *(*)(char *))myapp_get_objtype;
break;
case GET_FILETYPE:
/* takes a string argument (filename) */
/* returns a string (file type) */
xdr_argument = xdr_wrapstring;
xdr_result = xdr_wrapstring;
proc = (char *(*)(char *))myapp_get_filetype;
break;
case END_SERVER:
/* takes no arguments */
/* returns no data */
/* unregisters service with local rpcbind daemon */
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_void;
proc = (char *(*)(char *))myapp_end_server;
break;
default:
/* fall through case. return error to client */
svcerr_noproc(svc);
return;
} /* end switch(request-&gt;rq_proc) */
/* clear the argument */
memset((char *)&amp;argument, (int)0, sizeof(argument));
/* decode argument from client using xdr_argument() */
if (svc_getargs(svc, xdr_argument, (char *)&amp;argument) == FALSE) {
/* if svc_getargs() fails, return RPC_CANTDECODEARGS to client */
svcerr_decode(svc);
return;
}
/* call local procedure, passing in pointer to argument */
result = (char *)(*proc)((char *)&amp;argument);
/* check first that result isn't NULL */
/* try to send results back to client. check for failure */
if ((result != NULL) &amp;&amp; (svc_sendreply(svc, xdr_result, result) == FALSE))
{
/* send error message back to client */
svcerr_systemerr(svc);
}
/* free the decoded argument's space */
if (svc_freeargs(svc, xdr_argument, (char *)&amp;argument) == FALSE) {
/* if unable to free, print error and exit */
(void)fprintf(stderr, "unable to free arguments\n");
exit(1);
}
} /* end of myapp_dispatch() */</pre>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="rzahpservicecode.htm" title="Transport independent remote procedure call (TI-RPC) programming provides an effective method for developing distributed client-server based applications on i5/OS.">Examples: Develop service applications based on TI-RPC code</a></div>
</div>
</div>
</body>
</html>