This code example illustrates one of the simplified-level service APIs that are used in developing TI-RPC services.
In this code example, notice how each procedure is registered independently from the rest. At the simplified level, a service might have multiple procedures, but each one must be registered separately. If the service is unregistered, all of the procedures are unregistered at once. There is no method that is provided to unregister an individual procedure while leaving the remaining procedures intact.
This level is a good choice for services with a small number of procedures. It is also useful for prototyping a much larger service by using a limited number of the final procedures. As with all the service levels, the final call in the service should be to svc_run(), which goes into Select Wait (waiting for a connection from a client).
#include <stdio.h> #include <netconfig.h> #include <rpc/rpc.h> #include <errno.h> #include "myapp.h" int main(int argc, char *argv[]) { bool_t rslt; /* return value for rpc_call() */ /* unregister any existing copy of this service */ /* (void)svc_unreg(program, version) */ svc_unreg(PROGNUM, VERSNUM); /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_UID, myapp_get_uid, xdr_wrapstring, xdr_u_int, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_UID"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_UID_STRING, myapp_get_uid_string, xdr_wrapstring, xdr_wrapstring, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_UID_STRING"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_SIZE, myapp_get_size, xdr_wrapstring, xdr_int, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_SIZE"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_MTIME, myapp_get_mtime, xdr_wrapstring, xdr_long, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_MTIME"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_MTIME_STRING, myapp_get_mtime_string, xdr_wrapstring, xdr_wrapstring, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_MTIME_STRING"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_CODEPAGE, myapp_get_codepage, xdr_wrapstring, xdr_u_short, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_CODEPAGE"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_OBJTYPE, myapp_get_objtype, xdr_wrapstring, xdr_wrapstring, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_OBJTYPE"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, GET_FILETYPE, myapp_get_filetype, xdr_wrapstring, xdr_wrapstring, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "GET_FILETYPE"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); return 1; } /* (bool_t)rpc_reg(prognum, versnum, procnum, procname, */ /* xdr_in, xdr_out, nettype) */ rslt = rpc_reg(PROGNUM, VERSNUM, END_SERVER, myapp_end_server, (xdrproc_t)xdr_void, (xdrproc_t)xdr_void, NETTYPE); /* check for errors calling rpc_reg() */ if (rslt == FALSE) { /* print error messages and exit */ fprintf(stderr, "Error calling rpc_reg for %s\n", "END_SERVER"); fprintf(stderr, "PROG: %lu\tVERS: %lu\tNET: %s\n", PROGNUM, VERSNUM, NETTYPE); /* clean up before exiting */ svc_unreg(PROGNUM, VERSNUM); 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() */