home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / rpc2 / part04 / rpc / doc / rpc.prog.p2 next >
Encoding:
Text File  |  1986-11-30  |  32.3 KB  |  1,634 lines

  1. .LP
  2. In order to do an RPC callback,
  3. you need a program number to make the RPC call on.
  4. Since this will be a dynamically generated program number,
  5. it should be in the transient range, 0x40000000 - 0x5fffffff.
  6. The routine
  7. .LW gettransient()
  8. returns a valid program number in the transient range,
  9. and registers it with the portmapper.
  10. It only talks to the portmapper running on the same machine as the
  11. .LW gettransient()
  12. routine itself.
  13. The call to
  14. .LW pmap_set()
  15. is a test and set operation,
  16. in that it indivisibly tests whether a program number
  17. has already been registered,
  18. and if it has not, then reserves it.
  19. On return, the
  20. .LW sockp
  21. argument will contain a socket that can be used
  22. as the argument to an
  23. .LW svcudp_create()
  24. or
  25. .LW svctcp_create()
  26. call.
  27. .BS
  28. .LS no
  29. #include <stdio.h>
  30. #include <rpc/rpc.h>
  31. #include <sys/socket.h>
  32. .sp.5
  33. gettransient(proto, vers, sockp)
  34.     int proto, vers, *sockp;
  35. {
  36.     static int prognum = 0x40000000;
  37.     int s, len, socktype;
  38.     struct sockaddr_in addr;
  39. .sp.5
  40.     switch(proto) {
  41.         case IPPROTO_UDP:
  42.             socktype = SOCK_DGRAM;
  43.             break;
  44.         case IPPROTO_TCP:
  45.             socktype = SOCK_STREAM;
  46.             break;
  47.         default:
  48.             fprintf(stderr, "unknown protocol type\en");
  49.             return 0;
  50.     }
  51.     if (*sockp == RPC_ANYSOCK) {
  52.         if ((s = socket(AF_INET, socktype, 0)) < 0) {
  53.             perror("socket");
  54.             return (0);
  55.         }
  56.         *sockp = s;
  57.     }
  58.     else
  59.         s = *sockp;
  60.     addr.sin_addr.s_addr = 0;
  61.     addr.sin_family = AF_INET;
  62.     addr.sin_port = 0;
  63.     len = sizeof(addr);
  64.     /*
  65.      * may be already bound, so don't check for error
  66.      */
  67.     bind(s, &addr, len);
  68.     if (getsockname(s, &addr, &len)< 0) {
  69.         perror("getsockname");
  70.         return (0);
  71.     }
  72.     while (!pmap_set(prognum++, vers, proto, addr.sin_port))
  73.         continue;
  74.     return (prognum-1);
  75. }
  76. .Lf
  77. .BE
  78. The following pair of programs illustrate how to use the
  79. .LW gettransient()
  80. routine.
  81. The client makes an RPC call to the server,
  82. passing it a transient program number.
  83. Then the client waits around to receive a callback
  84. from the server at that program number.
  85. The server registers the program
  86. .LW EXAMPLEPROG ,
  87. so that it can receive the RPC call
  88. informing it of the callback program number.
  89. Then at some random time (on receiving an
  90. .LW ALRM
  91. signal in this example), it sends a callback RPC call,
  92. using the program number it received earlier.
  93. .BS
  94. .LS no
  95. /*
  96.  * client
  97.  */
  98. #include <stdio.h>
  99. #include <rpc/rpc.h>
  100. .sp.5
  101. int callback();
  102. char hostname[256];
  103. .sp.5
  104. main(argc, argv)
  105.     char **argv;
  106. {
  107.     int x, ans, s;
  108.     SVCXPRT *xprt;
  109. .sp.5
  110.     gethostname(hostname, sizeof(hostname));
  111.     s = RPC_ANYSOCK;
  112.     x = gettransient(IPPROTO_UDP, 1, &s);
  113.     fprintf(stderr, "client gets prognum %d\en", x);
  114.     if ((xprt = svcudp_create(s)) == NULL) {
  115.       fprintf(stderr, "rpc_server: svcudp_create\en");
  116.         exit(1);
  117.     }
  118.     /* protocol is 0 - gettransient() does registering
  119.      */
  120.     (void)svc_register(xprt, x, 1, callback, 0);
  121.     ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS,
  122.         EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0);
  123.     if (ans != RPC_SUCCESS) {
  124.         fprintf(stderr, "call: ");
  125.         clnt_perrno(ans);
  126.         fprintf(stderr, "\en");
  127.     }
  128.     svc_run();
  129.     fprintf(stderr, "Error: svc_run shouldn't return\en");
  130. }
  131. .sp.5
  132. callback(rqstp, transp)
  133.     register struct svc_req *rqstp;
  134.     register SVCXPRT *transp;
  135. {
  136.     switch (rqstp->rq_proc) {
  137.         case 0:
  138.             if (!svc_sendreply(transp, xdr_void, 0)) {
  139.                 fprintf(stderr, "err: rusersd\en");
  140.                 exit(1);
  141.             }
  142.             exit(0);
  143.         case 1:
  144.             if (!svc_getargs(transp, xdr_void, 0)) {
  145.                 svcerr_decode(transp);
  146.                 exit(1);
  147.             }
  148.             fprintf(stderr, "client got callback\en");
  149.             if (!svc_sendreply(transp, xdr_void, 0)) {
  150.                 fprintf(stderr, "err: rusersd");
  151.                 exit(1);
  152.             }
  153.     }
  154. }
  155. .sp.5
  156. /*
  157.  * server
  158.  */
  159. #include <stdio.h>
  160. #include <rpc/rpc.h>
  161. #include <sys/signal.h>
  162. .sp.5
  163. char *getnewprog();
  164. char hostname[256];
  165. int docallback();
  166. int pnum;        /* program number for callback routine */
  167. .sp.5
  168. main(argc, argv)
  169.     char **argv;
  170. {
  171.     gethostname(hostname, sizeof(hostname));
  172.     registerrpc(EXAMPLEPROG, EXAMPLEVERS,
  173.       EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void);
  174.     fprintf(stderr, "server going into svc_run\en");
  175.     signal(SIGALRM, docallback);
  176.     alarm(10);
  177.     svc_run();
  178.     fprintf(stderr, "Error: svc_run shouldn't return\en");
  179. }
  180. .sp.5
  181. char *
  182. getnewprog(pnump)
  183.     char *pnump;
  184. {
  185.     pnum = *(int *)pnump;
  186.     return NULL;
  187. }
  188. .sp.5
  189. docallback()
  190. {
  191.     int ans;
  192. .sp.5
  193.     ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0,
  194.         xdr_void, 0);
  195.     if (ans != 0) {
  196.         fprintf(stderr, "server: ");
  197.         clnt_perrno(ans);
  198.         fprintf(stderr, "\en");
  199.     }
  200. }
  201. .Lf
  202. .BE
  203. .SH
  204. Appendix A: Synopsis of RPC Routines
  205. .SH
  206. auth_destroy()
  207. .LP
  208. .BS
  209. .LS
  210. void
  211. auth_destroy(auth)
  212.     AUTH *auth;
  213. .Lf
  214. .BE
  215. A macro that destroys the authentication information associated with
  216. .LW auth .
  217. Destruction usually involves deallocation
  218. of private data structures.  The use of
  219. .LW auth
  220. is undefined after calling
  221. .LW auth_destroy() .
  222. .SH
  223. authnone_create()
  224. .LP
  225. .BS
  226. .LS
  227. AUTH *
  228. authnone_create()
  229. .Lf
  230. .BE
  231. Creates and returns an RPC authentication handle that passes no
  232. usable authentication information with each remote procedure call.
  233. .SH
  234. authunix_create()
  235. .LP
  236. .BS
  237. .LS
  238. AUTH *
  239. authunix_create(host, uid, gid, len, aup_gids)
  240.     char *host;
  241.     int uid, gid, len, *aup_gids;
  242. .Lf
  243. .BE
  244. Creates and returns an RPC authentication handle that contains
  245. .UX
  246. authentication information.
  247. The parameter
  248. .LW host
  249. is the name of the machine on which the information was created;
  250. .LW uid
  251. is the user's user ID;
  252. .LW gid
  253. is the user's current group ID;
  254. .LW len
  255. and
  256. .LW aup_gids
  257. refer to a counted array of groups to which the user belongs.
  258. It is easy to impersonate a user.
  259. .SH
  260. authunix_create\%_default()
  261. .LP
  262. .BS
  263. .LS
  264. AUTH *
  265. authunix_create_default()
  266. .Lf
  267. .BE
  268. Calls
  269. .LW authunix_create()
  270. with the appropriate parameters.
  271. .SH
  272. callrpc()
  273. .LP
  274. .BS
  275. .LS
  276. callrpc(host,prognum,versnum,procnum,inproc,in,outproc,out)
  277.     char *host;
  278.     u_long prognum, versnum, procnum;
  279.     char *in, *out;
  280.     xdrproc_t inproc, outproc;
  281. .Lf
  282. .BE
  283. Calls the remote procedure associated with
  284. .LW prognum ,
  285. .LW versnum ,
  286. and
  287. .LW procnum
  288. on the machine,
  289. .LW host .
  290. The parameter
  291. .LW in
  292. is the address of the procedure's argument(s), and
  293. .LW out
  294. is the address of where to place the result(s);
  295. .LW inproc
  296. is used to encode the procedure's parameters, and
  297. .LW outproc
  298. is used to decode the procedure's results.
  299. This routine returns zero if it succeeds, or the value of
  300. .LW "enum clnt_stat"
  301. cast to an integer if it fails.
  302. The routine
  303. .LW clnt_perrno()
  304. is handy for translating failure statuses into messages.
  305. Warning: calling remote procedures with this routine
  306. uses UDP/IP as a transport; see
  307. .LW clntudp_create()
  308. for restrictions.
  309. .SH
  310. clnt_broadcast()
  311. .LP
  312. .BS
  313. .LS
  314. enum clnt_stat
  315. clnt_broadcast(prognum, versnum, procnum,
  316.   inproc, in, outproc, out, eachresult)
  317.     u_long prognum, versnum, procnum;
  318.     char *in, *out;
  319.     xdrproc_t inproc, outproc;
  320.     resultproc_t eachresult;
  321. .Lf
  322. .BE
  323. Like
  324. .LW callrpc() ,
  325. except the call message is broadcast to all locally connected broadcast nets.
  326. Each time it receives a response, this routine calls
  327. .LW eachresult() ,
  328. whose form is
  329. .BS
  330. .LS
  331.     eachresult(out, addr)
  332.         char *out;
  333.         struct sockaddr_in *addr;
  334. .Lf
  335. .BE
  336. where
  337. .LW out
  338. is the same as
  339. .LW out
  340. passed to
  341. .LW clnt_broadcast() ,
  342. except that the remote procedure's output is decoded there;
  343. .LW addr
  344. points to the address of the machine that sent the results.  If
  345. .LW eachresult()
  346. returns zero,
  347. .LW clnt_broadcast()
  348. waits for more replies;
  349. otherwise it returns with appropriate status.
  350. .SH
  351. clnt_call()
  352. .LP
  353. .BS
  354. .LS
  355. enum clnt_stat
  356. clnt_call(clnt, procnum, inproc, in, outproc, out, tout)
  357.     CLIENT *clnt; long procnum;
  358.     xdrproc_t inproc, outproc;
  359.     char *in, *out;
  360.     struct timeval tout;
  361. .Lf
  362. .BE
  363. A macro that calls the remote procedure
  364. .LW procnum
  365. associated with the client handle,
  366. .LW clnt ,
  367. which is obtained with an RPC client creation routine such as
  368. .LW clntudp_create() .
  369. The parameter
  370. .LW in
  371. is the address of the procedure's argument(s), and
  372. .LW out
  373. is the address of where to place the result(s);
  374. .LW inproc
  375. is used to encode the procedure's parameters, and
  376. .LW outproc
  377. is used to decode the procedure's results;
  378. .LW tout
  379. is the time allowed for results to come back.
  380. .SH
  381. clnt_destroy()
  382. .LP
  383. .BS
  384. .LS
  385. clnt_destroy(clnt)
  386.     CLIENT *clnt;
  387. .Lf
  388. .BE
  389. A macro that destroys the client's RPC handle.
  390. Destruction usually involves deallocation
  391. of private data structures, including
  392. .LW clnt
  393. itself.  Use of
  394. .LW clnt
  395. is undefined after calling
  396. .LW clnt_destroy() .
  397. It is the user's responsibility to close sockets associated with
  398. .LW clnt .
  399. .SH
  400. clnt_freeres()
  401. .LP
  402. .BS
  403. .LS
  404. clnt_freeres(clnt, outproc, out)
  405.     CLIENT *clnt;
  406.     xdrproc_t outproc;
  407.     char *out;
  408. .Lf
  409. .BE
  410. A macro that frees any data allocated by the RPC/XDR system
  411. when it decoded the results of an RPC call.
  412. The parameter
  413. .LW out
  414. is the address of the results, and
  415. .LW outproc
  416. is the XDR routine describing the results in simple primitives.
  417. This routine returns one if the results were successfully freed,
  418. and zero otherwise.
  419. .SH
  420. clnt_geterr()
  421. .LP
  422. .BS
  423. .LS
  424. void
  425. clnt_geterr(clnt, errp)
  426.     CLIENT *clnt;
  427.     struct rpc_err *errp;
  428. .Lf
  429. .BE
  430. A macro that copies the error structure out of the client handle
  431. to the structure at address
  432. .LW errp .
  433. .SH
  434. clnt_pcreateerror()
  435. .LP
  436. .BS
  437. .LS
  438. void
  439. clnt_pcreateerror(s)
  440.     char *s;
  441. .Lf
  442. .BE
  443. Prints a message to standard error indicating
  444. why a client RPC handle could not be created.
  445. The message is prepended with string
  446. .LW s
  447. and a colon.
  448. Used after a
  449. .LW clntraw_create() ,
  450. .LW clnttcp_create() ,
  451. or
  452. .LW clntudp_create()
  453. call.
  454. .SH
  455. clnt_perrno()
  456. .LP
  457. .BS
  458. .LS
  459. void
  460. clnt_perrno(stat)
  461.     enum clnt_stat stat;
  462. .Lf
  463. .BE
  464. Prints a message to standard error corresponding
  465. to the condition indicated by
  466. .LW stat .
  467. Used after
  468. .LW callrpc() .
  469. .SH
  470. clnt_perror()
  471. .LP
  472. .BS
  473. .LS
  474. clnt_perror(clnt, s)
  475.     CLIENT *clnt;
  476.     char *s;
  477. .Lf
  478. .BE
  479. Prints a message to standard error indicating why an RPC call failed;
  480. .LW clnt
  481. is the handle used to do the call.
  482. The message is prepended with string
  483. .LW s
  484. and a colon.
  485. Used after
  486. .LW clnt_call() .
  487. .SH
  488. clntraw_create()
  489. .LP
  490. .BS
  491. .LS
  492. CLIENT *
  493. clntraw_create(prognum, versnum)
  494.     u_long prognum, versnum;
  495. .Lf
  496. .BE
  497. This routine creates a toy RPC client for the remote program
  498. .LW prognum ,
  499. version
  500. .LW versnum .
  501. The transport used to pass messages to the service
  502. is actually a buffer within the process's address space,
  503. so the corresponding RPC server should live in the same address space; see
  504. .LW svcraw_create() .
  505. This allows simulation of RPC and acquisition of RPC overheads,
  506. such as round trip times, without any kernel interference.
  507. This routine returns
  508. .LW NULL
  509. if it fails.
  510. .SH
  511. clnttcp_create()
  512. .LP
  513. .BS
  514. .LS
  515. CLIENT *
  516. clnttcp_create(addr,prognum,versnum,sockp,sendsz,recvsz)
  517.     struct sockaddr_in *addr;
  518.     u_long prognum, versnum;
  519.     int *sockp;
  520.     u_int sendsz, recvsz;
  521. .Lf
  522. .BE
  523. This routine creates an RPC client for the remote program
  524. .LW prognum ,
  525. version
  526. .LW versnum ;
  527. the client uses TCP/IP as a transport.
  528. The remote program is located at Internet address
  529. .LW *addr .
  530. If
  531. .LW addr->sin_port
  532. is zero, then it is set to the actual port that the remote
  533. program is listening on (the remote
  534. .I portmap
  535. service is consulted for this information).
  536. The parameter
  537. .LW *sockp
  538. is a socket; if it is
  539. .LW RPC_ANYSOCK ,
  540. then this routine opens a new one and sets
  541. .LW *sockp .
  542. Since TCP-based RPC uses buffered I/O, the user may specify
  543. the size of the send and receive buffers with the parameters
  544. .LW sendsz
  545. and
  546. .LW recvsz ;
  547. values of zero choose suitable defaults.
  548. This routine returns
  549. .LW NULL
  550. if it fails.
  551. .SH
  552. clntudp_create()
  553. .LP
  554. .BS
  555. .LS
  556. CLIENT *
  557. clntudp_create(addr, prognum, versnum, wait, sockp)
  558.     struct sockaddr_in *addr;
  559.     u_long prognum, versnum;
  560.     struct timeval wait;
  561.     int *sockp;
  562. .Lf
  563. .BE
  564. This routine creates an RPC client for the remote program
  565. .LW prognum ,
  566. version
  567. .LW versnum ;
  568. the client uses use UDP/IP as a transport.
  569. The remote program is located at Internet address
  570. .LW *addr .
  571. If
  572. .LW addr->sin_port
  573. is zero, then it is set to actual port that the remote
  574. program is listening on (the remote
  575. .I portmap
  576. service is consulted for this information).
  577. The parameter
  578. .LW *sockp
  579. is a socket; if it is
  580. .LW RPC_ANYSOCK ,
  581. then this routine opens a new one and sets
  582. .LW *sockp .
  583. The UDP transport resends the call message in intervals of
  584. .LW wait
  585. time until a response is received or until the call times out.
  586. The total time for the call to time out is specified by
  587. .LW clnt_call() .
  588. Warning: since UDP-based RPC messages can only hold up to 8 Kbytes
  589. of encoded data, this transport cannot be used for procedures
  590. that take large arguments or return huge results.
  591. .SH
  592. get_myaddress()
  593. .LP
  594. .BS
  595. .LS
  596. void
  597. get_myaddress(addr)
  598.     struct sockaddr_in *addr;
  599. .Lf
  600. .BE
  601. Stuffs the machine's IP address into
  602. .LW *addr ,
  603. without consulting the library routines that deal with
  604. .I /etc/hosts .
  605. The port number is always set to
  606. .LW htons(PMAPPORT) .
  607. .SH
  608. pmap_getmaps()
  609. .LP
  610. .BS
  611. .LS
  612. struct pmaplist *
  613. pmap_getmaps(addr)
  614.     struct sockaddr_in *addr;
  615. .Lf
  616. .BE
  617. A user interface to the
  618. .I portmap
  619. service, which returns a list of the current RPC program-to-port mappings
  620. on the host located at IP address
  621. .LW *addr .
  622. This routine can return
  623. .LW NULL .
  624. The command
  625. .LW "rpcinfo -p"
  626. uses this routine.
  627. .SH
  628. pmap_getport()
  629. .LP
  630. .BS
  631. .LS
  632. u_short
  633. pmap_getport(addr, prognum, versnum, protocol)
  634.     struct sockaddr_in *addr;
  635.     u_long prognum, versnum, protocol;
  636. .Lf
  637. .BE
  638. A user interface to the
  639. .I portmap
  640. service, which returns the port number
  641. on which waits a service that supports program number
  642. .LW prognum ,
  643. version
  644. .LW versnum ,
  645. and speaks the transport protocol associated with protocol.
  646. A return value of zero means that the mapping does not exist or that
  647. the RPC system failured to contact the remote
  648. .I portmap
  649. service.  In the latter case, the global variable
  650. .LW rpc_createerr
  651. contains the RPC status.
  652. .SH
  653. pmap_rmtcall()
  654. .LP
  655. .BS
  656. .LS
  657. enum clnt_stat
  658. pmap_rmtcall(addr, prognum, versnum, procnum,
  659.   inproc, in, outproc, out, tout, portp)
  660.     struct sockaddr_in *addr;
  661.     u_long prognum, versnum, procnum;
  662.     char *in, *out;
  663.     xdrproc_t inproc, outproc;
  664.     struct timeval tout;
  665.     u_long *portp;
  666. .Lf
  667. .BE
  668. A user interface to the
  669. .I portmap
  670. service, which instructs
  671. .I portmap
  672. on the host at IP address
  673. .LW *addr
  674. to make an RPC call on your behalf to a procedure on that host.
  675. The parameter
  676. .LW *portp
  677. will be modified to the program's port number if the procedure succeeds.
  678. The definitions of other parameters are discussed in
  679. .LW callrpc()
  680. and
  681. .LW clnt_call() .
  682. This procedure should be used for a ``ping'' and nothing else.
  683. See also
  684. .LW clnt_broadcast() .
  685. .SH
  686. pmap_set()
  687. .LP
  688. .BS
  689. .LS
  690. pmap_set(prognum, versnum, protocol, port)
  691.     u_long prognum, versnum, protocol;
  692.     u_short port;
  693. .Lf
  694. .BE
  695. A user interface to the
  696. .I portmap
  697. service, which establishes a mapping between the triple
  698. .LW [prognum,versnum,protocol]
  699. and
  700. .LW port
  701. on the machine's
  702. .I portmap
  703. service.  The value of protocol is most likely
  704. .LW IPPROTO_UDP
  705. or
  706. .LW IPPROTO_TCP .
  707. This routine returns one if it succeeds, zero otherwise.
  708. Automatically done by
  709. .LW svc_register() .
  710. .SH
  711. pmap_unset()
  712. .LP
  713. .BS
  714. .LS
  715. pmap_unset(prognum, versnum)
  716.     u_long prognum, versnum;
  717. .Lf
  718. .BE
  719. A user interface to the
  720. .I portmap
  721. service, which destroys all mappings between the triple
  722. .LW [prognum,versnum,*]
  723. and
  724. .LW ports
  725. on the machine's
  726. .I portmap
  727. service.
  728. This routine returns one if it succeeds, zero otherwise.
  729. .SH
  730. registerrpc()
  731. .LP
  732. .BS
  733. .LS
  734. registerrpc(prognum,versnum,procnum,procname,inproc,outproc)
  735.     u_long prognum, versnum, procnum;
  736.     char *(*procname)();
  737.     xdrproc_t inproc, outproc;
  738. .Lf
  739. .BE
  740. Registers procedure
  741. .LW procname
  742. with the RPC service package.  If a request arrives for program
  743. .LW prognum ,
  744. version
  745. .LW versnum ,
  746. and procedure
  747. .LW procnum ,
  748. .LW procname
  749. is called with a pointer to its parameter(s);
  750. .LW progname
  751. should return a pointer to its static result(s);
  752. .LW inproc
  753. is used to decode the parameters while
  754. .LW outproc
  755. is used to encode the results.
  756. This routine returns zero if the registration succeeded, \-1 otherwise.
  757. Warning: remote procedures registered in this form
  758. are accessed using the UDP/IP transport; see
  759. .LW svcudp_create()
  760. for restrictions.
  761. .SH
  762. rpc_createerr
  763. .LP
  764. .BS
  765. .LS
  766. struct rpc_createerr    rpc_createerr;
  767. .Lf
  768. .BE
  769. A global variable whose value is set by any RPC client creation routine
  770. that does not succeed.  Use the routine
  771. .LW clnt_pcreateerror()
  772. to print the reason why.
  773. .SH
  774. svc_destroy()
  775. .LP
  776. .BS
  777. .LS
  778. svc_destroy(xprt)
  779.     SVCXPRT *xprt;
  780. .Lf
  781. .BE
  782. A macro that destroys the RPC service transport handle,
  783. .LW xprt .
  784. Destruction usually involves deallocation
  785. of private data structures, including
  786. .LW xprt
  787. itself.  Use of
  788. .LW xprt
  789. is undefined after calling this routine.
  790. .SH
  791. svc_fds
  792. .LP
  793. .BS
  794. .LS
  795. int    svc_fds;
  796. .Lf
  797. .BE
  798. A global variable reflecting the RPC service side's
  799. read file descriptor bit mask; it is suitable as a parameter to the
  800. .LW select()
  801. system call.  This is only of interest
  802. if a service implementor does not call
  803. .LW svc_run() ,
  804. but rather does his own asynchronous event processing.
  805. This variable is read-only (do not pass its address to
  806. .LW select() !),
  807. yet it may change after calls to
  808. .LW svc_getreq()
  809. or any creation routines.
  810. .SH
  811. svc_freeargs()
  812. .LP
  813. .BS
  814. .LS
  815. svc_freeargs(xprt, inproc, in)
  816.     SVCXPRT *xprt;
  817.     xdrproc_t inproc;
  818.     char *in;
  819. .Lf
  820. .BE
  821. A macro that frees any data allocated by the RPC/XDR system
  822. when it decoded the arguments to a service procedure using
  823. .LW svc_getargs() .
  824. This routine returns one if the results were successfully freed,
  825. and zero otherwise.
  826. .SH
  827. svc_getargs()
  828. .LP
  829. .BS
  830. .LS
  831. svc_getargs(xprt, inproc, in)
  832.     SVCXPRT *xprt;
  833.     xdrproc_t inproc;
  834.     char *in;
  835. .Lf
  836. .BE
  837. A macro that decodes the arguments of an RPC request
  838. associated with the RPC service transport handle,
  839. .LW xprt .
  840. The parameter
  841. .LW in
  842. is the address where the arguments will be placed;
  843. .LW inproc
  844. is the XDR routine used to decode the arguments.
  845. This routine returns one if decoding succeeds, and zero otherwise.
  846. .SH
  847. svc_getcaller()
  848. .LP
  849. .BS
  850. .LS
  851. struct sockaddr_in
  852. svc_getcaller(xprt)
  853.     SVCXPRT *xprt;
  854. .Lf
  855. .BE
  856. The approved way of getting the network address of the caller
  857. of a procedure associated with the RPC service transport handle,
  858. .LW xprt .
  859. .SH
  860. svc_getreq()
  861. .LP
  862. .BS
  863. .LS
  864. svc_getreq(rdfds)
  865.     int rdfds;
  866. .Lf
  867. .BE
  868. This routine is only of interest if a service implementor does not call
  869. .LW svc_run() ,
  870. but instead implements custom asynchronous event processing.
  871. It is called when the
  872. .LW select()
  873. system call has determined that an RPC request
  874. has arrived on some RPC socket(s);
  875. .LW rdfds
  876. is the resultant read file descriptor bit mask.
  877. The routine returns when all sockets associated with the value of
  878. .LW rdfds
  879. have been serviced.
  880. .SH
  881. svc_register()
  882. .LP
  883. .BS
  884. .LS
  885. svc_register(xprt, prognum, versnum, dispatch, protocol)
  886.     SVCXPRT *xprt;
  887.     u_long prognum, versnum;
  888.     void (*dispatch)();
  889.     u_long protocol;
  890. .Lf
  891. .BE
  892. Associates
  893. .LW prognum
  894. and
  895. .LW versnum
  896. with the service dispatch procedure,
  897. .LW dispatch() .
  898. If
  899. .LW protocol
  900. is zero, the service is not registered with the
  901. .I portmap
  902. service.  If
  903. .LW protocol
  904. is non-zero, then a mapping of the triple
  905. .LW [prognum,versnum,protocol]
  906. to
  907. .LW xprt->xp_port
  908. is established with the local
  909. .I portmap
  910. service (generally
  911. .LW protocol
  912. is zero,
  913. .LW IPPROTO_UDP
  914. or
  915. .LW IPPROTO_TCP ).
  916. The procedure
  917. .LW dispatch()
  918. has the following form:
  919. .BS
  920. .LS
  921.     dispatch(request, xprt)
  922.         struct svc_req *request;
  923.         SVCXPRT *xprt;
  924. .Lf
  925. .BE
  926. The
  927. .LW svc_register()
  928. routine returns one if it succeeds, and zero otherwise.
  929. .SH
  930. svc_run()
  931. .LP
  932. .BS
  933. .LS
  934. svc_run()
  935. .Lf
  936. .BE
  937. This routine never returns.  It waits for RPC requests to arrive,
  938. and calls the appropriate service procedure using
  939. .LW svc_getreq()
  940. when one arrives.  This procedure is usually waiting for a
  941. .LW select()
  942. system call to return.
  943. .SH
  944. svc_sendreply()
  945. .LP
  946. .BS
  947. .LS
  948. svc_sendreply(xprt, outproc, out)
  949.     SVCXPRT *xprt;
  950.     xdrproc_t outproc;
  951.     char *out;
  952. .Lf
  953. .BE
  954. Called by an RPC service's dispatch routine
  955. to send the results of a remote procedure call.
  956. The parameter
  957. .LW xprt
  958. is the caller's associated transport handle;
  959. .LW outproc
  960. is the XDR routine which is used to encode the results; and
  961. .LW out
  962. is the address of the results.
  963. This routine returns one if it succeeds, zero otherwise.
  964. .SH
  965. svc_unregister()
  966. .LP
  967. .BS
  968. .LS
  969. void
  970. svc_unregister(prognum, versnum)
  971.     u_long prognum, versnum;
  972. .Lf
  973. .BE
  974. Removes all mapping of the double
  975. .LW [prognum,versnum]
  976. to dispatch routines, and of the triple
  977. .LW [prognum,versnum,*]
  978. to port number.
  979. .SH
  980. svcerr_auth()
  981. .LP
  982. .BS
  983. .LS
  984. void
  985. svcerr_auth(xprt, why)
  986.     SVCXPRT *xprt;
  987.     enum auth_stat why;
  988. .Lf
  989. .BE
  990. Called by a service dispatch routine that refuses to perform
  991. a remote procedure call due to an authentication error.
  992. .SH
  993. svcerr_decode()
  994. .LP
  995. .BS
  996. .LS
  997. void
  998. svcerr_decode(xprt)
  999.     SVCXPRT *xprt;
  1000. .Lf
  1001. .BE
  1002. Called by a service dispatch routine that can't successfully
  1003. decode its parameters.  See also
  1004. .LW svc_getargs() .
  1005. .SH
  1006. svcerr_noproc()
  1007. .LP
  1008. .BS
  1009. .LS
  1010. void
  1011. svcerr_noproc(xprt)
  1012.     SVCXPRT *xprt;
  1013. .Lf
  1014. .BE
  1015. Called by a service dispatch routine that doesn't implement
  1016. the desired procedure number the caller request.
  1017. .SH
  1018. svcerr_noprog()
  1019. .LP
  1020. .BS
  1021. .LS
  1022. void
  1023. svcerr_noprog(xprt)
  1024.     SVCXPRT *xprt;
  1025. .Lf
  1026. .BE
  1027. Called when the desired program is not registered with the RPC package.
  1028. Service implementors usually don't need this routine.
  1029. .SH
  1030. svcerr_progvers()
  1031. .LP
  1032. .BS
  1033. .LS
  1034. void
  1035. svcerr_progvers(xprt)
  1036.     SVCXPRT *xprt;
  1037. .Lf
  1038. .BE
  1039. Called when the desired version of a program is not registered
  1040. with the RPC package.
  1041. Service implementors usually don't need this routine.
  1042. .SH
  1043. svcerr_systemerr()
  1044. .LP
  1045. .BS
  1046. .LS
  1047. void
  1048. svcerr_systemerr(xprt)
  1049.     SVCXPRT *xprt;
  1050. .Lf
  1051. .BE
  1052. Called by a service dispatch routine when it detects a system error
  1053. not covered by any particular protocol.
  1054. For example, if a service can no longer allocate storage,
  1055. it may call this routine.
  1056. .SH
  1057. svcerr_weakauth()
  1058. .LP
  1059. .BS
  1060. .LS
  1061. void
  1062. svcerr_weakauth(xprt)
  1063.     SVCXPRT *xprt;
  1064. .Lf
  1065. .BE
  1066. Called by a service dispatch routine that refuses to perform
  1067. a remote procedure call due to insufficient (but correct)
  1068. authentication parameters.  The routine calls
  1069. .LW svcerr_auth(xprt,AUTH_TOOWEAK) .
  1070. .SH
  1071. svcraw_create()
  1072. .LP
  1073. .BS
  1074. .LS
  1075. SVCXPRT *
  1076. svcraw_create()
  1077. .Lf
  1078. .BE
  1079. This routine creates a toy RPC service transport,
  1080. to which it returns a pointer.  The transport
  1081. is really a buffer within the process's address space,
  1082. so the corresponding RPC client should live in the same address space; see
  1083. .LW clntraw_create() .
  1084. This routine allows simulation of RPC and acquisition of RPC overheads
  1085. (such as round trip times), without any kernel interference.
  1086. This routine returns
  1087. .LW NULL
  1088. if it fails.
  1089. .SH
  1090. svctcp_create()
  1091. .LP
  1092. .BS
  1093. .LS
  1094. SVCXPRT *
  1095. svctcp_create(sock, send_buf_size, recv_buf_size)
  1096.     int sock;
  1097.     u_int send_buf_size, recv_buf_size;
  1098. .Lf
  1099. .BE
  1100. This routine creates a TCP/IP-based RPC service transport,
  1101. to which it returns a pointer.
  1102. The transport is associated with the socket
  1103. .LW sock ,
  1104. which may be
  1105. .LW RPC_ANYSOCK ,
  1106. in which case a new socket is created.
  1107. If the socket is not bound to a local TCP port, then this routine
  1108. binds it to an arbitrary port.  Upon completion,
  1109. .LW xprt->xp_sock
  1110. is the transport's socket number, and
  1111. .LW xprt->xp_port
  1112. is the transport's port number.
  1113. This routine returns
  1114. .LW NULL
  1115. if it fails.  Since TCP-based RPC uses buffered I/O,
  1116. users may specify the size of the
  1117. .LW send
  1118. and
  1119. .LW receive
  1120. buffers; values of zero choose suitable defaults.
  1121. .SH
  1122. svcudp_create()
  1123. .LP
  1124. .BS
  1125. .LS
  1126. SVCXPRT *
  1127. svcudp_create(sock)
  1128.     int sock;
  1129. .Lf
  1130. .BE
  1131. This routine creates a UDP/IP-based RPC service transport,
  1132. to which it returns a pointer.
  1133. The transport is associated with the socket
  1134. .LW sock ,
  1135. which may be
  1136. .LW RPC_ANYSOCK ,
  1137. in which case a new socket is created.
  1138. If the socket is not bound to a local UDP port, then this routine
  1139. binds it to an arbitrary port.  Upon completion,
  1140. .LW xprt->xp_sock
  1141. is the transport's socket number, and
  1142. .LW xprt->xp_port
  1143. is the transport's port number.
  1144. This routine returns
  1145. .LW NULL
  1146. if it fails.
  1147. Warning: since UDP-based RPC messages can only hold up to 8 Kbytes
  1148. of encoded data, this transport cannot be used for procedures
  1149. that take large arguments or return huge results.
  1150. .SH
  1151. xdr_accepted_reply()
  1152. .LP
  1153. .BS
  1154. .LS
  1155. xdr_accepted_reply(xdrs, ar)
  1156.     XDR *xdrs;
  1157.     struct accepted_reply *ar;
  1158. .Lf
  1159. .BE
  1160. Used for describing RPC messages, externally.
  1161. This routine is useful for users who wish to generate
  1162. RPC-style messages without using the RPC package.
  1163. .SH
  1164. xdr_array()
  1165. .LP
  1166. .BS
  1167. .LS
  1168. xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc)
  1169.     XDR *xdrs;
  1170.     char **arrp;
  1171.     u_int *sizep, maxsize, elsize;
  1172.     xdrproc_t elproc;
  1173. .Lf
  1174. .BE
  1175. A filter primitive that translates between arrays
  1176. and their corresponding external representations.
  1177. The parameter
  1178. .LW arrp
  1179. is the address of the pointer to the array, while
  1180. .LW sizep
  1181. is the address of the element count of the array;
  1182. this element count cannot exceed
  1183. .LW maxsize .
  1184. The parameter
  1185. .LW elsize
  1186. is the
  1187. .LW sizeof()
  1188. each of the array's elements, and
  1189. .LW elproc
  1190. is an XDR filter that translates between
  1191. the array elements' C form, and their external representation.
  1192. This routine returns one if it succeeds, zero otherwise.
  1193. .SH
  1194. xdr_authunix_parms()
  1195. .LP
  1196. .BS
  1197. .LS
  1198. xdr_authunix_parms(xdrs, aupp)
  1199.     XDR *xdrs;
  1200.     struct authunix_parms *aupp;
  1201. .Lf
  1202. .BE
  1203. Used for describing UNIX credentials, externally.
  1204. This routine is useful for users who wish to generate
  1205. these credentials without using the RPC authentication package.
  1206. .SH
  1207. xdr_bool()
  1208. .LP
  1209. .BS
  1210. .LS
  1211. xdr_bool(xdrs, bp)
  1212.     XDR *xdrs;
  1213.     bool_t *bp;
  1214. .Lf
  1215. .BE
  1216. A filter primitive that translates between booleans (C integers)
  1217. and their external representations.
  1218. When encoding data, this filter produces values of either one or zero.
  1219. This routine returns one if it succeeds, zero otherwise.
  1220. .SH
  1221. xdr_bytes()
  1222. .LP
  1223. .BS
  1224. .LS
  1225. xdr_bytes(xdrs, sp, sizep, maxsize)
  1226.     XDR *xdrs;
  1227.     char **sp;
  1228.     u_int *sizep, maxsize;
  1229. .Lf
  1230. .BE
  1231. A filter primitive that translates between counted byte strings
  1232. and their external representations.
  1233. The parameter
  1234. .LW sp
  1235. is the address of the string pointer.
  1236. The length of the string is located at address
  1237. .LW sizep ;
  1238. strings cannot be longer than
  1239. .LW maxsize .
  1240. This routine returns one if it succeeds, zero otherwise.
  1241. .SH
  1242. xdr_callhdr()
  1243. .LP
  1244. .BS
  1245. .LS
  1246. void
  1247. xdr_callhdr(xdrs, chdr)
  1248.     XDR *xdrs;
  1249.     struct rpc_msg *chdr;
  1250. .Lf
  1251. .BE
  1252. Used for describing RPC messages, externally.
  1253. This routine is useful for users who wish to generate
  1254. RPC-style messages without using the RPC package.
  1255. .SH
  1256. xdr_callmsg()
  1257. .LP
  1258. .BS
  1259. .LS
  1260. xdr_callmsg(xdrs, cmsg)
  1261.     XDR *xdrs;
  1262.     struct rpc_msg *cmsg;
  1263. .Lf
  1264. .BE
  1265. Used for describing RPC messages, externally.
  1266. This routine is useful for users who wish to generate
  1267. RPC-style messages without using the RPC package.
  1268. .SH
  1269. xdr_double()
  1270. .LP
  1271. .BS
  1272. .LS
  1273. xdr_double(xdrs, dp)
  1274.     XDR *xdrs;
  1275.     double *dp;
  1276. .Lf
  1277. .BE
  1278. A filter primitive that translates between C
  1279. .LW double
  1280. precision numbers and their external representations.
  1281. This routine returns one if it succeeds, zero otherwise.
  1282. .SH
  1283. xdr_enum()
  1284. .LP
  1285. .BS
  1286. .LS
  1287. xdr_enum(xdrs, ep)
  1288.     XDR *xdrs;
  1289.     enum_t *ep;
  1290. .Lf
  1291. .BE
  1292. A filter primitive that translates between C
  1293. .LW enum s
  1294. (actually integers) and their external representations.
  1295. This routine returns one if it succeeds, zero otherwise.
  1296. .SH
  1297. xdr_float()
  1298. .LP
  1299. .BS
  1300. .LS
  1301. xdr_float(xdrs, fp)
  1302.     XDR *xdrs;
  1303.     float *fp;
  1304. .Lf
  1305. .BE
  1306. A filter primitive that translates between C
  1307. .LW float s
  1308. and their external representations.
  1309. This routine returns one if it succeeds, zero otherwise.
  1310. .SH
  1311. xdr_inline()
  1312. .LP
  1313. .BS
  1314. .LS
  1315. long *
  1316. xdr_inline(xdrs, len)
  1317.     XDR *xdrs;
  1318.     int len;
  1319. .Lf
  1320. .BE
  1321. A macro that invokes the in-line routine associated with the XDR stream,
  1322. .LW xdrs .
  1323. The routine returns a pointer
  1324. to a contiguous piece of the stream's buffer;
  1325. .LW len
  1326. is the byte length of the desired buffer.
  1327. Note that pointer is cast to
  1328. .LW "long *" .
  1329. Warning:
  1330. .LW xdr_inline()
  1331. may return
  1332. .LW NULL
  1333. (0) if it cannot allocate a contiguous piece of a buffer.
  1334. Therefore the behavior may vary among stream instances;
  1335. it exists for the sake of efficiency.
  1336. .SH
  1337. xdr_int()
  1338. .LP
  1339. .BS
  1340. .LS
  1341. xdr_int(xdrs, ip)
  1342.     XDR *xdrs;
  1343.     int *ip;
  1344. .Lf
  1345. .BE
  1346. A filter primitive that translates between C integers
  1347. and their external representations.
  1348. This routine returns one if it succeeds, zero otherwise.
  1349. .SH
  1350. xdr_long()
  1351. .LP
  1352. .BS
  1353. .LS
  1354. xdr_long(xdrs, lp)
  1355.     XDR *xdrs;
  1356.     long *lp;
  1357. .Lf
  1358. .BE
  1359. A filter primitive that translates between C
  1360. .LW long
  1361. integers and their external representations.
  1362. This routine returns one if it succeeds, zero otherwise.
  1363. .SH
  1364. xdr_opaque()
  1365. .LP
  1366. .BS
  1367. .LS
  1368. xdr_opaque(xdrs, cp, cnt)
  1369.     XDR *xdrs;
  1370.     char *cp;
  1371.     u_int cnt;
  1372. .Lf
  1373. .BE
  1374. A filter primitive that translates between fixed size opaque data
  1375. and its external representation.
  1376. The parameter
  1377. .LW cp
  1378. is the address of the opaque object, and
  1379. .LW cnt
  1380. is its size in bytes.
  1381. This routine returns one if it succeeds, zero otherwise.
  1382. .SH
  1383. xdr_opaque_auth()
  1384. .LP
  1385. .BS
  1386. .LS
  1387. xdr_opaque_auth(xdrs, ap)
  1388.     XDR *xdrs;
  1389.     struct opaque_auth *ap;
  1390. .Lf
  1391. .BE
  1392. Used for describing RPC messages, externally.
  1393. This routine is useful for users who wish to generate
  1394. RPC-style messages without using the RPC package.
  1395. .SH
  1396. xdr_pmap()
  1397. .LP
  1398. .BS
  1399. .LS
  1400. xdr_pmap(xdrs, regs)
  1401.     XDR *xdrs;
  1402.     struct pmap *regs;
  1403. .Lf
  1404. .BE
  1405. Used for describing parameters to various
  1406. .I portmap
  1407. procedures, externally.
  1408. This routine is useful for users who wish to generate
  1409. these parameters without using the
  1410. .LW pmap
  1411. interface.
  1412. .SH
  1413. xdr_pmaplist()
  1414. .LP
  1415. .BS
  1416. .LS
  1417. xdr_pmaplist(xdrs, rp)
  1418.     XDR *xdrs;
  1419.     struct pmaplist **rp;
  1420. .Lf
  1421. .BE
  1422. Used for describing a list of port mappings, externally.
  1423. This routine is useful for users who wish to generate
  1424. these parameters without using the
  1425. .LW pmap
  1426. interface.
  1427. .SH
  1428. xdr_reference()
  1429. .LP
  1430. .BS
  1431. .LS
  1432. xdr_reference(xdrs, pp, size, proc)
  1433.     XDR *xdrs;
  1434.     char **pp;
  1435.     u_int size;
  1436.     xdrproc_t proc;
  1437. .Lf
  1438. .BE
  1439. A primitive that provides pointer chasing within structures.
  1440. The parameter
  1441. .LW pp
  1442. is the address of the pointer;
  1443. .LW size
  1444. is the
  1445. .LW sizeof()
  1446. the structure that
  1447. .LW *pp
  1448. points to; and
  1449. .LW proc
  1450. is an XDR procedure that filters the structure
  1451. between its C form and its external representation.
  1452. This routine returns one if it succeeds, zero otherwise.
  1453. .SH
  1454. xdr_rejected_reply()
  1455. .LP
  1456. .BS
  1457. .LS
  1458. xdr_rejected_reply(xdrs, rr)
  1459.     XDR *xdrs;
  1460.     struct rejected_reply *rr;
  1461. .Lf
  1462. .BE
  1463. Used for describing RPC messages, externally.
  1464. This routine is useful for users who wish to generate
  1465. RPC-style messages without using the RPC package.
  1466. .SH
  1467. xdr_replymsg()
  1468. .LP
  1469. .BS
  1470. .LS
  1471. xdr_replymsg(xdrs, rmsg)
  1472.     XDR *xdrs;
  1473.     struct rpc_msg *rmsg;
  1474. .Lf
  1475. .BE
  1476. Used for describing RPC messages, externally.
  1477. This routine is useful for users who wish to generate
  1478. RPC style messages without using the RPC package.
  1479. .SH
  1480. xdr_short()
  1481. .LP
  1482. .BS
  1483. .LS
  1484. xdr_short(xdrs, sp)
  1485.     XDR *xdrs;
  1486.     short *sp;
  1487. .Lf
  1488. .BE
  1489. A filter primitive that translates between C
  1490. .LW short
  1491. integers and their external representations.
  1492. This routine returns one if it succeeds, zero otherwise.
  1493. .SH
  1494. xdr_string()
  1495. .LP
  1496. .BS
  1497. .LS
  1498. xdr_string(xdrs, sp, maxsize)
  1499.     XDR *xdrs;
  1500.     char **sp;
  1501.     u_int maxsize;
  1502. .Lf
  1503. .BE
  1504. A filter primitive that translates between C strings and their
  1505. corresponding external representations.
  1506. Strings cannot be longer than
  1507. .LW maxsize .
  1508. Note that
  1509. .LW sp
  1510. is the address of the string's pointer.
  1511. This routine returns one if it succeeds, zero otherwise.
  1512. .SH
  1513. xdr_u_int()
  1514. .LP
  1515. .BS
  1516. .LS
  1517. xdr_u_int(xdrs, up)
  1518.     XDR *xdrs;
  1519.     unsigned *up;
  1520. .Lf
  1521. .BE
  1522. A filter primitive that translates between C
  1523. .LW unsigned
  1524. integers and their external representations.
  1525. This routine returns one if it succeeds, zero otherwise.
  1526. .SH
  1527. xdr_u_long()
  1528. .LP
  1529. .BS
  1530. .LS
  1531. xdr_u_long(xdrs, ulp)
  1532.     XDR *xdrs;
  1533.     unsigned long *ulp;
  1534. .Lf
  1535. .BE
  1536. A filter primitive that translates between C
  1537. .LW "unsigned long"
  1538. integers and their external representations.
  1539. This routine returns one if it succeeds, zero otherwise.
  1540. .SH
  1541. xdr_u_short()
  1542. .LP
  1543. .BS
  1544. .LS
  1545. xdr_u_short(xdrs, usp)
  1546.     XDR *xdrs;
  1547.     unsigned short *usp;
  1548. .Lf
  1549. .BE
  1550. A filter primitive that translates between C
  1551. .LW "unsigned short"
  1552. integers and their external representations.
  1553. This routine returns one if it succeeds, zero otherwise.
  1554. .SH
  1555. xdr_union()
  1556. .LP
  1557. .BS
  1558. .LS
  1559. xdr_union(xdrs, dscmp, unp, choices, dfault)
  1560.     XDR *xdrs;
  1561.     int *dscmp;
  1562.     char *unp;
  1563.     struct xdr_discrim *choices;
  1564.     xdrproc_t dfault;
  1565. .Lf
  1566. .BE
  1567. A filter primitive that translates between a discriminated C
  1568. .LW union
  1569. and its corresponding external representation.  The parameter
  1570. .LW dscmp
  1571. is the address of the union's discriminant, while
  1572. .LW unp
  1573. in the address of the union.
  1574. This routine returns one if it succeeds, zero otherwise.
  1575. .SH
  1576. xdr_void()
  1577. .LP
  1578. .BS
  1579. .LS
  1580. xdr_void()
  1581. .Lf
  1582. .BE
  1583. This routine always returns one.
  1584. .SH
  1585. xdr_wrapstring()
  1586. .LP
  1587. .BS
  1588. .LS
  1589. xdr_wrapstring(xdrs, sp)
  1590.     XDR *xdrs;
  1591.     char **sp;
  1592. .Lf
  1593. .BE
  1594. A primitive that calls
  1595. .LW xdr_string(xdrs,sp,MAXUNSIGNED);
  1596. where
  1597. .LW MAXUNSIGNED
  1598. is the maximum value of an unsigned integer.
  1599. This is handy because the RPC package passes
  1600. only two parameters XDR routines, whereas
  1601. .LW xdr_string() ,
  1602. one of the most frequently used primitives, requires three parameters.
  1603. This routine returns one if it succeeds, zero otherwise.
  1604. .SH
  1605. xprt_register()
  1606. .LP
  1607. .BS
  1608. .LS
  1609. void
  1610. xprt_register(xprt)
  1611.     SVCXPRT *xprt;
  1612. .Lf
  1613. .BE
  1614. After RPC service transport handles are created,
  1615. they should register themselves with the RPC service package.
  1616. This routine modifies the global variable
  1617. .LW svc_fds .
  1618. Service implementors usually don't need this routine.
  1619. .SH
  1620. xprt_unregister()
  1621. .LP
  1622. .BS
  1623. .LS
  1624. void
  1625. xprt_unregister(xprt)
  1626.     SVCXPRT *xprt;
  1627. .Lf
  1628. .BE
  1629. Before an RPC service transport handle is destroyed,
  1630. it should unregister itself with the RPC service package.
  1631. This routine modifies the global variable
  1632. .LW svc_fds .
  1633. Service implementors usually don't need this routine.
  1634.