範例: TI-RPC 最上層用戶端 API
此程式碼範例說明用於開發 TI-RPC 應用程式的最上層用戶端 API。
在最上層,您必須先建立用戶端控點,才能使用或修改它。 最上層 API 易於使用,它們容許比簡化層次更多的操作和錯誤處理。
附註: 使用程式碼範例,即表示您同意 程式碼授權及免責聲明資訊的條款。
#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() */
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 */
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);
/* clnt_create(host, prognum, versnum, nettype); */
clnt = clnt_create(hostname, PROGNUM, VERSNUM, NETTYPE);
/* check to make sure clnt_create() didn't fail */
if (clnt == (CLIENT *)NULL) {
/* if we failed, print out all appropriate error messages and exit */
fprintf(stderr, "Error calling clnt_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 */
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);
}