359 lines
13 KiB
HTML
359 lines
13 KiB
HTML
<?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 expert-level client API" />
|
|
<meta name="abstract" content="This code example illustrates an expert-level client API that is used in developing TI-RPC applications." />
|
|
<meta name="description" content="This code example illustrates an expert-level client API that is used in developing TI-RPC applications." />
|
|
<meta name="DC.Relation" scheme="URI" content="rzahpclientcode.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="rzahpexpertclient" />
|
|
<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 expert-level client API</title>
|
|
</head>
|
|
<body id="rzahpexpertclient"><a name="rzahpexpertclient"><!-- --></a>
|
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
|
<h1 class="topictitle1">Example: TI-RPC expert-level client API</h1>
|
|
<div><p>This code example illustrates an expert-level client API that is
|
|
used in developing TI-RPC applications.</p>
|
|
<div class="section"><p>The expert level for the development of a client API is the most
|
|
complicated. It also offers the most customization. This is the only level
|
|
where the buffer size can be tuned for the client API. This level requires
|
|
the programmer to set up the universal address for the client to connect to,
|
|
either by using the name-to-address translation APIs or one of the other expert-level
|
|
APIs. Either way, this level requires more work, but it allows the programmer
|
|
to tailor the client application to the environment it runs in.</p>
|
|
<div class="note"><span class="notetitle">Note:</span> By
|
|
using the code example, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</div>
|
|
<pre>#include <stdio.h>
|
|
#include <netconfig.h>
|
|
#include <netdir.h>
|
|
#include <errno.h>
|
|
#include "myapp.h"
|
|
|
|
#define EXIT 100
|
|
|
|
int main(void) {
|
|
|
|
enum clnt_stat rslt; /* return value of clnt_call() */
|
|
char hostname[256]; /* buffer for remote service's hostname */
|
|
unsigned long procnum; /* procedure to call */
|
|
char filename[512]; /* buffer for filename */
|
|
xdrproc_t xdr_argument; /* xdr procedure to encode arguments */
|
|
xdrproc_t xdr_result; /* xdr procedure to decode results */
|
|
CLIENT *clnt; /* pointer to client handle */
|
|
struct timeval tout; /* timeout for clnt_call() */
|
|
struct netconfig *nconf;/* transport information */
|
|
struct netbuf svcaddr; /* universal address of remote service */
|
|
bool_t rpcb_rslt; /* return value for rpcb_getaddr() */
|
|
char *arg = filename; /* pointer to filename buffer */
|
|
|
|
union {
|
|
u_int myapp_get_uid_result;
|
|
char * myapp_get_uid_string_result;
|
|
int myapp_get_size_result;
|
|
long myapp_get_mtime_result;
|
|
char * myapp_get_mtime_string_result;
|
|
u_short myapp_get_codepage_result;
|
|
char * myapp_get_objtype_result;
|
|
char * myapp_get_filetype_result;
|
|
} result; /* a union of all the possible results */
|
|
|
|
/* initialize the struct netbuf space */
|
|
svcaddr.maxlen = 16;
|
|
svcaddr.buf = (char *)malloc(svcaddr.maxlen);
|
|
|
|
if (svcaddr.buf == (char *)NULL) {
|
|
/* if malloc() failed, print error messages and exit */
|
|
fprintf(stderr, "Error calling malloc() for struct netbuf\n");
|
|
fprintf(stderr, "errno: %d\n", errno);
|
|
return 1;
|
|
}
|
|
|
|
tout.tv_sec = 30; /* set default timeout to 30.00 seconds */
|
|
tout.tv_usec = 0;
|
|
|
|
/* get the hostname from the user */
|
|
printf("Enter the hostname where the remote service is running: \n");
|
|
scanf("%s", (char *)&hostname);
|
|
|
|
myapp_print_menu(); /* print out the menu choices */
|
|
|
|
/* get the procedure number to call from the user */
|
|
printf("\nEnter a procedure number to call: \n");
|
|
scanf("%lu", &procnum);
|
|
|
|
/* get the filename from the user */
|
|
printf("\nEnter a filename to stat: \n");
|
|
scanf("%s", (char *)&filename);
|
|
|
|
/* getnetconfigent(nettype) */
|
|
nconf = getnetconfigent(NETTYPE);
|
|
|
|
/* check to make sure getnetconfigent() didn't fail */
|
|
if (nconf == NULL) {
|
|
/* if getnetconfigent() failed, print error messages and exit */
|
|
fprintf(stderr, "Error calling getnetconfigent(%s)\n", NETTYPE);
|
|
fprintf(stderr, "errno: %d\n", errno);
|
|
return 1;
|
|
}
|
|
|
|
/* rpcb_getaddr(prognum, versnum, nconf, output netbuf, hostname) */
|
|
/* this sets the universal address svcaddr */
|
|
rpcb_rslt = rpcb_getaddr(PROGNUM, VERSNUM, nconf, &svcaddr, hostname);
|
|
|
|
/* check to make sure rpcb_getaddr() didn't fail */
|
|
if (rpcb_rslt == FALSE) {
|
|
/* if rpcb_getaddr() failed, print error messages and exit */
|
|
fprintf(stderr, "Error calling rpcb_getaddr()\n");
|
|
fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n",
|
|
PROGNUM, VERSNUM, NETTYPE);
|
|
fprintf(stderr, "clnt_stat: %d\n", rpc_createerr.cf_stat);
|
|
fprintf(stderr, "errno: %d\n", errno);
|
|
fprintf(stderr, "re_errno: %d\n", rpc_createerr.cf_error.re_errno);
|
|
return 1;
|
|
}
|
|
|
|
/* clnt_tli_create(filedes, netconfig, netbuf, */
|
|
/* prognum, versnum, sendsz, recvsz); */
|
|
clnt = clnt_tli_create(RPC_ANYFD, nconf, &svcaddr,
|
|
PROGNUM, VERSNUM, 0, 0);
|
|
|
|
/* check to make sure clnt_tli_create() didn't fail */
|
|
if (clnt == (CLIENT *)NULL) {
|
|
/* if we failed, print out all appropriate error messages and exit */
|
|
fprintf(stderr, "Error calling clnt_tli_create()\n");
|
|
fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n",
|
|
PROGNUM, VERSNUM, NETTYPE);
|
|
fprintf(stderr, "clnt_stat: %d\n", rpc_createerr.cf_stat);
|
|
fprintf(stderr, "errno: %d\n", errno);
|
|
fprintf(stderr, "re_errno: %d\n", rpc_createerr.cf_error.re_errno);
|
|
return 1;
|
|
}
|
|
|
|
/* switch on the input */
|
|
switch (procnum) {
|
|
|
|
case NULLPROC:
|
|
/* set the encode procedure */
|
|
xdr_argument = (xdrproc_t)xdr_void;
|
|
/* set the decode procedure */
|
|
xdr_result = (xdrproc_t)xdr_void;
|
|
break;
|
|
|
|
case GET_UID:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_u_int;
|
|
break;
|
|
|
|
case GET_UID_STRING:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_wrapstring;
|
|
break;
|
|
|
|
case GET_SIZE:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_int;
|
|
break;
|
|
|
|
case GET_MTIME:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_long;
|
|
break;
|
|
|
|
case GET_MTIME_STRING:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_wrapstring;
|
|
break;
|
|
|
|
case GET_CODEPAGE:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_u_short;
|
|
break;
|
|
|
|
case GET_OBJTYPE:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_wrapstring;
|
|
break;
|
|
|
|
case GET_FILETYPE:
|
|
/* set the encode procedure */
|
|
xdr_argument = xdr_wrapstring;
|
|
/* set the decode procedure */
|
|
xdr_result = xdr_wrapstring;
|
|
break;
|
|
|
|
case END_SERVER:
|
|
/* set the encode procedure */
|
|
xdr_argument = (xdrproc_t)xdr_void;
|
|
/* set the decode procedure */
|
|
xdr_result = (xdrproc_t)xdr_void;
|
|
break;
|
|
|
|
case EXIT:
|
|
/* we're done. clean up and exit */
|
|
clnt_destroy(clnt);
|
|
return 1;
|
|
break;
|
|
|
|
default:
|
|
/* invalid procedure number entered. defaulting to NULLPROC */
|
|
printf("Invalid choice. Issuing NULLRPOC instead.\n");
|
|
procnum = NULLPROC;
|
|
/* set the encode procedure */
|
|
xdr_argument = (xdrproc_t)xdr_void;
|
|
/* set the decode procedure */
|
|
xdr_result = (xdrproc_t)xdr_void;
|
|
break;
|
|
|
|
} /* end of switch(procnum) */
|
|
|
|
/* clnt_call(client, procnum, xdr_inproc, in, xdr_outproc, out, timeout) */
|
|
rslt = clnt_call(clnt, procnum, xdr_argument, (char *)&arg,
|
|
xdr_result, (char *)&result, tout);
|
|
|
|
/* check to make sure clnt_call() succeeded */
|
|
if (rslt != RPC_SUCCESS) {
|
|
/* if clnt_call() failed, print errors and exit */
|
|
printf("An error occurred calling %lu procedure\n", procnum);
|
|
printf("clnt_stat: %d\terrno: %d\n", rslt, errno);
|
|
clnt_destroy(clnt);
|
|
return 1;
|
|
}
|
|
|
|
/* clnt_call() succeeded. switch on procedure and print results */
|
|
switch (procnum) {
|
|
|
|
case NULLPROC:
|
|
/* print results and exit */
|
|
printf("NULLRPOC call succeeded\n");
|
|
break;
|
|
|
|
case GET_UID:
|
|
/* print results and exit */
|
|
printf("uid of %s: %u\n",
|
|
filename, result.myapp_get_uid_result);
|
|
break;
|
|
|
|
case GET_UID_STRING:
|
|
/* print results and exit */
|
|
printf("owner of %s: %s\n",
|
|
filename, result.myapp_get_uid_string_result);
|
|
break;
|
|
|
|
case GET_SIZE:
|
|
/* print results and exit */
|
|
printf("size of %s: %d\n",
|
|
filename, result.myapp_get_size_result);
|
|
break;
|
|
|
|
case GET_MTIME:
|
|
/* print results and exit */
|
|
printf("last modified time of %s: %ld\n",
|
|
filename, result.myapp_get_mtime_result);
|
|
break;
|
|
|
|
case GET_MTIME_STRING:
|
|
/* print results and exit */
|
|
printf("last modified time of %s: %s\n",
|
|
filename, result.myapp_get_mtime_string_result);
|
|
break;
|
|
|
|
case GET_CODEPAGE:
|
|
/* print results and exit */
|
|
printf("codepage of %s: %d\n",
|
|
filename, result.myapp_get_codepage_result);
|
|
break;
|
|
|
|
case GET_OBJTYPE:
|
|
/* print results and exit */
|
|
printf("object type of %s: %s\n",
|
|
filename, result.myapp_get_objtype_result);
|
|
break;
|
|
|
|
case GET_FILETYPE:
|
|
/* print results and exit */
|
|
printf("file type of %s: %s\n",
|
|
filename, result.myapp_get_filetype_result);
|
|
break;
|
|
|
|
case END_SERVER:
|
|
/* print results and exit */
|
|
printf("Service has been unregistered.\n");
|
|
printf("You must still kill the job in QBATCH\n");
|
|
break;
|
|
|
|
default:
|
|
/* we should never get the default case. */
|
|
/* the previous switch should catch it. */
|
|
break;
|
|
|
|
} /* end of switch(procnum) */
|
|
|
|
|
|
/* clean up and exit */
|
|
|
|
/* free the netconfig struct */
|
|
freenetconfigent(nconf);
|
|
/* free the universal address buffer */
|
|
free(svcaddr.buf);
|
|
/* destroy the client handle */
|
|
clnt_destroy(clnt);
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
void myapp_print_menu(void) {
|
|
|
|
/* print out the procedure choices */
|
|
printf("%.2ld - GET_UID %.2ld - GET_UID_STRING\n",
|
|
GET_UID, GET_UID_STRING);
|
|
printf("%.2ld - GET_SIZE %.2ld - GET_MTIME\n",
|
|
GET_SIZE, GET_MTIME);
|
|
printf("%.2ld - GET_MTIME_STRING %.2ld - GET_CODEPAGE\n",
|
|
GET_MTIME_STRING, GET_CODEPAGE);
|
|
printf("%.2ld - GET_OBJTYPE %.2ld - GET_FILETYPE\n",
|
|
GET_OBJTYPE, GET_FILETYPE);
|
|
printf("%.2ld - END_SERVER %.2d - EXIT\n",
|
|
END_SERVER, EXIT);
|
|
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="familylinks">
|
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="rzahpclientcode.htm" title="Transport independent remote procedure call (TI-RPC) programming provides an effective method for developing distributed client-server based applications on i5/OS.">Develop client applications based on TI-RPC code examples</a></div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |